dworkin / dgd

Dworkin's Game Driver, an object-oriented database management system originally used to run MUDs.
https://www.dworkin.nl/dgd/
GNU Affero General Public License v3.0
103 stars 31 forks source link

Question: Updating LWOs #61

Closed nyankers closed 2 years ago

nyankers commented 2 years ago

I've been hesitant to use LWOs due to them not having an obvious upgrade path like full objects have. In general, when an object has data that needs to be structured, I'll usually just make a lib instead, that way I can upgrade that lib as needed including patching.

The only reason I'm considering them now is I've got need for a data structure that can be passed around easily, but I don't want a full object. Another option is that I could continue put it all in a lib, and just write some copy()-style method in the lib that handles it all, so using LWO still isn't a strong need here.

The trouble is that this data structure would have a persistent lifespan - that is, I could imagine certain instances of it remaining indefinitely. This means, regardless of the approach I use, it needs a plan for upgrades - being able to arbitrarily change code, API, and even data. Libs have that (I'm using a modified version of cloudlib for that, I've added some clone handling and an int->object kfun to speed it up, but otherwise it behaves per cloudlib).

So my question is what you're thoughts are about this. Given how robust DGD's persistence is, its upgrade mechanisms are, etc. I assumed there's some consideration for long-term LWO use. I wonder if either LWOs aren't intended to handle persistent needs or if there's an upgrade model for them I'm just unaware of.

Thanks! <3

dworkin commented 2 years ago

LWOs can be upgraded automatically just as persistent objects are, but they cannot be patched as easily because they are harder to find. To upgrade data within a LWO, you have two options:

nyankers commented 2 years ago

Yeah, patching is the big concern.

I'm hesitant about the first approach. Unless I very carefully limit which objects can even access the LWO, it's entirely possible an LWO could end up in some mixed/mapping variable field somewhere and eventually break. That is, I don't see any advantage this method has over just storing the data on the object itself and writing API accordingly, but I definitely see potential disadvantages.

The second one seems to be the only reliable means for keeping LWOs up-to-date "no matter what" - though it also seems a bit clunky. As far as I know, there's no trigger from DGD to an LWO that says "your code has changed" (and I'd guess writing one could get very messy very quickly), so you'd be checking with every API call that might need a patch. It seems like it should work though.

I was thinking how to handle this with a bit of hacking, e.g. I could make a kfun that allows viewing an object's variables as an array (e.g. ({ 102, "data", "mapping", ([ ]) })) but while that'd theoretically solve the matter, going through every object's data to force a complete upgrade sounds clunky too, haha. If an object is storing large amounts of data in untyped arrays/maps, I'd have to go through every element.

I think for persistent data, I'll stick with the current lib approach I've been doing, and for this particular issue, just write a copy()-style method on the lib itself. I think I'll only use LWOs for short-term data, like events that are too complex to handle with anything lighter.

Thank you very much for your answers. ^^