Archived

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

IceGrid + IceBox + IceStorm - service as a publisher/subscriber

Hi!
I'm new to Ice so I run through a couple of tutorials and basically now I want to create a sample app. Services will be replicated and available under some name, lets say "Hello". Now the client connects to one of the instances via locator and name "Hello" and sends some request. This "query" is then replicated to the rest of the instances (so the state of all instances will be similiar). I came up with this idea:
* Service runs under IceBox
* Service registers adapter, fetches proxy and subscribes it to a topic
* after servant receives query from the client it sends some message to the specified topic.

However several problems occur. First - service needs to be available under well known name and when I try to register sever instances of the same service to a given topic - exception is thrown (AlreadyRegistered).

Second - when the service stops (stop() method) I try to deregister subscriber from the topic but the IceStorm service is down (or so assume cause - Ice.NoEndpointException proxy = "IceStorm/topic.HelloService-topic -t @ IceStorm-1.IceStorm.IceStorm.TopicManager")

Third - I assume there will be problems with service start order - what if IceStorm will start later than HelloService etc).

Comments

  • matthew
    matthew NL, Canada
    However several problems occur. First - service needs to be available under well known name and when I try to register sever instances of the same service to a given topic - exception is thrown (AlreadyRegistered).

    You cannot register the same name twice. It sounds like what you want is to setup a replicated service. You can find out more information on service replication in the Ice manual. You might also want to look at cpp/demo/IceGrid/replication, and perhaps Issue 21 of Connections (http://www.zeroc.com/newsletter/issue21.pdf).
    Second - when the service stops (stop() method) I try to deregister subscriber from the topic but the IceStorm service is down (or so assume cause - Ice.NoEndpointException proxy = "IceStorm/topic.HelloService-topic -t @ IceStorm-1.IceStorm.IceStorm.TopicManager")

    If you get a NoEndpoints exception, then, yes, the IceStorm server is down. In this case, you can likely ignore the exception.
    Third - I assume there will be problems with service start order - what if IceStorm will start later than HelloService etc).

    If HelloService tries to contact IceStorm, and assuming IceStorm is managed by IceGrid, then there would be no issue as IceGrid would start IceStorm. If this is not your setup, then please provide more information.
  • OK since there is a problem with server startup order, I decided to migrate IceStorm to different server.

    I solved the problem with naming by registering each servant twice (once under well-known-name <Hello> and the second time with UUID). The problem was that each time client contacted one of the instances and the instance sent message to the topic, only one subscriber received it. IceStorm threw and error that the rest of the objects cannot be found. After some time I realized that those 3 services were running in replica group. When I detached them from that group suddenly all 3 were receiving message from the topic.

    Now I know that I must be doing something wrong or misusing the Ice itself. But I wanted to keep those services in replica-group (for load balancing) and still make it possible for the to communicate in publish/subscribe manner. Can this be achieved?
  • matthew
    matthew NL, Canada
    What issues with startup order? I'm not entirely clear on what are trying to do. Do you intend your subscribers to be replicated?
  • Servants must be replicated. Each servant is simultaneously publisher/subscriber to the topic. When one of the load-balanced servants receives request from client it must sent message on that topic for other servants (to keep the state between them synchronized). The problem is that only one servant/subscriber receives a message. IceStorm says that it can not find the rest of them. One I removed servants (adapters) from replica group - all servants started receiving messages, but now there is no replication though.

    I didn't want this exception occurring when unsibscribing from the topic, so now IceStorm lives in a separate service and I don't have to bother that IceStorm will be stopped before services will unregister - this is what I meant by "startup order" (sorry for not being clear :) I know that probably it doesn't matter but I thought that this could be causing my problems.
  • matthew
    matthew NL, Canada
    Ok, the situation is that you host two Ice objects in each server. One Ice object is replicated, the second is used to subscribe to IceStorm. I suspect that you've been using a replicated object for the IceStorm subscriber. This is incorrect. This subscriber object should not be replicated; if it is, IceStorm will only send the data to one of the replicas (after all, replication says they are all the same) causing the problems that you've observed. You can create a non-replicated proxy by calling createIndirectProxy on your replicated object adapter.

    Please check the earlier referenced documentation for more details.
  • OK, so my fo service looks like this:
    m_adapter = communicator.createObjectAdapter ("HelloService-" + id);
    m_service = new HelloI (id, m_topic);
    m_adapter.add (m_service, communicator.stringToIdentity ("HelloService"));
                            
    Identity ident = new Identity(Ice.Util.generateUUID (), "");
    m_serviceProxy = m_adapter.createIndirectProxy (ident);
    
    m_topic.subscribeAndGetPublisher (null, m_serviceProxy);
    m_adapter.activate ();
    

    m_topic is initialized earlier and is of type TopicPrx. Adapter is replicated. When I subscribe, IceStorm confirms in logs that indeed subscribers came. But after first messages are sent, it throws exceptions that previously subscribed objects (indirect proxy) cannot be found. Locator for IceStorm is set to point to the IceGrid registry.
  • matthew
    matthew NL, Canada
    Sorry, that should have been createDirectProxy.
  • m_serviceProxy = m_adapter.createDirectProxy (ident);
    

    replaced with the code above ... still the same error.
  • matthew
    matthew NL, Canada
    It cannot be the same error, since direct proxies don't go through IceGrid, they would go directly to the hosting server. What message do you get exactly?
  • [ 01/15/09 22:25:55.708 icebox: Topic: HelloService-topic: subscribeAndGetPublisher: CC29088A-47D6-45EB-B757-DD81A2D8485C ]
    [ 01/15/09 22:25:55.861 icebox: Topic: HelloService-topic: subscribeAndGetPublisher: 376BA3C7-5FF8-49B1-B2B8-8DCCCEDC5339 ]
    [ 01/15/09 22:25:55.937 icebox: Topic: HelloService-topic: subscribeAndGetPublisher: 0E1FEF83-2641-4619-A808-8EC0871B3098 ]
    [ 01/15/09 22:26:05.736 icebox: Subscriber: 00BD57F0 CC29088A-47D6-45EB-B757-DD81A2D8485C: subscriber errored out: OutgoingAsync.cpp:305: Ice::ObjectNotExistException:
    object does not exist:
    identity: `CC29088A-47D6-45EB-B757-DD81A2D8485C'
    facet:
    operation: serviceSaidHello retry: 0/0 ]
    [ 01/15/09 22:26:05.767 icebox: Subscriber: 00BD8BA0 376BA3C7-5FF8-49B1-B2B8-8DCCCEDC5339: subscriber errored out: OutgoingAsync.cpp:305: Ice::ObjectNotExistException:
    object does not exist:
    identity: `376BA3C7-5FF8-49B1-B2B8-8DCCCEDC5339'
    facet:
    operation: serviceSaidHello retry: 0/0 ]
    [ 01/15/09 22:26:05.801 icebox: Subscriber: 00BDB350 0E1FEF83-2641-4619-A808-8EC0871B3098: subscriber errored out: OutgoingAsync.cpp:305: Ice::ObjectNotExistException:
    object does not exist:
    identity: `0E1FEF83-2641-4619-A808-8EC0871B3098'
    facet:
    operation: serviceSaidHello retry: 0/0 ]

    Should I somehow register this direct proxy or keep it alive?
  • matthew
    matthew NL, Canada
    You have to register the servant for that identity... I don't see that being done anywhere in your code :)
  • Yeeey, it works. I've added this line:
    m_adapter.add (m_service, ident);
    

    and now everything works as expected :) Thanks for help!