Ice.ObjectNotExistException with ice_fixed in bidir connections

ThomasSThomasS Member Thomas SOrganization: bluecrestcapitalProject: market data

Hi,

In 3.7.2 I have started to receive Ice.ObjectNotExistException when using ice_fixed and trying to send a callback on a bidirectional connection. Removing the ice_fixed fixes the problem for my C# clients but it seems that it is a requirement to make the javascript clients work (https://forums.zeroc.com/discussion/46532/nodejs-callback-implementation). The problem happen when calling the same method a second time after getting a timeout exception (by putting a break-point on the server code). The following calls are received, execute and return normally but the callbacks throw Ice.ObjectNotExistException every time.

I can reproduce by taking the bdir example and duplicating line 34 in https://github.com/zeroc-ice/ice-demos/blob/3.7/csharp/Ice/bidir/Client.cs.
That causes the second call to throw Ice.ObjectNotExistException calling the call back.

By playing a bit with the demo code I noticed that I don't get this exception when running the whole using block in a loop ie by creating a new communicator for every call. But I would think that it is not the best way to do it.

Do I have to do something particular
Would you be able to advise on this please?

Thanks

Comments

  • xdmxdm ZeroC Staff La Coruña, SpainAdministrators, ZeroC Staff Jose Gutierrez de la ConchaOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff

    Hi Thomas,

    When using bidir connections you should keep in mind that the lifetime of the fixed proxy is tied to the lifetime of the connection used to create it, the application should be prepared to deal with connection lost, I suspect that in your case Ice run-time is closing the connection, and subsequent calls are using a connection that was not setup for bidirectional use.

    You can check if the connection is being close by enabling network tracing Ice.Trace.Network=1

    You should also review the bidir connection documentation

    If the client forgot to call setAdapter on the connection, the notify call on the fixed proxy fails with an ObjectNotExistException raised by the client and propagated to the server.

    Cheers,
    José

  • ThomasSThomasS Member Thomas SOrganization: bluecrestcapitalProject: market data

    Hi Jose,

    Thanks for the explanation, but I am not sure that it is what is happening here.
    I have tried again with Ice.Trace.Network=1 and can't see any lost connection.

    I think it boils down to having several calls on the same fixed connection, I have attached the modified client from the demo project I have linked to above.

    On the server It does throw the exception with the first callback after the second call has been received.
    On the client it just stops receiving the callbacks for the first call.

    Thanks,
    Thomas

  • benoitbenoit ZeroC Staff Rennes, FranceAdministrators, ZeroC Staff Benoit FoucherOrganization: ZeroC, Inc.Project: Ice ZeroC Staff

    Hi,

    Your modification is equivalent to running the following code in the client:

    // C#
    var communicator = Ice.Util.initialize(ref args, "config.client")
    
    var server = CallbackSenderPrxHelper.checkedCast(communicator.propertyToProxy("CallbackSender.Proxy"));
    var connection = server.ice_getConnection();
    
    var adapter1 = communicator.createObjectAdapter("");
    var proxy1 = CallbackReceiverPrxHelper.uncheckedCast(adapter.addWithUUID(new CallbackReceiverI()));
    connection.setAdapter(adapter2);
    server1.addClient(proxy1);
    
    var server2 = CallbackSenderPrxHelper.checkedCast(communicator.propertyToProxy("CallbackSender.Proxy"));
    var adapter2 = communicator.createObjectAdapter("");
    var proxy2 = CallbackReceiverPrxHelper.uncheckedCast(adapter.addWithUUID(new CallbackReceiverI()));
    connection.setAdapter(adapter2);
    server2.addClient(proxy2);
    

    You can verify this by printing out proxy.ice_getConnection().ToString() and verify that both Run methods are indeed using the same Ice connection.

    There can only be one object adapter associated with an Ice connection. If you replace the previous object adapter, this object adapter will no longer be able to dispatch bi-dir invocations receiver over the connection and the peer will get an Ice.ObjectNotExistException for the Ice objects registered with this previous object adapter.

    You should use two different Ice connections if you want to use two distinct object adapters. This is what you achieve by creating different Ice communicators. You can also use ice_connectionId on the server proxy to associate different connections to the same proxy:

    var server = CallbackSenderPrxHelper.checkedCast(communicator.propertyToProxy("CallbackSender.Proxy"));
    var server1 = (CallbackSenderPrx)server.ice_connectionId("con1");
    var server2 =  (CallbackSenderPrx)server.ice_connectionId("con2");
    

    Cheers,
    Benoit

Sign In or Register to comment.