Archived

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

Proxy reconnection to reactivated adapter

We have been investigating using IcePack and had a question. We want to leverage the reactivation feature of IcePack in case a service goes down so that a running client can continue using a reactivated object without having to restart the client. We have been using the example in demo/IcePack/hello in the installation.

Section 20.4.5 of the manual says:

"If a client holds a proxy to an object in an object adapter that is deactivated and then reactivated on a different port, the retry behavior in the client’s Ice run time will automatically refresh the proxy’s endpoints."

With that in mind we run the demo as suggested in the README file:

$ ../../../bin/icepacknode --Ice.Config=config --warn

In a separate window:

$ ../../../bin/icepackadmin --Ice.Config=config -e 'application add "application.xml"'
$ ./client


Everything starts fine and we can use the menu options in client.

Then we purposefully, kill the icebox server started by icepacknode using the kill command on the process id. icepacknode detects this and outputs:

[ icepacknode: Activator: detected server `IceBox1' termination ]

With the client still running, we then type the "t" command and icepacknode outputs this:

[ icepacknode: Activator: activating server `IceBox1'
path = /build/external/Ice-1.2.0/bin/icebox
pwd =
args = --Ice.Config=db/node/servers/IceBox1/config/config_icebox --Ice.Default.Locator=IcePack/Locator:default -p 12000 ]
[ icepacknode: Activator: activated server `IceBox1'(pid = 29200) ]

but the client outputs this:

==> t
Outgoing.cpp:271: Ice::ObjectNotExistException:
object does not exist
identity: Foo
facet:
operation: sayHello

We tried catching this exeption and rebuilding the proxies like this:

try
{
hello->sayHello();
}
catch(const Ice::Exception& ex)
{
cerr << ex << endl;

cerr << "recreating object..." << endl;
try
{
query = IcePack::QueryPrx::checkedCast(communicator->stringToProxy("IcePack/Query"));
factory = HelloFactoryPrx::checkedCast(query->findObjectByType("::HelloFactory"));
hello = factory->create("Foo");
}
catch(const Ice::Exception& ex)
{
cerr << ex << endl;
}
hello->sayHello();
}

but we get this from the client:

Outgoing.cpp:271: Ice::ObjectNotExistException:
object does not exist
identity: Foo
facet:
operation: sayHello
recreating object...
Outgoing.cpp:330: Ice::UnknownUserException:
unknown user exception
unknown user exception text:
IcePack::ObjectDeploymentException
Outgoing.cpp:271: Ice::ObjectNotExistException:
object does not exist
identity: Foo
facet:
operation: sayHello

If the client is stopped and restarted, everyting works fine again.

So we have a fundamental misunderstanding of the above statement in the manual and the capabilities of the Ice runtime and/or we are doing something fundamentally wrong in the code to be able to reconnect the proxies.

Can you please set us straight on this one.

Thanks again,

Brian

Comments

  • benoit
    benoit Rennes, France
    Hi Brian,

    I can't reproduce the exception you are getting. Did you only modify the client or also the server?

    I'm afraid this demo is a little too complicted to demonstrate the automatic connection re-establishement to an object. The problem is that the state of the demo server isn't restored when the IcePack node restarts it again. The Foo hello object is gone when you kill the server.

    I'm attaching a simpler demo to demonstrate the functionality you want to see. It's basically the Ice/hello demo deployed with IcePack. The hello server is registered with the node and the client is doing a lookup by type to find the hello object.

    You should see that the IcePack node will activate the server on demand when the first request comes in. You should be able to kill the server and the client should transparently re-connect to the Hello object. You can even see what's happening under the hood by enabling tracing using the --Ice.Trace.Location=1 option.

    To try out the demo:
    $ cd Ice-1.2.0/demo/IcePack
    $ tar -zxvf simple.tar.gz
    $ cd simple
    $ make
    <follow the README instructions>

    Let me know if you have any issues running this demo!

    Benoit.
  • Benoit,

    Thanks for the response. I downloaded and first tried to compile your example, but I kept getting dependency errors. Finally, I figured out that I must run "slice2cpp Hello.ice" before compiling so whatever rule deals with SLICE_SRCS in the Makefile was not getting executed. Do you why?

    Anyway, once I figured that problem out, I ran the demo and did as you said and it worked fine. However, I noticed that the major difference between the IcePack simple demo and the hello demo is that in hello, I was running the server through IceBox and not as an application. In hello, I killed icebox, not the server application. When I then tried to hit "t" in the client, it could not reconnect as described in my previous email.

    We want to run our servers/servants as services in IceBox and so this is the example we are looking to emulate -- i.e.

    1) the service, and therefore the servant it runs, goes down
    2) the client tries to send a message to that servant
    3) IcePack automatically restarts IceBox and reconnects the client proxy

    Try changing hello/application.xml so the server is only run inside IceBox and I think you will see the problem. Is this a bug or is there something we still do not understand?

    Thanks again for your help,

    Brian
  • mes
    mes California
    Hi Brian,

    The Ice retry mechanism, coupled with IcePack's on-demand activation, is intended to satisfy the requirement for transparent reconnection to servers. In the case of the IcePack hello demo, this feature isn't properly demonstrated because the sample client is given responsibility for creating the well-known object (i.e., by invoking on HelloFactory). Therefore, when the server (or service) is restarted, it has no idea that it needs to reactivate a servant for the well-known object, and this causes the ObjectNotExistException to be raised. A more realistic example would use persistence to allow the server to handle this situation correctly.

    Out of curiosity, I tried reproducing the behavior you described. Unfortunately, I haven't been able to elicit the UnknownUserException. Do you get this result consistently?

    If so, perhaps you could help me out and modify src/IcePack/AdminI.cpp by changing addObject as shown below:
        ...
        try
        {
            addObjectWithType(proxy, proxy->ice_id(), current);
        }
        catch(const Ice::LocalException& e)
        {
            cerr << "addObject failed:" << endl << e << endl;
            ...
    
    Then rebuild IcePack and run the demo again. Please let me know the results.

    Thanks,
    - Mark
  • Mark,

    What you say about the demo makes sense. I did get that error consistently using the demo, but the good news is that I went a head and tried this procedure of killing icebox using our application and it seems to work fine in smoke test mode. I will need to do further testing, but looks good so far.

    I did go ahead and make that change for you in the source, recompile, and re-run, but the newly inserted error message never came out. I've attached a file containing output from the 3 key apps in the demo -- icepacknode, icepackadmin, and client -- just in case it is helpful to you in some way.

    If you want me to try something else, just let me know, otherwise we can close this thread for now.

    Thanks,

    Brian