Archived

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

Ice-E and Glacier2

Hi,
I am using Ice-E to develop an application in a TC65 modem. I try to establish a session between the application ("modem") and a Glacier2 router. This is the code:
properties.setProperty("TC65Operations.Modem.Endpoints","");
String proxy_router="Glacier2/router:tcp -p 10000 -h 138.4.9.76";
Glacier2.RouterPrx router =Glacier2.RouterPrxHelper.checkedCast(communicator.stringToProxy(proxy_router));
if(router==null)
throw new Exception("Router es null");
Management.RegisterSessionPrx sessionReg;
while(true){
try{
sessionReg =Management.RegisterSessionPrxHelper.uncheckedCast(router.createSession("1", "1"));
break;
}
catch(Exception e){
}
}


Then I create an object adapter to receive callbacks, and I regist it. The problem is that the adapter created have not endpoints associated, and I do not know why.
Ice.Identity TC65OperationsIdent=new Ice.Identity();
TC65OperationsIdent.name = "TC65operations";
TC65OperationsIdent.category = category;
Ice.ObjectAdapter adapterTC65Operations = communicator.createObjectAdapter("TC65Operations.Modem");
TC65OperationsPrx TC65OperationsProxy = TC65OperationsPrxHelper.uncheckedCast(adapterTC65Operations.add(new TC65OperationsI(manager, adapterTC65Storer, properties,getterProxies,commConn,outStream), TC65OperationsIdent));

adapterTC65Operations.activate();
sessionReg.regist(TC65OperationsProxy);

I developed the same application with Ice-3.0.0 and I had not this problem. With Ice-3.0.0 I created a configuration file with the properties:
TC65Operations.Modem.Router=Glacier2/router:tcp -p 10000 -h 138.4.9.76
TC65Operations.Modem.Endpoints=
and the adapter created had an endpoint correctly assigned.

What could be the problem?

Thanks

Comments

  • benoit
    benoit Rennes, France
    Hi,

    Did you build Ice-E with router support enabled? (ICEE_HAS_ROUTER needs to be defined in include/IceE/Config.h). Did you try the demo/IceE/chat demo to see if it works? If it works, you could check and use the demo to try to figure out what's different from your application.

    Cheers,
    Benoit.
  • Hi again, I have read in a post of fgarcia this :
    In any case, I suspect I know what the problem is. You're using thread per connection with a bidirectional connection. It's not possible to have nested callbacks with such a configuration. You shouldn't use --Ice.ThreadPerConnection for your modem application. Instead, you should use the default thread pool model and adjust the size of the client thread pool to allow nested callbacks. I recommend you to take a look at the section "30.9 The Ice Threading Models" in the manual. It explains the limitations of the different threading models and how to setup the thread pool size to allow nested callbacks.

    is it posible to use it with IceE?

    Thanks
  • marc
    marc Florida
    No, Ice-E supports thread per connection only. You cannot have callbacks with thread per connection and bi-directional connections with more than one nesting level.

    Just to avoid any confusion, this works:

    client -> server -> client

    I.e., you can have your client call the server, which calls back the client. What you cannot do is this:

    client -> server -> client -> server

    I.e., you cannot have the client call the server, then the server call back, and then the client call the server again from this callback.

    (This assumes all calls are twoway. You can get away with one additional nesting level if the last call is oneway.)
  • our case

    (Modificated)
    Hi again:

    What we do is that:

    client -> server 1 -> server 2 -> server 1 -> client

    How can we solve it?

    Thanks
  • marc
    marc Florida
    cesartovic wrote:
    Hi again:

    What we do is that:

    client -> server 1 -> server 2 -> client

    How can we solve it?

    Thanks

    There is nothing special to do, this works just fine with bi-dir and thread-per-connection.

    Update: Just saw your modification, this will work fine, too. As long as there is only one nesting level, there is no problem.
  • Sorry, a mistake in previous post

    Hi again and sorry because I have a mistake in the case:

    What we do is that:

    client -> server 1 -> server 2 -> server 1 -> client

    How can we solve it?

    Thanks
  • marc
    marc Florida
    We are both posting too fast :) See my post above, this will work fine, too.
  • Problem

    Hi again,

    We have a problem with the las case and we don`t know how can we solve it because we need the properties in IceE:
    properties.setProperty("Ice.ThreadPool.Client.Size","1");
    properties.setProperty("Ice.ThreadPool.Client.SizeMax","10");
    properties.setProperty("Ice.ThreadPool.Server.Size","1");
    properties.setProperty("Ice.ThreadPool.Server.SizeMax","10");

    My partner working with Ice needs these properties ,like benoit says to fgarcia,to work fine. I have to adapt his code to IceE Java
    and seems to have a problem when we try to retrieve a topic with this command and we think that is problem of configuration or connections:

    IceStorm.TopicPrx topico = topicManager.retrieve(topic);

    We use IceE as Server 1 in the schema:

    Client -> Server 1 -> Server 2 -> Server 1 -> Client

    Could you give us any sollution??

    Thanks a lot:)
  • marc
    marc Florida
    Oops... sorry, I was wrong with my last post:

    client -> server -> client

    This only works if the call from the server to the client is oneway, otherwise it will block. So in your example:

    client -> server1 -> server2 -> server1 -> client

    Assuming the connection from client to server1 is bi-dir and that server1 uses thread-per-connection (which is the only model supported by Ice-E), you must make the call from server1 to the client (the last call in the chain) a oneway call. Sorry for the confusion.

    The properties for the thread pool won't do anything in Ice-E, since Ice-E does not support the thread pool model.
  • The real scenario is that between client and server1 there is a Glacier2 router. The server1 establishes a session with the Glacier2 router and registes its proxy for callbacks. Then the process is:

    client -> Glacier2_rt -> server1 -> server2 -> server1 ->Glacier2_rt -> client

    How can server1 makes an oneway call to the client? If we configure this proxy as oneway, it results in an error at run time ("TwoWayOnlyException")

    Thanks
  • marc
    marc Florida
    Whether or not you use Glacier2 in between the client and server2 does not matter.

    A TwowayOnlyException means that you cannot send an operation as oneway, because the operation has a return value, out parameters, or user exceptions.

    If you must have a twoway callback because you have out parameters or return values, then I'm afraid you cannot do what you want to do, without redesigning your application so that this twoway is not required anymore.
  • marc
    marc Florida
    Actually, I still don't understand your setup. If you use Glacier2, then your connection from the client to Glacier2 is bi-dir, but not from Glacier2 to server1. So there should be no problem with nested calls if you use twoway operations.

    Perhaps it would be best if you post a small, self-contained example that demonstrates the problem (complete with configuration).
  • Ok, here is the example. I have eliminated all the useless code.
    The example is compilated with Ice-3.0.0 and only use Ice, not Ice-E, but if we achieve to do it works, the application with Ice-E will also work.
    Tha application has 5 executables files: localStorer, gestor, glacier2router, modem and emuladorDrupal. You have to execute them in this order and follow the orders of the emuladorDrupal, it is very simple.
    Now the "modem" is configured with ThreadPerConnection model because this is the model that will use the application with Ice-E. Now the properties Ice.Trace.Network and Ice.Trace.Protocol are deactivated.
    Also there are 2 scripts to execute and stop the global applications. You can run them with "bash inicio.sh" or "bash fin.sh".

    Thanks for your help.
  • marc
    marc Florida
    I'm confused... you wrote above that you have this scenario:

    client -> glacier -> server1 -> server2

    You wrote that server1 is the process using Ice-E (and thus uses thread per connection), and that server1 == modem. Is this correct?

    However, modem is a client, not a a server, since modem initiates the connection to Glacier2.

    So before I dig deeper into your example, can you clarify the calling sequence?
  • marc
    marc Florida
    Regardless of the client/server confusion, the problem is this code:
    allNotifications
    TC65OperationsI::getNotificationTC65ByDate(const string & topic, const string & end, const string & begin, const Ice::Current&)
    {
      allNotifications tmpNoti;
      
      cout << "!!!!!getterProxies[incidencias]: " << _adapterTC65->getCommunicator()->proxyToString(_getter) << endl;
      cout << "!!!!!Before getNotificationByDate" << endl;
      
      tmpNoti = _getter->getNotificationByDate(end,begin);
    
      cout << "!!!!!Pasado el getNotificationByDate" << endl;
    
      return tmpNoti;
    }
    

    You are making a twoway call from a callback. This is not possible with thread-per-connection and bi-directional connections. You must redesign your application so that it does not rely on having to make a twoway call in this callback.
  • Ok, the real scenario and the calling sequence are:

    emuladorDrupal -> gestor -> glacier2 -> modem -> localStorer
    >

    emuladorDrupal <- gestor <- glacier2 <- modem <- localStorer <

    The modem creates a session with glacier2 router, and is the application that will use Ice-E.
    The "emuladorDrupal" is only an application to interact with the user.

    Thanks
  • marc
    marc Florida
    fgarcia wrote:
    Ok, the real scenario and the calling sequence are:

    emuladorDrupal -> gestor -> glacier2 -> modem -> localStorer
    >

    emuladorDrupal <- gestor <- glacier2 <- modem <- localStorer <

    The modem creates a session with glacier2 router, and is the application that will use Ice-E.
    The "emuladorDrupal" is only an application to interact with the user.

    Thanks

    As it is configured, the modem would not call localStorer directly, but would call it using glacier2, so the scenario would be:

    emuladorDrupal -> gestor -> glacier2 -> modem -> glacier2 -> localStorer

    If it would call localStorer directly, then there would be no problem with the twoway call, because there would be a separate connection between modem and localStorer.
  • New problem

    Hi again,
    now, I am trying to develop a simple application in IceE with java instead of c++ (as previously I did), and I have some problems.
    The applications is very simple, it is only a subscriber-publisher with a glacier2 router. I configure the subscriber to uses the glacier2 router:
    ...
    communicator = Ice.Util.initialize(new String[0]);
    String proxyRouter = "DemoGlacier2/router:tcp -p 10000"
    router = Glacier.RouterPrxHelper.checkedCast(communicator.stringToProxy(proxyRouter));
    if(router != null){
    communicator.setDefaultRouter(router);
    properties = communicator.getProperties();
    properties.setProperty("Monitor.Subscriber.Router", proxyRouter);
    properties.setProperty("Monitor.Subscriber.Endpoints", "");

    router.createSession("1", "1");
    }

    Ice.ObjectPrx obj = communicator.stringToProxy("DemoIceStorm/TopicManager:tcp -p 10005");
    IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj);
    ...
    ...

    I have not problems compiling it, but when I run it, I get an Ice.ConnectionLostException

    Do you know what is the problem?

    I have a similar subscriber developed in C++ with Ice (not IceE), and I have not problems with it, and it connects to the same glacier2 router, iceStorm service, and publisher.

    Thanks in advance
  • One thing about the previous problem,
    I have commented the line
    communicator.setDefaultRouter(router);
    I do not get errors in the compilation, and the execution seems to be all right; it does not throw exceptions, the subscription is correct, etc; but when the publisher publish some information, it does not reach the subscriber, I explain myself.
    Following the traces (Ice.Trace.Network and Ice.Trace.Protocol), I can see that the publisher sends the information to the icestorm service, it forwards the operation to the glacier2 router with the correct identity of the subscriber, and finally the router forwards it to the subscriber:
    [ glacier2router: Protocol: sendeing batch request
    ...
    ...
    identity = ^NdY0vPhG7TSh\'X,4O0a/7f:0:0:1:305c8d6a-fe3b-488e-ac89-f4c0d888d308
    facet=
    operation = sendInfo
    ...
    context = _fwd/Oz ]

    I am running the subscriber in the emulator of the wireless toolkit, and the emulator`s light shines eache time the publisher publishes anything, but the subscriber does not anything. And it only has to show a text message on the terminal, show.

    I hope this information helps to solve the problems

    Thanks again
  • To get more details, you should:
    • Switch on connection tracing in the client, i.e., Ice.Trace.Network=2
    • Enable various Glacier2 trace settings, i.e., Glacier2.Client.Trace.Reject, Glacier2.Trace.Session.
  • I have yet setted these propeties, and I have posted the interesting information. Let me known, if you need any other detail.

    Thanks
  • You must post much more detailed log information. For example, the part of the log where the connection from the client is closed, and the corresponding part where it is opened. I'm afraid with the information your provide, it's impossible to tell what the problem is.
  • Ok,
    this is the information generated by the glacier2router refered to when the client is opened, and when it is closed:
    [[ glacier2router: Network: accepted tcp connection
    local address = 127.0.0.1:10000
    remote address = 127.0.0.1:57610 ]
    ...
    [ glacier2router: Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 74
    request id = 1
    identity = DemoGlacier2/router
    facet =
    operation = ice_isA
    mode = 1 (nonmutating)
    context = ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 26
    request id = 1
    reply status = 0 (ok) ]
    [ glacier2router: Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 65
    request id = 2
    identity = DemoGlacier2/router
    facet =
    operation = createSession
    mode = 0 (normal)
    context = ]
    [ glacier2router: Protocol: sending request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 58
    request id = 3
    identity = verifier
    facet =
    operation = checkPermissions
    mode = 1 (nonmutating)
    context = ]
    [ glacier2router: Protocol: received reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 27
    request id = 3
    reply status = 0 (ok) ]
    [ glacier2router: Protocol: sending request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 54
    request id = 4
    identity = sessionmanager
    facet =
    operation = create
    mode = 0 (normal)
    context = ]
    [ glacier2router: Protocol: received reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 96
    request id = 4
    reply status = 0 (ok) ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 96
    request id = 2
    reply status = 0 (ok) ]
    [ glacier2router: Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 62
    request id = 3
    identity = DemoGlacier2/router
    facet =
    operation = getClientProxy
    mode = 1 (nonmutating)
    context = ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 65
    request id = 3
    reply status = 0 (ok) ]
    [ glacier2router: Network: accepted tcp connection
    local address = 192.168.1.3:10000
    remote address = 192.168.1.3:59064 ]
    [ glacier2router: Protocol: sending validate connection
    message type = 3 (validate connection)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 14 ]
    [ glacier2router: Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 109
    request id = 4
    identity = DemoGlacier2/router
    facet =
    operation = addProxy
    mode = 2 (idempotent)
    context = ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 25
    request id = 4
    reply status = 0 (ok) ]
    [ glacier2router: Protocol: received request
    message type = 0 (request)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 86
    request id = 1
    identity = DemoIceStorm/TopicManager
    facet =
    operation = ice_isA
    mode = 1 (nonmutating)
    context = ]
    [ glacier2router: Glacier2: rejecting request. no session is associated with the connection.
    identity: DemoIceStorm/TopicManager ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 54
    request id = 1
    reply status = 2 (object not exist)
    identity = DemoIceStorm/TopicManager
    facet =
    operation = ice_isA ]

    request id = 1
    identity = DemoIceStorm/TopicManager
    facet =
    operation = ice_isA
    mode = 1 (nonmutating)
    context = ]
    [ glacier2router: Glacier2: rejecting request. no session is associated with the connection.
    identity: DemoIceStorm/TopicManager ]
    [ glacier2router: Protocol: sending reply
    message type = 2 (reply)
    compression status = 0 (not compressed; do not compress response, if any)
    message size = 54
    request id = 1
    reply status = 2 (object not exist)
    identity = DemoIceStorm/TopicManager
    facet =
    operation = ice_isA ]
    [ glacier2router: Network: closing tcp connection
    local address = 192.168.1.3:10000
    remote address = 192.168.1.3:59065 ]
    ...

    I don't know how to get the traces of the client because it is implemented with IceEJ and the wireless toolkit

    Thanks
  • Your client opens two connections:

    [ glacier2router: Network: accepted tcp connection
    local address = 127.0.0.1:10000
    remote address = 127.0.0.1:57610 ]

    and:

    [ glacier2router: Network: accepted tcp connection
    local address = 192.168.1.3:10000
    remote address = 192.168.1.3:59064 ]

    One of the two connections has no associated session. I believe this is the reason for the failure. If you open two connections on purpose, then you must create a session for both of them. If you do not do this on purpose, then you must find out why and where a second connection is opened in your client.
  • I see what you say, but I don't know how it is possible because I only open one connection (at least on purpose). Could you say where the other commention is opened? Here is the code:
    ...
    communicator = Ice.Util.initialize(new String[0]);
    router = Glacier2.RouterPrxHelper.checkedCast(communicator.stringToProxy(proxyRouter));
    if(router != null)
    {
    communicator.setDefaultRouter(router);

    properties = communicator.getProperties();
    properties.setProperty("Ice.ACM.Client","0");
    properties.setProperty("Ice.ACM.Server","0");
    properties.setProperty("Ice.MonitorConnections","60");
    properties.setProperty("Ice.RetryIntervals","-1");

    try
    {
    router.createSession("1","1");
    }
    catch (Exception e)
    {
    System.out.println("Permission deinied: " + e);
    }
    }

    else
    {
    System.err.println("There isn't router");
    }

    listTopicPrx = new IceStorm.TopicPrx[3];

    Ice.ObjectPrx obj = communicator.stringToProxy("DemoIceStorm/TopicManager:tcp -p 10005");
    IceStorm.TopicManagerPrx topicManager = IceStorm.TopicManagerPrxHelper.checkedCast(obj);
    ...

    Thanks
  • From the code it's impossible to tell. One common problem is that different timeouts are used, in which case a new connection for each timeout is established (because timeouts are per connection, not per call).

    This would be much easier to debug if you could run the client in an emulator and get the tracing information from the client. Then you can see when the client opens new connections (with both Ice.Trace.Network=2 and Ice.Trace.Protocol=1). I'm afraid without such traces, I cannot provide much assistance.
  • dwayne
    dwayne St. John's, Newfoundland
    I would suggest is that you make sure you explicitly set the -h parameter in your endpoint and proxy configuration. Your problem might be cause by the fact that without a -h parameter present Ice will listen on all local interfaces.

    Regards,
    Dwayne
  • That was the problem!!!
    I have set explicitly the -h parameter and it works.

    Thank you very much for all your help