Sequence number for llOwnerSay RLV messages

Issue #111 new
Sam Wilson created an issue

I've recently run into an issue, using Firestorm, where llOwnerSay messages do not arrive in the same order they were sent. Though I am not totally sure, I suspect that the cause is not specific to Firestorm.

My use case was animating windlight variables to create a breathing-glow effect. Most of the time the animation would run smoothly, but once in a while, a llOwnerSay message would appear much later than intended, getting the windlight setting "stuck" in some intermediate state.

I propose adding a new restriction-like command that would look like the following:

@seqnum:<counter>;<counter_name>=y/n

Counter name would be optional, to allow multiple scripts in the same object to use separate counters.

The effect of calling this command with n is that if counter is less than the previous value of counter (stored in the client) all following commands in the llOwnerSay message are discarded.

Calling seqnum with y would clear the counter.

Comments (8)

  1. Marine Kelley repo owner

    Interesting proposal, but ultimately, it isn't the responsibility of the RLV to take care of the order the messages are received, this is a purely network concern. But yes, that could fix the issue of having llOwnerSay messages that switch order, so I'll keep that in mind.

    In the meantime, if the order between two commands is very important to you, you could send all them in a single llOwnerSay message, separated by pipe chars ("|"), that way you are absolutely sure the RLV will process them in order. Don't forget that chat messages are truncated by the sim to 1023 characters though (which is one of the reasons why I always try to keep the RLV commands short, the other reason being that Mono scripts really don't like strings).

  2. Sam Wilson reporter

    Unfortunately there is no way to put a delay between commands in the same message. Your options are either "as fast as the viewer can go" or "one round trip between script and client".

    You can force message order with something like:

    @setdebug_renderresolutiondivisor=4|versionnum=56
    

    But that is slow, requires a listen, and you can't timeout in any reasonable period because the llOwnerSay messages can be delayed by pretty significant amounts.

  3. Marine Kelley repo owner

    The real problem is that there is no acknowledgement from the viewer when a command is received (well, there is a way with notify, you don't need to request the version number or anything else, simply activate a notify and open a listener), an acknowledgement system would have to be controlled entirely by the script, rather than the viewer. It follows more or less your example though. But there is no way to tell the viewer "execute this command X in exactly Y seconds", which would not make much sense anyway. Rather "execute this command X only after you have received command Y", that would mean the viewer has to expect that command Y will be sent at some point (and from what, the same object ?).

    Also, your proposal of adding sequence numbers might work in the case when a command isn't really important (since it would be superseded by another one anyway), but in the case when you want two commands to be taken into account, both of them, and in one particular order, this wouldn't work. What I mentioned in the first paragraph might work better perhaps, but that would be a significant addition to the basic protocol.

  4. Sam Wilson reporter

    I'm not sure I follow what you mean about "execute this command X only after you have received command Y". That doesn't really seem to solve the issue of out of order llOwnerSay messages.

    If you combine seqnum with notify, you can actually get a basic ack+retransmit protocol going on, and have some reliable message transport. I mean, it'd be a total pain in the butt to implement on the script side, but it would be possible.

    Given S is the script, and V is the viewer, for example we start with:

    S: @notify:5;seqnum=add,seqnum:0=n
    V: /notify:5;seqnum=add
    V: /seqnum:0=n
    

    In the case where no reordering occurs:

    S: @seqnum:1=n,attach:some_folder=force
    V: /seqnum:1=n
    # Some delay in the script
    S: @seqnum:2=n,detach:some_folder=force
    V: /seqnum:2=n
    

    So we attach and detach some folder after a period of time. Now, this is what could happen if we add seqnum:

    S: @seqnum:1=n,attach:some_folder=force
    # Some delay in the script
    S: @seqnum:2=n,detach:some_folder=force
    V: /seqnum:2=n
    

    In the second case, the script would know that the attach never executed, and could take some action, say re-transmitting it, or alerting the user.

    Now that I think about this more, you'd also have to consider that the viewer's messages could be re-ordered as well.

  5. Marine Kelley repo owner

    What I meant by conditioning the execution of command X after having received command Y (granted, the letters weren't chosen right in the first place but let's stick to them), was that the script would tell the viewer to buffer command X instead of executing it right away, and wait for command Y to be received before executing X. That way you would be guaranteed to have your two commands executed in order.

    It's true that not only the incoming llOwnerSay messages (from the viewer's point of view) may be reordered, but also the outgoing ones (still from the viewer's point of view), so that compounds the issue even more.

    When I mentioned notify, I meant to use it in lieu of the sequence numbers. Like, in your script you activate a notify on a certain command, then you create a listener and call a function only when you receive a notification of this command having been received by the viewer. Then later you send your first command, and the second one would be sent only by the listen event (or whatever function it calls).

    I repeat, if you absolutely want your two commands to be received and executed in order by the viewer, with a delay in-between, then you can't rely on sequence numbers, you have to use a notify and do this asynchronously. It's a pain in the butt but it works. Sequence numbers (at least the ones you proposed, "drop a command if its sequence number is less than the latest one the viewer received) only solves the issue when the missed command is disposable (as in, it is superseded by the next one... that the viewer received first since there has been an inversion in the order the commands were received).

    I have to ask though, what is the problem with sending two commands in the same llOwnerSay message ? I did that specifically to avoid out-of-order commands... Is there an issue with having them executed as fast as the viewer can go ?

  6. Sam Wilson reporter

    You know, I think you're right. This is a fairly complicated problem that I don't think a simple RLV command like @seqnum can solve.

    I would like to be able to have smooth animations that don't leave windlight settings in a weird state because of reordered messages, but adding a command just for that isn't really useful.

    Guaranteeing ordering between messages would be super useful, and I think possible with some kind of sequence number + notify combination, but sorting out the details of it would be beyond the amount of time I'm willing to spend on it.

  7. Marine Kelley repo owner

    It wouldn't be a trivial thing to do in a script indeed, but do take a look at the "notify" command, which basically means "notify the script on channel XXXX whenever the viewer receives and executes a command which line (i.e. command and even options if you want) contains the specified string". This would really help ordering your commands in the fashion that you want, while your script would still be in charge of controlling the delay.

    I did that with one of my products, which gives the user a folder directly under #RLV waits for it to be received (with a notify), then forces the user to wear it, waits for another notify, and then proceeds. Works like a charm.

  8. Sam Wilson reporter

    I do something similar. I have a little RLVa library I've been working on, and I do pretty much the same thing when I need command confirmation.

    The only real use case I have for something like this is animating value changes, where missed commands don't matter too much.

  9. Log in to comment