Hi--
So I've been using on-demand behavior transfer to pull into a minimal snapshot just what's required to run a particular application from a kitchen-sink snapshot (with a bunch of prerequisites from various authors). I ran into a situation that made me realize that my approach wasn't accurate enough.
What I had been doing was responding to each message not understood by installing a "loader" method [(RemoteMessageDispatcher class)>>loadAndResend and friends]. When run, the loader method fetches the appropriate method from the kitchen-sink system (using a special network client), then resends the message which originally wasn't understood. The whole process gets kicked off by a loader method that represents an entry point for the application in the kitchen-sink system.
I got pretty far doing this. New classes were installed and initialized properly, as a side-effect of transferring method literals. Super-sends and underrides were handled properly, and transfer loops were avoided. But I hadn't considered that the possibility of needing an override before the need for it is detected. In this case, one of the application classes had an implementation of >>name in the kitchen-sink system, and an application object in the minimal system sent that message. The receiver happily ran Object>>name instead of the override; the minimal system had no way of knowing that it should have installed the overriding method first.
This problem seems unsolvable in general (at least, without perfect type inference, which I am not interested in pursuing). Left unchecked, it could yield highly subtle errors, and so renders any session untrustable. So, I've changed my approach to an even more brute-force one. I'm running the kitchen-sink snapshot in the simulator, and reporting every simulated send, after the entry point, to another copy of the kitchen-sink snapshot which is running normally. That snapshot, in turn, will make sure that the involved method is installed in the minimal snapshot.
I appreciate any suggestions or comments. Well, apart from "this is all nuts"; I've already thought of that one. :)
thanks,
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
I'm absolutely sure this is a problem we discussed early on (early last year probably) and I thought we had worked out a solution. If you haven't already, try searching any emails you have saved on the matter though I think it was mostly done on skwakking fridays.
You need some flag in a method-like dictionary to say that the message name has been completely resolved down to the class of the receiver. The bad bit is that means having almost a C++ vtable for each class. Or you could invert it and have a table for each known selector that lists the classes for which it has been resolved. A small optimisation would be to look up the class chain to where it has been resolved and then ask the server image if there is any overrider below that. Set the flags of the 'lower' classes as appropriate. It's an expensive problem though since every message that needs to go to a superclass will ahve to check the overrides flag.
Yuck.
tim
Tim writes:
I'm absolutely sure this is a problem we discussed early on (early last year probably) and I thought we had worked out a solution.
Hmm, I think it only occurred to me to do this on-demand stuff just this March, when I had a real need to move an application from a kitchen-sink snapshot to a minimal one.
You need some flag in a method-like dictionary to say that the message name has been completely resolved down to the class of the receiver... Yuck.
Yeah. :) And I also just realized that an application's behavior could very well depend on some new *version* of a method which exists on both sides at the beginning. Then you have to get into comparing the content of methods from both sides (by hashing instructions and literals, I suppose). It seems even more strongly to me now that the simulator-based solution is the only completely accurate one.
On the other hand, one might just hope that the application hasn't messed much with "system" methods and classes, and do the inline thing, then just try to debug whatever discrepancies crop up, in the normal way (hoping that they aren't too subtle). There could certainly be practical niceties to that... it'd likely be a much faster process, since, as you mentioned earlier, simulation is pretty darned slow. :) It's also much harder to provide an automated service that involves the simulator. :)
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
On Saturday 03 July 2004 4:14 pm, Craig Latta wrote:
This problem seems unsolvable in general (at least, without perfect type inference, which I am not interested in pursuing). Left unchecked, it could yield highly subtle errors, and so renders any session untrustable. So, I've changed my approach to an even more brute-force one. I'm running the kitchen-sink snapshot in the simulator, and reporting every simulated send, after the entry point, to another copy of the kitchen-sink snapshot which is running normally. That snapshot, in turn, will make sure that the involved method is installed in the minimal snapshot.
I appreciate any suggestions or comments. Well, apart from "this is all nuts"; I've already thought of that one. :)
Why don't you just send over a catalog of the class contents when you send over the first method for it?
That way you can populate the method dictionary with stubs that will understand that they need to replace themselves.
That wouldnt work, would it? What if the first method is the one already declared on a superclass. i.e. I send a bunch of methods to a class, only the 7th one doesnt respond with a DNU, that is the first time you would need to go to the remote snapshot.
You must know what classes you want from the remote, yes? At the point where you get the "shape" of the remote class use Ned's idea and get the catalog then.
Russell
-----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev- bounces@lists.squeakfoundation.org] On Behalf Of Ned Konz Sent: Sunday, 4 July 2004 10:51 AM To: The general-purpose Squeak developers list Subject: Re: a wrinkle in on-demand behavior transfer
On Saturday 03 July 2004 4:14 pm, Craig Latta wrote:
This problem seems unsolvable in general (at least, without
perfect
type inference, which I am not interested in pursuing). Left unchecked, it could yield highly subtle errors, and so renders any session untrustable. So, I've changed my approach to an even more brute-force one. I'm running the kitchen-sink snapshot in the simulator, and reporting every simulated send, after the entry point, to another copy of the kitchen-sink snapshot which is running normally. That snapshot, in turn, will make sure that the involved method is installed in the minimal snapshot.
I appreciate any suggestions or comments. Well, apart from "this
is
all nuts"; I've already thought of that one. :)
Why don't you just send over a catalog of the class contents when you send over the first method for it?
That way you can populate the method dictionary with stubs that will understand that they need to replace themselves.
-- Ned Konz http://bike-nomad.com/squeak/
Hi Craig,
I got pretty far doing this. New classes were installed and initialized properly, as a side-effect of transferring method literals. Super-sends and underrides were handled properly, and transfer loops were avoided. But I hadn't considered that the possibility of needing an override before the need for it is detected. In this case, one of the application classes had an implementation of >>name in the kitchen-sink system, and an application object in the minimal system sent that message. The receiver happily ran Object>>name instead of the override; the minimal system had no way of knowing that it should have installed the overriding method first.
I guess that you have to store also the absence of an overwritten method. So even if the new class Foo is already present in the system, but "name" is called the first time on an object of it, you look up name on the kitchen sink image, as you did not flag it as absent yet. As in your example it is there, you just load it, if it had not been there, you flag it as "definitely not here" in the method-dic of the class Foo, and are faster the next time - I think it should not hurt too much, if you let the method lookup find a "definitely not here" vs. a "not here". ;-)
Makes sense?
Cheers,
Markus
This problem seems unsolvable in general (at least, without perfect type inference, which I am not interested in pursuing). Left unchecked, it could yield highly subtle errors, and so renders any session untrustable. So, I've changed my approach to an even more brute-force one. I'm running the kitchen-sink snapshot in the simulator, and reporting every simulated send, after the entry point, to another copy of the kitchen-sink snapshot which is running normally. That snapshot, in turn, will make sure that the involved method is installed in the minimal snapshot.
I appreciate any suggestions or comments. Well, apart from "this is all nuts"; I've already thought of that one. :)
thanks,
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
Markus Gaelli writes:
I guess that you have to store also the absence of an overwritten method. So even if the new class Foo is already present in the system, but "name" is called the first time on an object of it, you look up name on the kitchen sink image, as you did not flag it as absent yet. As in your example it is there, you just load it, if it had not been there, you flag it as "definitely not here" in the method-dic of the class Foo, and are faster the next time - I think it should not hurt too much, if you let the method lookup find a "definitely not here" vs. a "not here". ;-)
Hmm, the simulator-based solution sounds simpler than that. :)
thanks,
-C
-- Craig Latta improvisational musical informaticist craig@netjam.org www.netjam.org [|] Proceed for Truth!
squeak-dev@lists.squeakfoundation.org