Hi Mark,
The most basic solution is to create a replicated manager/factory object implemented by your servers (distributed across the world), and tell each client which servers to try, and in which order to try them.
(There is no IceStorm, IceGrid or any other service involved in this: just plain Ice)
The client configuration would be something like:
Code:
MyFactory=factory:ssl -h server1 -p 10000:ssl -h server2 -p 10000:ssl -h server3 -p1000
(here "factory" is the object-id of this replicated object, and each client would list the servers in closest-to-furthest-away order)
Your client code would use communicator.propertyToProxy("MyFactory") to create the corresponding proxy. Without additional configuration, Ice would pick one of the server endpoints at random, which defeats the ordering. You need to add:
Code:
MyFactory.EndpointSelection=Ordered
to tell Ice to try the endpoints in the provided order.
(I recommend reading "Connection Management in Ice" in http://www.zeroc.com/newsletter/issue24.pdf for more details on how Ice established connections).
Now, this simple solution works, but is not very flexible. If you add a new server, or move a server from one machine to another one, you'll have to update the configuration of all your clients (otherwise, they'll still work but won't find the new/moved server).
One improvement would be to use DNS to list your servers, i.e. you would create a DNS name "replicatedserver" that returns the server IPs in the desired order (presumably each client uses its own, local, DNS server). So the client configuration would become:
Code:
MyFactory=factory:ssl -h replicatedserver -p 10000
MyFactory.EndpointSelection=Ordered
and each time you add a new server or move a server, you would update the DNS entry for "replicatedserver".
If this DNS approach doesn't work (perhaps it's too hard to control the order of IPs in your various DNS servers), then you could instead introduce an intermediary server, whose only job is to provide the clients with the "best" factory proxy. Its operation would be something like:
Code:
interface FactoryLocator
{
Factory* getFactory(string clientLocation);
};
or
Code:
interface FactoryLocator
{
Factory* getFactory();
};
if you can use the client's IP to determine its location.
Of course, for fault-tolerance, you'd want to replicate this FactoryLocator server. The client would connect to one of the factory locators (not necessarily the closest one), get a good Factory proxy and proceed from there. Each time you add a new server/move an existing server, you would just need to update your factory locator instances.
The next level in sophistication is to use IceGrid to manage your servers, and replace the "Factory locator" by your own Ice::Locator implementation. This implementation would delegate to the IceGrid registry, and provide the ordering logic (closest to furthest), since IceGrid doesn't include this policy.
Best regards,
Bernard