03dab36e3e
queue up an invoker unit which would go off and do some database stuff and then by the time it came back and was ready to publish its results to a distributed object, the object in question would have been destroyed for any of a variety of fairly natural reasons (client disconnected or logged off, game was abandoned, dog ate homework). One "solution" to this problem would be to litter our games' code with thousands of calls to isActive() in the handleResult() methods of our invoker units. We've done a bit of that in Yohoho but I've resisted starting down that path in our other games. Another solution would be to create an Invoker.Unit wrapper that takes a reference to the distributed object (or objects) that it will be modifying and have the common unit code check that the object(s) in question are still alive at the end of the asynchronous operation and not call handleResult() if they are not. This has numerous problems: what do you do if one object is alive but not another, how do you incorporate this functionality in with the numerous other Invoker.Unit derivations we have that simplify our lives in other ways (without getting crazy and starting to use something like AOP), do you silently abort the operation or log something? So instead, I've come around to the idea that this is simply a dirty fact of life in asynchronous programming and the fact that we can accept modifications to distributed state after the distribted object in question is dead is a good thing. We used to log a warning every time this happened and freak out even more substantially if one tried to start a transaction on a dead object. Now we will simply log an informational message (I don't think this sort of thing should be silently ignored because there are some cases where it is an indication of incorrect code, those are simply more rare). We will also allow a transaction to be started on a dead object and when the transaction is committed, all the events involved will be dropped just like a single modification would have been dropped on that object. This allows the most sensible thing to happen which is any results that are published to still live objects will actually be published and results published to dead objects will be dropped without making a big fuss. Since a dead object by definition cannot have subscribers, no one could possibly have cared about the dropped events anyway. Also widened. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4545 542714f4-19e9-0310-aa3c-eee0fc999fb1