Archived

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

Are client invocations dispatched in the calling thread?

Hi zeroc, Are client invocations dispatched in the calling thread or by the ICE client runtime threads? Our application, HP Remote Graphics, sends mouse and keyboard events, as well as many other commands. If the network experiences a disruption, simulated by pulling a cable, then the main thread which the GUI is running in can hang until the network timeout is exceeded, in which case the application disconnects, or the network recovers, whichever occurs first.

RGS uses Qt which has a main event processing thread and mouse and keyboard commands are dispatched from. I would like to remove this lock-up in the application and be able to keep the application responsive. For example, minimally supply a disconnect button. If the ICE client invocations are dispatched in the calling thread, in this case main thread, I can think of several ways to do this involving building a dispatch layer on top of Ice, but I would prefer to not have to do this.

Is my understanding of Ice correct and is there any direct support in Ice for resolving this sort of scenario?

Regards --Roland

Comments

  • xdm
    xdm La Coruña, Spain
    Hi rhochmuth

    you must use other thread in your Qt app to make ice invocations, use the ui thread for this is a bad practice, main thread in Qt app must be only use for Ui draw operations.

    if you search for qt in zeroc forums you can get others replays about this topic
  • matthew
    matthew NL, Canada
    As XDM says you should not make RPCs from the main thread. If your Qt application also receives callbacks then you must also be careful not to make invocations on most Qt widgets from the callback threads. In general you should post an event to the Qt message queue which is then processed by your widget.

    I will write articles about Qt integration in the March & April newsletters.
  • With respect to receiving callback we do not do any Qt GUI operations from a non GUI thread. All incoming callbacks received that result in Qt gui ops are posted to the main event loop. My question is directed at client side outgoing invocations.

    It is perfectly acceptable to make outgoing client invocations from the Qt main event loop. There are no issues or Qt rules which prevent this. I beleive that every GUI application in the world would have the same issue that we see with Qt. For example, if I wrote a win32 application that had a button on it called sendMessage() and this button invoked an Ice command and you pulled the cable the application would hang until the timeout is exceeded. You don't need a sophisticated gui to do this, just try the Ice hello world console example and pull the cable with a timeout set. It will hang too. Right?

    In my program I use AMI to prevent waiting on any twoway invocations. All other invocations are oneway. If the network experiences a problem, then the oneway invocation can potentially hang for up to tiemout msecs.

    Nontheless, it sounds like I need to build a dispatch layer on top of Ice if I'm interested in preventing the potential application hangs when an Ice invocation is invoked. In other words, Ice invocations are marshalled and dispatched in the calling thread. Is that statement correct?

    Regards --Roland
  • rhochmuth wrote:
    Nontheless, it sounds like I need to build a dispatch layer on top of Ice if I'm interested in preventing the potential application hangs when an Ice invocation is invoked. In other words, Ice invocations are marshalled and dispatched in the calling thread. Is that statement correct?

    Yes, this statement is correct, even for oneways or AMI operations. In theory, Ice could internally use a special sender thread or thread pool, but this would add a lot of extra latency and general overhead to every call.

    You can get around this problem by writing a request queue: Instead of calling directly, you insert an object that represents a request into this request queue. The request queue is an active object, and will then use its own thread to send the requests in its queue. Glacier2 uses such a requests queue (in buffered mode), and the article Matthew will write for the March issue of Connections will also have an example.

    Another solution is to simply rely on timeouts. If you know that something is wrong with your server if it doen't respond within 100ms, and if it is ok for your GUI to block for 100ms, then simply set a 100ms timeout and call directly from the GUI thread. For most LAN applications, this is a perfectly acceptable design tradeoff.
  • Hi Marc, Thanks. I'll look into building a dispatch queue and look forward to the article from Matthew.

    Regards --Roland