Channel Zero and Max Listeners Request for Script Effeciency
|
|
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
|
06-11-2006 13:05
I would like to propose that if any script opens more than 1 channel zero listener it immediately crashes. I dont mean that the script just not open another listener. I mean outright breaks execution and has to be reset / recompiled. Warning message of
Multiple Channel Zero Listeners concurrently running. Sim Resource Alrt. Stopping Script.
or anything similar along those lines. There is NEVER a legitimate reason to run more than one chan zero listener in a script. EVER. If you are using filtered llListen() calls to only pick up special messages you will need to do the same filter AGAIN in your script itself to see which situation occured. Might as well use one non filtered llListen() call as that will mean your messages are only processed by one filter than by two easing up resources in the backend of the server while still doing the same tasts in the script unchanged.
With the script being forced to halt rather than just give a 'fail to open new listener' message that will force script writers to take IMMEDIATE responsibility for their scripts and to force them to use the most effecient means of accomplishing the task.
Also any script that hits the "Too Many Listeners" error should flat out crash too requiring script reset / recompile. The max listeners in a single script is somewhere around 5 dozen. Forget the exact number but I just can not imagine a situation that would require that many listeners except in a product that is scanning multiple channels to try to crach the communication protocol of some object for the sake of cheating.
Maybe even impliment some warning messages as XX number of listeners are open.
"Warning: 10 concurrent speech handlers scheduled. Approaching lag inducing levels." "Warning: 25 concurrent speech handlers scheduled. Approaching lag inducing levels." "Warning: 50 concurrent speech handlers scheduled. Approaching lag inducing levels." "Error: max listeners exceeded in single script. Script halted to improve sim performance"
BTW why do we needed the max listeners to be that high? Does ANYONE in all of SL use an object with more listeners than say TEN for a legitimate purpose where fewer llListen calls and more intelligent script design would have done the job without the resource hit?
I would like to see the Max Listeners limit reduced to 25 at most. For the sake of intelligent design alone any project needing more listeners than that would more likely benifit from being modularized out into seperate scripts.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
06-11-2006 13:12
People open more than one listen in the same script on the same channel? On purpose? Hm, I suppose it could be a lazy method of listening to a small number of people, or for a small set of messages. Poor practice though.
|
|
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
|
06-11-2006 14:12
People do it due to lazy programming.
They open the listener via on_rez() event. But never actually close the previous listeners first. So more and more listeners with the exact same filter applied get scheduled. Meaning something that fails the filter will have to get checked repeatedly till its failed every copy of the filter and is finally ignored. least the good news is that once a message passes a filter it just gets processed and doesnt have to check to see if it fails the others. That blessed design choice keeps a script from processing the same message mutliple times.
|
|
Eddy Stryker
libsecondlife Developer
Join date: 6 Jun 2004
Posts: 353
|
06-11-2006 15:31
You do realize that installing a filter with an llListen call is vastly less server cpu cycles than implementing your own filters in LSL right? Checking messages against filters is a lot less load than actually executing LSL code every time a message is sent.
Having said that, it would be good to limit the total installed listens. The problem is, if a script has a goal of listening for 50 different commands, it can install 50 filters, or make a catch-all filter with a 50-statement if block. The 50 filters would be incredibly faster than doing 50 string comparisons in LSL for every message sent. So lets say some advanced algorithm is created to limit the amount of work that can be done in a listen. The person with the goal of a 50 command script just creates 50 different scripts, and things become worst-case scenario.
|
|
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
|
06-12-2006 03:15
There is already a limit to the maximum number of listens which causes your script to 'crash' with a maximum listens warning. I can't remember what the limit is but a script I had that wasn't closing listens properly bumped into it. I also believe that duplicate listens are ignored, or replace the previous listen (so if you called llListen(0, "", NULL_KEY, ""  ; twice it would chuck the first one and only use the second). What if someone is using two, temporary and filtered listens on channel zero? This is exactly the same as the other discussion on listens in the other thread. For example: listen1 = llListen(0, "", llGetOwner(), "show"); listen2 = llListen(0, "", llGetOwner(), "hide"); With both listens being closed after 30 seconds? Their script would crash even though they contribute very little to lag.
_____________________
Computer (Mac Pro): 2 x Quad Core 3.2ghz Xeon 10gb DDR2 800mhz FB-DIMMS 4 x 750gb, 32mb cache hard-drives (RAID-0/striped) NVidia GeForce 8800GT (512mb)
|
|
ninjafoo Ng
Just me :)
Join date: 11 Feb 2006
Posts: 713
|
06-12-2006 05:21
From: Haravikk Mistral With both listens being closed after 30 seconds? Their script would crash even though they contribute very little to lag. Work around would be to write a single script that handled 1 command, for more commands you just duplicate this script up over and over and adjust as required.
_____________________
FooRoo : clothes,bdsm,cages,houses & scripts
QAvimator (Linux, MacOS X & Windows) : http://qavimator.org/
|
|
Adriana Caligari
Registered User
Join date: 21 Apr 2005
Posts: 458
|
06-12-2006 07:54
From: Haravikk Mistral There is already a limit to the maximum number of listens which causes your script to 'crash' with a maximum listens warning. I can't remember what the limit is but a script I had that wasn't closing listens properly bumped into it. I also believe that duplicate listens are ignored, or replace the previous listen (so if you called llListen(0, "", NULL_KEY, ""  ; twice it would chuck the first one and only use the second). What if someone is using two, temporary and filtered listens on channel zero? This is exactly the same as the other discussion on listens in the other thread. For example: listen1 = llListen(0, "", llGetOwner(), "show"); listen2 = llListen(0, "", llGetOwner(), "hide"); With both listens being closed after 30 seconds? Their script would crash even though they contribute very little to lag. 64 listens per object was the limit last time i checked.
|
|
Nargus Asturias
Registered User
Join date: 16 Sep 2005
Posts: 499
|
06-12-2006 08:05
I heard that one of the major adult items creator use llListen in every single prim instead of only one listen and lots of link_messages. And there're lots of prims in his/her /attachments/.
/Hopefully/ he/she have fixed that now, and that the listens have nothing to do with zero channel.....
_____________________
Nargus Asturias, aka, StreamWarrior Blue Eastern Water Dragon Brown-skinned Utahraptor from an Old Time
|
|
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
|
06-12-2006 11:33
From: Eddy Stryker You do realize that installing a filter with an llListen call is vastly less server cpu cycles than implementing your own filters in LSL right? Checking messages against filters is a lot less load than actually executing LSL code every time a message is sent.
Having said that, it would be good to limit the total installed listens. The problem is, if a script has a goal of listening for 50 different commands, it can install 50 filters, or make a catch-all filter with a 50-statement if block. The 50 filters would be incredibly faster than doing 50 string comparisons in LSL for every message sent. So lets say some advanced algorithm is created to limit the amount of work that can be done in a listen. The person with the goal of a 50 command script just creates 50 different scripts, and things become worst-case scenario. Actually, I remember a big thread over a year ago in the Scripting Tips forum, and lot sof empirical testing, which seemed to suggest fairly strongly that it's more efficient to use just one listener with a filter in your LSL code. I think the reasoning went along the lines that those filters are checked for any chat on any channel... so your several filters get in the action for any chat on high channels, even if it's just to check the channel number. I was surprised, too, believe me. From: Seronis Zagato People do it due to lazy programming.
They open the listener via on_rez() event. But never actually close the previous listeners first... Actually, I'm pretty sure that opening a duplicate listener with a duplicate filter will simply replace the existing one (ie do nothing). It's only if any of the listen filter parameters are different that a new listen is created. I can think of one instance where an innocent mistake will cause multiple channel 0 listeners, though. Say I make a tool that listens on channel 0. In my on_rez, I set up a listener for the object's owner. I forget to close it anywhere in the code, so when I give it to someone else, a new listener is created for them. Now I have two listeners on channel 0 and your new law triggers. Anyway, I think you mean well and all, but mandating coding practice like this is a good way to destroy a bunch of working items that have already been distributed across SL. Destroying existing objects is against the cardinal rule of policy decisions for a company in a position like LL. Sure, everyone should go fix their objects, but it can be impossible to tell who has a copy of your object, and there will always be someone who you haven't managed to get an upgrade to. Then there's the fact that there might be some really useful tools out there in-world that hit this new law, and their owners may have quit SL long since. Suddenly we lose the benefit of their creations.
|
|
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
|
06-12-2006 12:32
From: Eddy Stryker You do realize that installing a filter with an llListen call is vastly less server cpu cycles than implementing your own filters in LSL right? Checking messages against filters is a lot less load than actually executing LSL code every time a message is sent. For one-shot listeners that is true. But its NOT true in any other case. Let me explain: For each listener you have scheduled a message that does NOT pass the filters will get checked by each and every Listen you have scheduled. So the more complex your filters are the more work done on most messages that fail and if you are accepting multiple different messages that message will get checked by each fitler until it hits the one it passes causing a lot of unneeded processing. Since you are already filtering by multiple messages you probably need to HANDLE those messages different. Thus in your script itself it IS ALREADY fitlering each acceptible message in order to figure out which task is being performed. Specific example provided by Har but still have another comment for you. From: Eddy Stryker ... if a script has a goal of listening for 50 different commands, it can install 50 filters, or make a catch-all filter with a 50-statement if block. The 50 filters would be incredibly faster than doing 50 string comparisons in LSL for every message sent ... But your 50 filters are all gonna end up processing EVERY SINGLE THING said by EVERY speech that uses the channel you are listening on. Not just messages that pass your filter. By reducing the total number of filters so that you ONLY filter name or id you reduce the resource hit the server is required to take to process things you're not interested in (which far FAR outnumbers the messages you -are- interested in). To be fully honest your filters add a small ammount of processing to everything said in the entire sim regardless of channel. And again for messages in neighboring sims with a range large enough to cross a sim border. If you're interested in the technicalities I explained how the system works in THIS THREAD started by another resident in favor of completely removing all channel zero listeners. Your filter stipulations wont be processed by all these other messages but your channel will at a minimum and possibly distance factors. Now: From: Haravikk Mistral What if someone is using two, temporary and filtered listens on channel zero? This is exactly the same as the other discussion on listens in the other thread. For example: listen1 = llListen(0, "", llGetOwner(), "show"); listen2 = llListen(0, "", llGetOwner(), "hide"); With both listens being closed after 30 seconds? Their script would crash even though they contribute very little to lag. The fact of being temporary only and are soon to be closed is not an issue in this example. The fact you are using two seperate listeners on channel zero is irresponsible and unacceptible. In the example you showed there the messages are already filtered by Owner uuid. This means for every thing said by any avatar you are TWICE checking the channel, then the distance and then the speakers UUID to see if those items match. You should only do one llListen using: llListen(0,"",llGetOwner(),""); Reason being is this will reduce the load aquired from ALL channel messages. Then in the FEW cases where its the filtered avatar speaking your script itself is ALREADY having to check the message body to see if its 'show' or 'hide'. As long as you wrote your if checks properly the ONLY actions performed in your script would be two text checks that would short circuit at the first letter that doesnt match before moving on to the 2nd check and then exiting the event. You are already doing those filters. Its not requiring extra work from the script. So why are you filtering twice in the system? EDIT: Better explination of why its bad. In the case where the message you typed was 'show' it would process thru your filter and get accepted, not requiring further processing. In the case where the message you typed was 'hide' it would check channel and pass. check range and pass, check every digit of your UUID and pass. And after all that processing it would finally fail at the message itself which is gonna have to get checked AGAIN in the script. Make more sense that way? Ninja: no. the fix is to just use the more effecient method of fewer total listeners. attempting to bypass this particular failsafe would cause even more issues than just allowing a duplicate. Lex: exactly. i've done a lot of testing myself in the past year to see what types of benchmarks i could get in various things and used those results with what i already know about hard code (C and C++) to get the picture of how the backend works. Believe it or not though having the speach order of checks applied in this manner is THE fastest way possible when your test range of messages can span broad random ranges. I put technicalities in the thread i referenced above and if you wish i can get even more technical. Just the majority of people here dont have programming experience in compiled languages and my arguments here are based on how that backend is optimized and not on how LSL runs on its own. As far as duplicate listeners being removed: false. I heard this one quite some type ago and my response was this: integer loop; for( loop = 0; loop < 100; ++loop) { llListen(0,"",llGetOwner(),""); }
Compiled that in the new script state entry function and got the expected 'too many listens' error. They are not removed unless this changed since SL1.7 (last time i tested). Even if they fix this 'feature' so that duplicates are removed it wont work if the filter is applied and LATER the owner changes. The new owner would wear the item and the on_rez() would open a SECOND listen because it was never told to close the previous one and the new UUID being supplied is not the same as the one in the current queued filter. We still need the script to outright crash if a 2nd chan 0 listener is opened. We dont want those spare listeners running because of a bugged script. If those devices no longer are being maintained and they break someone else will make a new one. If the script is full permissions people can fix it theirselves or come to one of my scripting classes and i'll gladly guide them through HOW and WHY to fix it free of charge. The biggest point is that any script doing this SHOULD BREAK. That would have an IMMEDIATE improvement in sim resource usage and FORCE scripters to learn the proper methods of doing a task. It might make a few people frustrated INITIALLY but in the /long run/ it would only benifit the game. And if everything that was gonna break did so immediately after this update the recovery from such an act would be swift. new people would seize the opportunity to make replacement products and some would do it for free just for the sake of getting their name known.
|
|
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
|
06-12-2006 12:50
OK correction in Lex's favor. Any EXACTLY matching filter now does properly result in a no-op and the ORIGINAL filter being left in place. The return value from llListen() will match the handle ALREADY recieved from the previous filter with matching criteria. Tested this with..
integer loop;
default { touch_start(integer total_number) { llSay(0, "Touched."); list blah = []; for( loop = 0; loop < 100; ++loop) { blah += [ (string)llListen(0,"",llGetOwner(),"test") ]; } llOwnerSay( llList2CSV(blah) ); } }
if anyone cares
|
|
ninjafoo Ng
Just me :)
Join date: 11 Feb 2006
Posts: 713
|
06-13-2006 03:34
From: Seronis Zagato Ninja: no. the fix is to just use the more effecient method of fewer total listeners. attempting to bypass this particular failsafe would cause even more issues than just allowing a duplicate. Exactly my point - you close one door you cannot expect everyone to walk through the correct new door.
_____________________
FooRoo : clothes,bdsm,cages,houses & scripts
QAvimator (Linux, MacOS X & Windows) : http://qavimator.org/
|
|
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
|
06-13-2006 10:58
From: Seronis Zagato Lex: exactly. i've done a lot of testing myself in the past year to see what types of benchmarks i could get in various things and used those results with what i already know about hard code (C and C++) to get the picture of how the backend works. Believe it or not though having the speach order of checks applied in this manner is THE fastest way possible when your test range of messages can span broad random ranges. I put technicalities in the thread i referenced above and if you wish i can get even more technical. Just the majority of people here dont have programming experience in compiled languages and my arguments here are based on how that backend is optimized and not on how LSL runs on its own.
I've got similar experience in my year and a half plus in SL. I know from what I've seen and what I've read that what you're saying is correct, and that multiple listeners aren't the way to go. I'm not doubting that. From: someone ...
Even if they fix this 'feature' so that duplicates are removed it wont work if the filter is applied and LATER the owner changes. The new owner would wear the item and the on_rez() would open a SECOND listen because it was never told to close the previous one and the new UUID being supplied is not the same as the one in the current queued filter.
That's exactly what I said above. LSL can be hard enough for newbies to learn. This is an incredibly subtle problem, and I can see a newbie to LSL being entirely confused if the item they scripted up worked fine for them, but crashed with your cryptic "too many channel zero listeners" message when they passed it to a friend. I'm not saying this necessarily excuses poor coding style and lack of attention to detail, but I am saying that it's WAY too easy to make that mistake, and the resulting crash you advocate would be really confusing. From: someone We still need the script to outright crash if a 2nd chan 0 listener is opened. We dont want those spare listeners running because of a bugged script. If those devices no longer are being maintained and they break someone else will make a new one. If the script is full permissions people can fix it theirselves or come to one of my scripting classes and i'll gladly guide them through HOW and WHY to fix it free of charge.
Breaking existing content like this just isn't cool. It's just not something that can be justified. It's too late to think about a rule like this, because implementing it would break a lot of content now. Have you ever had any of your code or other SL content broken by a change LL made? I have, and it's incredibly infuriating. I think this is exactly the wrong way to go about creating the change you want to see. It'd be much better if you run workshops about listeners and tech talks about the right and wrong ways to do things. From: someone The biggest point is that any script doing this SHOULD BREAK. That would have an IMMEDIATE improvement in sim resource usage and FORCE scripters to learn the proper methods of doing a task. It might make a few people frustrated INITIALLY but in the /long run/ it would only benifit the game. And if everything that was gonna break did so immediately after this update the recovery from such an act would be swift. new people would seize the opportunity to make replacement products and some would do it for free just for the sake of getting their name known.
I'm gonna go out on a limb here and also question just how much of an improvement we'll see. There are so many other ways of lagging a sim through poor coding practice that I don't think that cleaning up a few channel-0 listeners is going to make that much of a difference. Before you go and break thousands of scripts that work fine right now just because of some theory that seems sound (and it does seem sound enough, but how can we be sure from out here?), you need some hard numbers to back this up. My guess is that each channel zero listener, while it is contributing noticeably to sim processing time, is probably making less of an impact than the sheer volume of scripts in a sim. See ( this thread). From: someone OK correction in Lex's favor. Any EXACTLY matching filter now does properly result in a no-op and the ORIGINAL filter being left in place. The return value from llListen() will match the handle ALREADY recieved from the previous filter with matching criteria.
I did that same test before I even posted that comment above...
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
06-13-2006 12:02
From: Seronis Zagato Since you are already filtering by multiple messages you probably need to HANDLE those messages different. Thus in your script itself it IS ALREADY fitlering each acceptible message in order to figure out which task is being performed. Specific example provided by Har but still have another comment for you. Yeh, but if you're only listening for "show" and "hide" you'll only have your LSL run when someone says "show" or "hide". If you listen for everything your LSL runs for everything everyone in range says on that channel. And there's lots of stuff on low channels. I've had command collisions when my own scripts triggering because someone else had a publicly controllable object using the same command. If you can get away with two listeners that filter in high performance "C" instead of LSL, you'll be reducing total lag. I agree that this is a limited tool, and more than a couple of listens is foolish. But it's not automatically a bad idea. Also, on a related subject, link messages don't seem any less laggy than high channel listens. SL doesn't seem to maintain message queues in an object, instead they run every script every frame and check to see if they have any work to do.
|
|
ninjafoo Ng
Just me :)
Join date: 11 Feb 2006
Posts: 713
|
06-14-2006 01:18
From: Lex Neva Breaking existing content like this just isn't cool. It's just not something that can be justified. It's too late to think about a rule like this, because implementing it would break a lot of content now. And, LL are famous for not implamenting things for fear of breaking content. The fact the get 80% of the dev work done, show a nice shiny proof of concept and then shelve the whole project is kinda disheartening, but thats what they do.
_____________________
FooRoo : clothes,bdsm,cages,houses & scripts
QAvimator (Linux, MacOS X & Windows) : http://qavimator.org/
|
|
Seronis Zagato
Verified Resident
Join date: 30 Aug 2005
Posts: 454
|
06-14-2006 03:05
From: Argent Stonecutter Yeh, but if you're only listening for "show" and "hide" you'll only have your LSL run when someone says "show" or "hide". If you listen for everything your LSL runs for everything everyone in range says on that channel. In the example above the filter was also limited to an avatar uuid. In that case for every message said by anyone but the owner it had to get processed for channel, range and then speaker key ebfore it fails. And it has to do this twice for everything said instead of just once. Messages by the owner will be a much lower percentage of the total speech messages going on in an area. At a bare minimum your two listeners will both have to get checked for EVERY messages channel. By reducing it to one Listen NOT filtered by messages you reduce the impact that all those other, vastly greater numbered, messages take in CPU time processing. On the other hand your script itself will already be effeciently making sure that the only action performed on owner messages will be two string comparisons and a couple function calls to access the scripts bytecode. When you consider this TINY increase in script executions is offset by all OTHER messages only getting processed once, and MOST of the owners own messages being reduced from two filter passes to one, the total gains make it more effecient. In a situation where you are not filtering by name or uuid you are correct and 2 listens would be an advantage. When either of those two things are fitlered though is a good indication that additionally filtering by message is bad.
|