• All submissions to this site are governed by Second Life Project Contribution Agreement. By submitting patches and other information using this site, you acknowledge that you have read, understood, and agreed to those terms.
Issue Details (XML | Word | Printable)

Key: SVC-310
Type: New Feature New Feature
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Escort DeFarge
Votes: 23
Watchers: 6
Operations

If you were logged in you would be able to see more operations.
2. Second Life Service - SVC

Object to object messaging

Created: 12/Jun/07 01:26 PM   Updated: 10/Oct/09 02:50 PM
Return to search
Component/s: Scripts
Affects Version/s: 1.16.0
Fix Version/s: None

Environment: N/A (Simulator)
Issue Links:
Duplicate
 
Relates


 Description  « Hide
A request either for: llMessageObject(key id, string message) or for the call llInstantMessage(key id, string message) be extended to include objects.

Given that the overhead of resolving an object's simulator location is non-trivial, perhaps some script delay would be acceptable. e.g. 3 seconds? If the search space is too great then perhaps the message call should enforce the need to include the region - e.g. llMessageObject(string Region, key id, string Message). Since "region search" already lists objects the overhead surely cannot be great, so in exchange for this constraint perhaps the script delay could be reduced to the same as an IM i.e. 0.2 seconds.



 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Mark Frazer added a comment - 13/Jun/07 03:55 AM
It might be a bit more complicated, because the implementation must first verify if the object actually exists. Further the object might have been deleted and the ID reassigned to another object.
A possible solution is a communication channel (object) that depends on all connected objects. But then again, they're all one complex object.

Escort DeFarge added a comment - 13/Jun/07 09:38 AM
I think it would be acceptable for the message to fail if the object is not rezzed anywhere...

...or if it's owned by someone else (which i would consider a feature).

Are UUIDs reused?, That rather defeats the purpose of unique ids and the guid space is larger than we'd "ever" need so it seems unnecessary from an implementation standpoint..

I suspect that the issue is more likely that the UUID of rezzed objects in a simulator is not tracked centrally, so finding the object would mean a global search of the grid - since objects don't have a log in like we agents. Would llMessageObject(string Region, key id, string message) solve this?

However, I get the feeling that we are both speculating


Daedalus Young added a comment - 17/Jul/07 02:56 PM
Well, if you can send en e-mail to a UUID, surely you can send inworld messages, right?

Escort DeFarge added a comment - 20/Jul/07 11:34 AM
Daedalus, I think you missed the point. Compare the overhead of this proposal to the actual implementation overhead (both script code and its effect on the platform) using smtp. I do already have systems sending thousands of object messages per day. I'm after a better solution and this would be it.

Cheshyr Pontchartrain added a comment - 16/Aug/08 12:02 PM
I would love to see this as well. Particularly since llEmail() is an instant message. The documentation is quite specific that llEmail() sent to an in-world object is handled by the instant message system. So why impose an arbitrary 15 second delay? And worse, why is the email event handled so poorly that it doesn't fire like any proper event, but must be polled?

Sen Pixie added a comment - 16/Aug/08 12:16 PM
I'm behind this 100%. I sell objects that require a large amount of inter-sim object-object communication. Using 15-20 e-mail relay scripts is just insane, but I have no other choice. I think the standard llInstantMessage delay of 0.2 seconds would be fine. It would greatly decrease script overhead for my products, at least. Can that really be a bad thing?
Instead of allowing llInstantMessage to do object to object, I'd prefer removing most of the delay from e-mail, since the subject and message fields are nice to have. But that's just my preference, I'd take whatever I could get without the 20 second delay.

anthony reisman added a comment - 19/Aug/08 02:06 PM
This should be resolved when Kelly finishes work on http server for objects in SVC-1086

Escort DeFarge added a comment - 12/Nov/08 09:39 AM
I don't think SVC-1086 does directly address this feature request. While useful indeed, SVC1086 doesn't really give you anything more than fixed xml-rpc (which used to work at one time).

I'm asking for a feature that will send an object to object message and not have to hack it using email - In order to use either SVC1086 or xml-rpc you need to run and support a webserver externally and it so just increases the complexity of this straightforward capability rather than reducing it.


Escort DeFarge added a comment - 12/Nov/08 09:59 AM
The search engine for a region provides a list of objects on a sim. So this overhead can surely not be great. I'm amending the description to add a suggestion that the region be included as a parameter if required to reduce the overhead of this proposed call.

Argent Stonecutter added a comment - 06/Jan/09 04:47 AM - edited
Another possible approach to cut down on overhead would be to have two calls, one to create a handle for an object (that would do the heavy lifting of locating it), and one to send a message over that connection. Or even:
Inter-Prim Communication
// In the receiver, register to receive IPC:
key listen_id = llAcceptIPC();
//...
dataserver(key id, string msg)
{
  if(id == listen_id) {
    doSomethingWith(msg);
    llReplyIPC(some_string); // Send a response IPC to the sender of the current message
  }
}

// In the sender, look up the object, delays script 5s if region is "":
key prim_id = llSetupIPC(string region, key object_id);
if(prim_id != NULL_KEY) { // NULL_KEY if lookup fails
  llSendIPC(prim_id, some_string); // Send an IPC to a connected prim
}
//...
dataserver(key id, string msg)
{
  if(id == prim_id) {
    if(msg == "") { // Empty reply message means the message was lost
      prim_id = NULL_KEY;
    } else {
      doSomethingWith(msg);
    }
  }
}

If the receiver is alive but doesn't call llReplyIPC, there will be no dataserver reply. It's up to the programmer to decide whether the normal communication is one-way (reply only if the handle becomes invalid [eg, server prim reset, derezzed, or moved to another region]) or two-way. If the message is lost at a low level (eg, sim restarting, congestion) there would be no reply message.


Escort DeFarge added a comment - 06/Jan/09 06:41 AM
Interesting angle on this Argent... this looks to me as though it could actually be harder for LL to implement... I 'm speculating here as I'm working with incomplete information, however fwiw...

1) There's four new library functions here for LL to implement rather than just one, and also I'm not sure the "setup overhead" is high enough to warrant this complexity (for the reasons stated in the description/comments in this ticket).

2) In all current llRequest... calls, the convention of the key returned to dataserver is generally that it's a per query "transaction" key, rather than a persistent key returning multiple data at arbitrary points in the future..

3) If your proposal or even the proposed llMessageObject is too hard... then I'm wondering whether llRemoteRegionSay(string region, integer channel, string message) may be more feasible for LL to implement? It's not exactly what I had in mind but would be simple to do and would at least be a major improvement over a timer polling llGetEmail!

Regs,
/esc


Argent Stonecutter added a comment - 06/Jan/09 08:49 AM - edited
The number of calls isn't really relevant. It's the semantic distance between the functionality required and the functionality available in the operating system. In this case, I modeled the API on the underlying socket calls that the server would have to make... socket/listen, socket/connect, sendto, and recvfrom.

That's a good point on dataserver, I was thinking in terms of the behavior of http_server and email events, and I suppose it would be cleaner to have an ipc_server event:

Inter-Prim Communication
// In the receiver, register to receive IPC:
llAcceptIPC();
//...
// Source is an ipc_id for the reply message, it is not the UUID of the originating prim.
ipc_server(key source, string msg)
{
    doSomethingWith(msg);
    llSendIPC(source, some_string); // Send a response IPC to the sender of the current message
}

// In the sender, look up the object, delays script 5s if region is "":
key ipc_id = llConnectIPC(string region, key object_id);
if(ipc_id != NULL_KEY) { // NULL_KEY if lookup fails
  llSendIPC(ipc_id, some_string); // Send an IPC to a connected prim
}
//...
ipc_server(key id, string msg)
{
  if(id == ipc_id) {
    if(msg == "") { // Empty reply message means the message was lost
      ipc_id = NULL_KEY;
    } else {
      doSomethingWith(msg);
    }
  }
}

Of course you wouldn't call socket/listen for each prim that called llAcceptIPC, rather you would have a single listener process on the sim that would be responsible for maintaining a list of prims that had registered as a listener, forwarding llSendIPC requests, and (if the region parameter is optional) communicating with the central registry. Writing such a handler in Perl, Tcl, or Python would be no more than a day's work.

An alternative solution, now that I've looked at llEmail again, would be this:

llEmailServer
default {
    state_entry() {
        llEmailServer();
    }

    email(string time, string address, string subj, string message, integer num_left) {
         llOwnerSay("I got an email: " + subj + "\n" + message);
    }
}

Also, looking at the llEmailServer example in the LSL wiki, wouldn't this make the existing API more efficient?

llEmail
default {
  state_entry()
  {
    llSetTimerEvent(10); // Email isn't super-fast, you know.
  }
 
  timer()
  {
    llGetNextEmail("", ""); //Check for emails
  }
 
  email(string time, string address, string subj, string message, integer num_left)
  {
    llOwnerSay("I got an email: " + subj + "\n" + message);
    if(num_left > 0)
      llGetNextEmail("", "");
  }
}

Why wouldn't this code work? Does the sim actually run the email() event from llGetNextEmail() directly rather than doing it in the event queue? o_O;;;


Escort DeFarge added a comment - 06/Jan/09 09:45 AM - edited
Part of the pain of llEmail is that the receiver frequently de-registers from receiving any mail at all... this relates to another venerable bug (SVC-688).

I find myself asking why llGetNextEmail is required at all, and am concluding that there's something wrong with the way the email event is triggered. Why isn't the code just... e.g.

Simpler llEmail
default {
    email(string time, string address, string subj, string message) 
    {
        llOwnerSay("I got an email: " + subj + "\n" + message);
    }
}

I assume this is because the receiving sim is a client of the MTA, and acts like a standard POP3 client. Hence if the sim decides (which it frequently does) to stop requesting mail, then the queue backs up on the SMTP servers (note – the reason i think this is correct is that a sim restart often re-registers its mail client and you get a stream of previously undelivered messages suddenly come through).

I guess this is a long way of saying that llEmailServer()/llAcceptEmail() would indeed be a way to "register" the object with the sim as a client of the MTA and have the sim poll the server if that list of registered clients isn't empty...?


Cinco Pizzicato added a comment - 19/May/09 08:03 PM
We have llMessageLinked(). So I want llMessage(), with key instead of channel. That's the only difference. So:

llMessage(key target, integer num, string str, key id);

If it's not too computationally expensive to send a linked message within an object, then it is not too computationally expensive to send a message to a given UUID within a sim.

Object email should do this, but it doesn't, because for some reason LL wants to bring in all the overhead of a mail subsystem.

Further, prims/objects would, by default, not receive these messages, and be required to do something like llReceiveMessages(TRUE); to start. Then the prim could turn them off if so desired by sending FALSE to the same function.

The addition of these two functions would allow all sorts of duct-tape laggy workarounds to be abandoned in favor of elegant code. How can it possibly be better to, for instance, hash your own UUID, send it to a rezzed object in the start parameter, have the rezzed object do a scan of all nearby prims, loop through them, hash their UUIDs, compare the hash to the start param, and then finally know it's parent..... How can that be better than llMessage(childUUID, timeToDie, "iamyourparent", llGetKey());?

It seems like all that LSL bytecode would be ten times more wasteful than the couple of SQL calls required to find a prim in a sim by UUID. That's what has to be happening for linked messages, and linked messages aren't ever cited as laggy.


Richardjrn Weatherwax added a comment - 10/Oct/09 02:50 PM
would this work for objects in diff sims?
if so then im behind this 10000000000000%