in reply to Organizing my packages

It is too bad that nobody got around to answering this question (server problems can't have helped). I don't really have an answer either, but I do have some basic ideas.

The basic problem with getting this migration to work is being able to name your resource uniformly and have the same naming work before and after. Therefore I would suggest breaking out the naming logic into an object which Net::Distributed proxies off of, and then have a migration module. There is (as you note) a strong tie between the migration infrastructure and the naming object. There is no issue for children of the Net::Distributed other than the fact that they may need to implement some methods that the migration module will expect. (Note: Storable is likely to be massively helpful for you.)

In order for migration to be able to work you need to have your naming authority set up, persistent, with everyone looks to them for names. When an object wants to migrate it tells the naming authority to delay any name resolutions, it spawns the new child, tells the naming authority where the resource is to be found now, and then exits. Clients just block during the migration process then find the object at the new location.

The naming authority could be something as simple as a relational database. It could be a custom server.

The advantage of the design I proposed is that if someone doesn't want to support migration, they can use a simpler and faster design. If someone thinks it should work differently than it does, they can subclass that proxy object and the difference will ripple properly through all subclasses of Net::Distributed that they might have.

Whether or not you like this design, my suggestion for a good places to look for inspiration are clustering projects like Mosix. Their overall design may differ in key respects, but they have to face the same issue and are likely to have good advice about issues they faced.

Replies are listed 'Best First'.
Re: Re (tilly) 1: Organizing my packages
by dash2 (Hermit) on Feb 06, 2002 at 12:00 UTC

    Interesting solution.

    Actually there are two problems here:

    1. a specific issue with migration methods - need to provide new addressses. I got round this by simply having the Migrator handler initialized with an array of spare addresses, which are popped off to migrated children. So the handler itself is the naming authority.

    2. a general issue with coupling. I came to the conclusion that Handler objects need to be tightly coupled with the Distributed object, which is basically just a facade. Handler objects supply all the functionality for handling messages, so they need to be able to send messages back, etc.

    So now I initialize Handlers with the Distributed object which uses them. If an object requires special behaviour to use a handler, you subclass the handler and provide the special behaviour from the Distributed object's public methods.

    Example: to serialize using Storable, I need to undef a HTTP::Daemon object in Distributed::Transport, because it has a blessed socket which I can't serialize. Of course, if I am using a different transport, this won't apply. Rather than adding migration specific stuff to Net::Distributed::Transport, I can just subclass the Migrator to be Migrator::HTTP, and to automatically undef the Daemon and bring it back to life after subclassing.

    I don't think there is a better solution than this. To provide object-specific behaviour, you either subclass the object, or subclass a related handler. As Distributed is meant to be a facade, subclassing it feels wrong.

    Thanks for your comments. Net::Distributed has had some changes which I will upload shortly; Net::Distributed::Space is coming soon... woohoo.

    dave hj~