Jump to content

"Linkset Data" is coming.


Lucia Nightfire
 Share

You are about to reply to a thread that has been inactive for 422 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

N.B. I think it's been mentioned before in this or another thread, but apparently llLinksetDataWrite(k,v); does not generate a linkset_data() event if k already had the value v. This obviously makes sense in most use-cases, but it does make using LSD as a complete replacement for link messages slightly fiddly. (One possible protocol for an 'active message' is for the sender to write the LSD, and the receiver to delete it. This works fine unless the receiver doesn't receive the message (programming error) in which case the 'pipe could get stuck' if an identical message is common and you don't delete the value) No real reason not to use both if it makes sense to do so.

Link to comment
Share on other sites

4 hours ago, Quistess Alpha said:

I think it's been mentioned before in this or another thread, but apparently llLinksetDataWrite(k,v); does not generate a linkset_data() event if k already had the value v.

This was explicitly discussed while LSD was in development and it was figured that this is preferable, since it makes scripts simpler (no need to handle your own "should I write this value" logic) and reduces redundant events.

(It's very easy to flood the event queue.)

If you definitely want every write to cause an event, you can remove the value when consumed, or add a random bit of data at the end of the value during the write, or you can use a dedicated "something has changed" key which serves as a notification but only contains random data itself.

Edited by Wulfie Reanimator
  • Thanks 1
Link to comment
Share on other sites

Huzzah! I successfully converted my JSON Parser script to use Linkset Data! It only took a couple hours...and it seems no slower from what I can tell so far.

Next steps: Since there is "only" 64K of Linkset Data available for our use, I am considering using it primarily for "volatile data".  But for now, I am only using 2K or so for JSON code + volatile data.  I guess it depends on how much script memory I actually have in the main JSON Parser script (I've been afraid to look).  The Schema script that writes the initial LSD data has 43K memory available, so no hurry there.

 

Link to comment
Share on other sites

  • 2 weeks later...

Happy new year everyone :)

Actually I wanted to discuss this in the next SL Server meeting but explaining the matter in few sentences would be difficult and easier to read here and maybe I will not come to asking there, so we can discuss here instead. :)
 
It happens repeatedly (at least once every few weeks) that the viewer crashes and attachments are rolled back and some important data is lost. And it is not always data you can restore in few seconds. I was hoping LSD will persist crash rollbacks but apparently it was not designed for this but maybe we can use LSD to establish such a persistence. So I wanted ask few questions before I make a reasonable feature request if any.
 
Question 1: Is it correct that attachment data is load from asset servers and then passed from sim to sim and stored back to the asset servers only  when the attachment is detached or the owner logs out or crashed? Back in this thread it was claimed to be so, but not by a Linden, so I better ask to confirm. When it is not correct, the rest is maybe irrelevant.
 
Actually it is naturally to do it this way: Attachments change their data permanently and it is wise to save the data when the attachments stop collecting it, i.e. on detach or on crash. However, I was thinking that detecting a crash works precise but because attachments seem to loose data to crashes sometimes, it seems that there are conditions preventing saving attachments on crash and LL can not fix them.  
 
Hence we can try the data loss prevention. First attempt: When the avatar is leaving a region, the region stores the attachment data to the asset  servers when this data was changed while on the region. Not practicable because the relevant attachments change their state dozens of times on every region and we would overload the asset servers every time we leave a region.
 
The system can not know which data is volatile and must not be saved and which has to be persistent. We need a way to tell the system which data must be kept persistent and which can be lost without problems. To do so, we could use the LSD storage:  
 
Attempt 2: When an attachment is leaving a region after the LSD store of the attachment was changed, the server stores the content of the LSD storage back to the asset servers. Whatever scripts want to keep persistent, they simply put on the LSD storage and when the attachment is attached, they load the actual data from there. As long scripts keep the important data in the LSD storage, crashes will not wipe them.
 
Better but still not fully practicable yet: Some applications will use LSD storage to replace inter-script communication and those attachments will load the asset server needlessly like it was for the attempt 1, because the LSD storage will be changing permanently on every region.
 
Hence the attempt 3: The 'persistent' keys:

integer llLinksetDataWritePersistent(string name, string value);

Creates or changes a persistent key. A key that was created this way is marked as persistent and can only be changed with this function; calling llLinksetDataWrite() for this key fails. A persistent key can be read normally with llLinksetDataRead(). Persistent keys are not protected. To have a key persistent and protected, we can write the data protected and use a secondary persistent key that changes every time the protected key does (like a revision number for persistent-protected data, but it can be even a boolean actually which flips.)
 
Now, when leaving a region after a persistent key was changed on it, the server stores the entire LSD storage with this key back to the asset servers. Changing non-persistent keys will not mark the LSD storage as 'has to be stored'. This way scripts can change the LSD storage without loading the asset servers but once a persistent key was changed, the first leaving the region writes the data into asset servers. A bad crash looses only the data of the last region, not the progress of the entire day.
 
Sometimes we can run into race conditions here: Leaving a region and changing the persistent key after arriving and before crashing. The  leaving region detects crash as well and saves the LSD storage after the entering region already did, invalidating so the LSD content.
 
To prevent this, the LSD storage would have a revision number. When attachment is rezzed, the revision number is reset to 0 on the asset server and rezzed link-set. Every time a persistent key changes, the revision number is increased. When a region server tries to store the LSD storage to the asset server, the data is only accepted when the revision number is newer than on the asset server. This avoids overwriting the stored LSD data with the older content.
 
Now Question 2: Is it possible to write the LSD storage to asset server separate from the rest of the attachment? Can the structure of the attachment asset be organized in a way, that the LSD storage can be stored separately faster and more efficient than saving the entire attachment?
 
When this is not the case than probably the whole attachment must be stored together with the LSD storage for persistence.
 
Question 3: Is the suggested automatic LSD backup possible to tackle?
 
When not, maybe it is more preferable to have a function that triggers the backup manually, e.g. after important data has changed:
 

integer llLinksetDataStore();

The function would store the content of the LSD storage to the asset servers, or when the LSD storage can't be saved separately, then the whole linkset. The function may have a throttle per attachment and fail when called too frequent (be it more often than every 15 minutes) anywhere in the linkset.

  • Like 1
Link to comment
Share on other sites

2 hours ago, Jenna Felton said:

[possible methods to backup attachment memory]

IMO the most sane solution to the problem would be to allow access to the KVP datastore from outside experience-enabled parcels, but I don't see that happening.

  • Like 1
Link to comment
Share on other sites

16 hours ago, Quistess Alpha said:

IMO the most sane solution to the problem would be to allow access to the KVP datastore from outside experience-enabled parcels, but I don't see that happening.

I've noticed this as well, I get around it by hosting my own external KVP system for backups and settings' conflict resolution.  On the device I maintain "Active data" A periodic LSD backup of the important user config which gets mirrored externally. I use unix time stamps to maintain a hierarchy of restore points.  
 

Other data gets broken down by use. Config/Player Content data is force written externally each time it is changed, and that external backup always wins in a restore. If the external source is not available then the local Config Data hash is restored from LSD.  etc .etc.

Things like XP or score are restored from highest value of all restore points.

 

System states are never backed up. 

Can't think of a better way to do it, but if anyone has ideas, I'm eager to learn.

 

Edited by Kehf Nelson
  • Like 1
Link to comment
Share on other sites

Now, I'm at the "next step" where I want one object - with its own LSD - to send that data to another object.

I guess they need to use "llRegionSayTo()" with the "listen()" event..

The use-case is:  64k just ain't enough. But, rather than load a notecard into the "client" object's LSD (with 0.1sec delay per line), llRegionSayTo() has no delay so long as the channel# is negative. 

So, multiple "server" objects could have LSD pre-loaded, and send the data in 1024 byte chunks using llRegionSayTo() to the "client" objects without a throttle or 0.1sec delay.  In an example use-case, both the server and client objects could be attached to the HUD.

Thoughts?

Edited by Love Zhaoying
Link to comment
Share on other sites

7 hours ago, Kehf Nelson said:

I've noticed this as well, I get around it by hosting my own external KVP system for backups and settings' conflict resolution.  On the device I maintain "Active data" A periodic LSD backup of the important user config which gets mirrored externally. I use unix time stamps to maintain a hierarchy of restore points. 

...

That is doable, have a free attachment slot then when collected some important data, attach a backup storage item, send the data to it, or when restoring data, read from it via chat commands and then detach after saving or reading the data. When using RLV it goes even automatically, otherwise needs user action, but then it is a little inconvenient.

I hoped it would work automatically from the attachment itself, with any viewer and without an extra backup item. And without an experience because that is not something any resident can afford. There is an other Jira which was accepted, and maybe (probably not but nice to dream of :)) was the reason to invent the LSD: A grid-wide KVP database to store data persistently. This can be an other solution if it is implemented.

Edited by Jenna Felton
Link to comment
Share on other sites

8 hours ago, Love Zhaoying said:

Now, I'm at the "next step" where I want one object - with its own LSD - to send that data to another object.

I guess they need to use "llRegionSayTo()" with the "listen()" event...

That is the simplest approach. Both 'LSD containers' must have scripts installed with an access API between them. The API must implement access rules (who is allowed to read or write the store, which keys are read-only) and also specify formatting of the data. Especially when the access must be allowed between items of different owners and creators.

But I'd rather wait with this until it is casted in marble that LL is not going to add an outside access to the LSD storage to the LSL. When this happens, the API with this access should be negotiated and added to SL wiki. But there is nothing that prevents anybody to invent this API for very own applications.

  • Thanks 1
Link to comment
Share on other sites

Managed to finally figure out how to get wiki editing access and have added the results of my experimentation (from what I read in this thread, pretty much what everyone else did upon finding this amazing new feature). Mostly in llLinksetDataWrite. Also added some example snippets, one of which seems to semi-reliably prevent data tampering, or at least gives a good starting point to do so.

Have already successfully incorporated LSD into a couple of projects that have been sitting around waiting for me to put the effort in to build some web services to mostly-permanently store configuration data without notecards (soooo 2006!)

I noticed earlier that the Protected functions were incurring exactly an undocumented 0.5s delay but as of this week they don't seem to anymore? I assumed this was due to some sort of time-based hashing algorithm. Why, I have no idea, considering there is no real reason to encrypt the data on-server.

I'm not totally up to speed yet on the wiki's arcane templates so someone else will have to add the control character rezzing bug, though hopefully since this stuff is fresh it will be quickly and quietly fixed...

  • Like 1
Link to comment
Share on other sites

On 1/2/2023 at 1:42 PM, Jenna Felton said:

It happens repeatedly (at least once every few weeks) that the viewer crashes and attachments are rolled back and some important data is lost. And it is not always data you can restore in few seconds. I was hoping LSD will persist crash rollbacks but apparently it was not designed for this but maybe we can use LSD to establish such a persistence. So I wanted ask few questions before I make a reasonable feature request if any.
 
Question 1: Is it correct that attachment data is load from asset servers and then passed from sim to sim and stored back to the asset servers only  when the attachment is detached or the owner logs out or crashed? Back in this thread it was claimed to be so, but not by a Linden, so I better ask to confirm. When it is not correct, the rest is maybe irrelevant.
 
Actually it is naturally to do it this way: Attachments change their data permanently and it is wise to save the data when the attachments stop collecting it, i.e. on detach or on crash. However, I was thinking that detecting a crash works precise but because attachments seem to loose data to crashes sometimes, it seems that there are conditions preventing saving attachments on crash and LL can not fix them.  
 
Hence we can try the data loss prevention. First attempt: When the avatar is leaving a region, the region stores the attachment data to the asset  servers when this data was changed while on the region. Not practicable because the relevant attachments change their state dozens of times on every region and we would overload the asset servers every time we leave a region.

An attachments state is only committed back to asset on detach/clean logoff (there is no difference, logoff=detach).

What is "Attachments change their data permanently"? An argument could be make for any single object attribute being permanent or temporary entirely on how its being used in a particular application.

I do not know the reasons for why timeout (ie crash or forced logout) does not result in a detach. Its possible this is to avoid unwanted results of commit at an unexpectedly point, eg. safer to assume that last intentional detach/logout is going to be consistent to what the user wants/expects.

Committing back to asset on region change would increase the time it takes to do region changes. Detached everything then reattach it, now add that time to every TP and region cross and ask if you would want that additional delay.

 

If you are crashing/disconnecting often enough that this is an actual issue, you may want to address what is causing that to happen. Generally the loss of changes on attachments on DC hasn't been that big of a problem, more of a possible annoyance for a user when it happens at an inconvenient time, like forgetting/not knowing to do a detach cycle after doing a lot of changes before the rest of their session do stuff that has higher risk of ending in a timeout/DC.

  • Like 2
Link to comment
Share on other sites

5 hours ago, Kadah Coba said:

I do not know the reasons for why timeout (ie crash or forced logout) does not result in a detach. Its possible this is to avoid unwanted results of commit at an unexpectedly point, eg. safer to assume that last intentional detach/logout is going to be consistent to what the user wants/expects.

It's the "LKG" (Last Known Good) principle.

The server has no idea why you disconnected uncleanly. Could be network issues, could be something you picked up messed things up on your server side. If the server commits your state, you might be trapped in a non-working state and that will be hairy.

So, the server simply rolls your state to "LKG" state, the state where you actually logged in, rezzed, and exist in-world properly.

Edit: An analogy is SQL "Transaction". When you logged in, every attachment issues "Begin Transaction". When you detach an item, the detached item issues "Commit Transaction". An orderly Quit results in all attachments issuing "Commit Transaction" but without changing the attachment state.

Edited by primerib1
  • Like 1
  • Thanks 2
Link to comment
Share on other sites

16 hours ago, primerib1 said:

It's the "LKG" (Last Known Good) principle.

The server has no idea why you disconnected uncleanly. Could be network issues, could be something you picked up messed things up on your server side. If the server commits your state, you might be trapped in a non-working state and that will be hairy.

So, the server simply rolls your state to "LKG" state, the state where you actually logged in, rezzed, and exist in-world properly.

Edit: An analogy is SQL "Transaction". When you logged in, every attachment issues "Begin Transaction". When you detach an item, the detached item issues "Commit Transaction". An orderly Quit results in all attachments issuing "Commit Transaction" but without changing the attachment state.

That was my assumption. Had forgotten about that term for it. x3

  • Like 2
Link to comment
Share on other sites

Okay here's a question:

If an item has entries in LSD, then the whole 64KiB LSD store will be moved to the new sim after successful crossing, right? But if the item does not create any key:value pair in LSD, then there will be no LSD store, and nothing to move, right?

What if the item performs an 

llLinksetDataReset()

before crossing? Will that result the sim skipping LSD store copy?

Or if the item does key:value pair deletions manually that ended up with no key:value pair left over in the LSD store?

The reason I'm asking this is that I'd like to keep my item's script load as small as possible to help increase smoothness during crossing.

Edited by primerib1
  • Like 1
Link to comment
Share on other sites

2 minutes ago, Love Zhaoying said:

That would be very useful for the way I am using LSD.

Well, you can add a comment explaining your usage of LSD and why the function will be useful to you.

I already did mention  "poor man's dict/hashtable" in the ticket itself, but if more scripters pipe up in there, it will probably be taken more seriously 😉

  • Thanks 1
Link to comment
Share on other sites

24 minutes ago, primerib1 said:

Well, you can add a comment explaining your usage of LSD and why the function will be useful to you.

I already did mention  "poor man's dict/hashtable" in the ticket itself, but if more scripters pipe up in there, it will probably be taken more seriously 😉

Done.

Link to comment
Share on other sites

From a recent blog (backed by a comment by Rider Linden during the Jan 10 Server/Simulator/Scripting meeting):  "An update to Linkset Data to fix the sorting for LSDFindKeys is being targeted for a maintenance release in early February."

My search-fu is weak and I can't find a reference what is specifically being fixed or what the problem is.  Is anyone here able to enlighten me?

Thanks

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

35 minutes ago, Anna Salyx said:

From a recent blog (backed by a comment by Rider Linden during the Jan 10 Server/Simulator/Scripting meeting):  "An update to Linkset Data to fix the sorting for LSDFindKeys is being targeted for a maintenance release in early February."

My search-fu is weak and I can't find a reference what is specifically being fixed or what the problem is.  Is anyone here able to enlighten me?

Thanks

I use the LSD functions every day, but didn't have a reason to use FindKeys yet.

Link to comment
Share on other sites

Thank you.   I don't use the FindKeys very often but one of my key projects does need it and having a consistent sort is going to be, well maybe not actually critical, but very helpful. I'll be looking forward to this fix.

Edited by Anna Salyx
  • Like 1
Link to comment
Share on other sites

On 1/11/2023 at 12:24 AM, primerib1 said:

Okay here's a question:

If an item has entries in LSD, then the whole 64KiB LSD store will be moved to the new sim after successful crossing, right? But if the item does not create any key:value pair in LSD, then there will be no LSD store, and nothing to move, right?

What if the item performs an 

llLinksetDataReset()

before crossing? Will that result the sim skipping LSD store copy?

Or if the item does key:value pair deletions manually that ended up with no key:value pair left over in the LSD store?

The reason I'm asking this is that I'd like to keep my item's script load as small as possible to help increase smoothness during crossing.

One comment here.  LSD is a prim property independent of any script.  Much like hover text, texture animation, particles, and etc, LSD persists if you remove the script. So deleting/resetting the data store will have zero effect on "script load" as is your stated purpose/concern.  I don't know how much overhead is involved when objects with any of the "extended" properties set are moved from region host to region host, or how much of a concern that truly is, but from a script / script load perspective, that particular overhead is, I believe, non-existent.

I do like the requested function to delete keys based on regex pattern though, that can and will be a very useful function.

 

  • Like 1
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 422 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...