Archived

This forum has been archived. Please start a new discussion on GitHub.

Dynamic Service Discovery with IceGrid

Assume I have a slice interface like:
module dictsvc {
  sequence<string> Results;
  interface IDictionaryService {
     Results Match(string input);
  };
};

In my hypothetical environment I have many different sources of dictionaries that I want to be able to search from an Ice Client. For purposes unrelated to this example, lets say I want to manually execute the services that expose these Ice Objects so I don't want to use any automatic IceBox style instantiation.

Each one of these separate services exposes the same Ice Interface (IDictionaryService) so they are contractually the same but functionally would return different results to the same function call / parameter combo.

From my client application, I want to find all of the available IDictionaryService instances available. After discovering all of the available instances, I want to be able to do some investigation on which one to use. For instance maybe the IDictionaryService has some metadata that I could look at, for this example something like "Language=English". From my client I could examine this meta data and choose the appropriate proxy to invoke my "Match" function call on.

I'm struggling to understand how to design this on Ice.

I have an installed IceGrid Repository, and following the examples I can easily register new object instances with unique AdapterId's and they show up in the Dynamic Object Adapters section of my registry (via IceGrid Admin Gui). I've read the documentation regarding Well-Known Objects and the IceGrid but I cannot 100% determine if this is the applicable solution. It seems like well known objects are registered with IceGrid in a less dynamic fashion than I am envisioning and I cannot find an example of a server registering itself as a well known object. I also cannot find anything that would lead me to understand how multiple servers implementing the same slice interface register themselves as a well known object. The IceGrid Query interface looks exactly like what I want to use from my client, but I cannot see how my servers should register at run time properly. It feels like there should be a query interface for the Dynamic Object Adapters.

I hope my question is clear. Any resources or suggestions are welcome.

Thank you-

Comments

  • benoit
    benoit Rennes, France
    Hi,

    Registering well-known objects dynamically requires to create an IceGrid administrative session with the IceGrid registry. You can't do it through Ice properties. We document how to create administrative session at this link: IceGrid Administrative Sessions. Once you have created an administrative session, your program can obtain the IceGrid::Admin object using IceGrid::AdminSession::getAdmin().

    The IceGrid::Admin interface allows to add, update, remove well-known objects with IceGrid using the addObject, addObjectWithType, updateObject and removeObject methods.

    Cheers,
    Benoit.
  • Benoit-

    Thank you so much for the fast response. Are well-known types and the methodology you describe the recommended way to design an application similar to what I described in the original posting? I'm just trying to ensure I am not missing a concept that more accurately implements my desired behavior.

    Thanks again-
    Rick
  • benoit
    benoit Rennes, France
    Hi,

    Using the well-known objects and the IceGrid registry is fine for discovering services. Another possibility for registering your well-known objects, object adapters and servers would be to use IceGrid nodes and the IceGrid deployment mechanism (where you describe the deployment with IceGrid XML descriptors). See the Ice manual for more information.

    Regarding the design of your interfaces, you will need to add getMetaData method to your IDictionaryService interface for clients to retrieve the metadata associated with each server. Your clients can then use the IceGrid::Query::findAllObjectsByType method to retrieve all the objects with a given registered type (registered with the IceGrid::Admin::addObjectWithType method). They can then invoke getMetadata on each object to retrieve the metadata for each server and select the best service.

    Note that this will require invoking on all the servers each time you want to find a service. You might want to consider caching the metadata in the client to not have to retrieve the metadata all the time.

    Another option would be to roll-out your own registry. Your server would register with your own registry and would provide their metadata at registration time. This would allow your clients to query the registry with a set of "query" metadata to find the best service.

    Cheers,
    Benoit.
  • Thank you Benoit, very helpful.
  • One issue I'm running into with the strategy discussed here for discovery of ICE objects, is that if a server that is hosting a registered well known ICE object crashes, it leaves a 'hanging' well known object registration to a no longer valid ICE object. My mechanism to discover ICE objects can then 'discover' an invalid ICE object and attempt to create a proxy to that no longer valid object.

    Is there any sort of built in mechanism in the IceGrid / Locator service design to automatically detect and purge no longer valid well known objects?
  • benoit
    benoit Rennes, France
    Hi,

    Could you tell us a bit more which strategy you choose to implement? Do you use the IceGrid deployment mechanism? Do you implement a custom registry to let your clients find the matching services?

    IceGrid doesn't have a mechanism to automatically unregister "stale" well-known objects. It simply can't figure out what is a "stale" well-known object. An Ice object being inaccessible for some time doesn't necessarily mean it won't be accessible again at some point (if the network connection is lost and re-established for example, or if the server is restarted after a crash).

    As you are discovering, IceGrid is better suited for applications where the deployment doesn't change often, servers can be added and removed but this is typically done through a registration mechanism.

    If the lifetime of your server's well-known object is bound to the server lifetime, you could consider adding some house-keeping service to ensure that well-known objects are correctly removed once the server is gone. It could for example ping at regular intervals the well-known objects. If the ping fails, it could un-register the well-known object (it could also retry several times before considering the server is gone in case the failure is caused by a transient network problem...).

    If you implement a custom registry service, another option would be for your servers to establish a session with your registry. The services from your servers would be advertised by your registry as long as your server has an active session with the registry.

    Cheers,
    Benoit.