Archived

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

Simple server notification of client

We are trying to use Ice to implement a simple application server.
The "application" can be an entity started in its own
process by a server or an object instantiated by a server.
The client only needs to send start and stop requests to servers
and receive status messages that indicate a servant has terminated
abnormally -- e.g. dumped core. (Note we are talking servant here,
not server). Thus, the amount of messages being passed between
Ice clients and servers in this environment as very small.

The crux of the problem is how to implement "server" notification
of "clients" of servant abnormal termination in the simplest
(and possibly not most efficient) way

After talking with Benoit, we surmised that IcePack is not an option for monitoring because:
1) we need to monitor servants, not servers.
2) it is not implemented on Windows 2K ( we
will be running Ice in a heteogenious Unix and PC environment).

We've found and read two forum articles that address similar
issues. One is titled "Notification Service" and the other
"Server Communication with client without clien's request".
One suggests using IceStorm, the other Glacier. Both these
Ice component solutions seem way overkill for what we require.
For example, firewalls are not an issue for us.

We've been reading about AMI and AMD in Chapter 17
of the manual and was wondering if that would be an option.
For example, here is a series of steps that we might use
with AMI/AMD:

1) the client would send an asynchronous request
to a server to start status checking. Included in this request
would be a callback specification that the server could use
to notify the client of an abnormal termination.
2) The server would receive the request and instantiate
an object ( in Java, a TimerTask )
that pinged the servant every 30 seconds. The TimerTask
object would hold the callback object as member data.
3) If a "ping" was not sucessful, the TimerTask would simply
call the callback method that would indicate a bad termination
to the client.

If no abnormal terminations occur, the client never receives
a callback invocation.

So, the bottom line is:


1) Would AMI/AMD be a recommended way to solve this
problem in the simplest way? If not, what would?
2) If so, does the above proposed solution sound reasonable.

Thanks,

Brian

Comments

  • Re: Simple server notification of client
    Originally posted by brian
    We are trying to use Ice to implement a simple application server.
    The "application" can be an entity started in its own
    process by a server or an object instantiated by a server.
    The client only needs to send start and stop requests to servers
    and receive status messages that indicate a servant has terminated
    abnormally -- e.g. dumped core. (Note we are talking servant here,
    not server). Thus, the amount of messages being passed between
    Ice clients and servers in this environment as very small.

    The crux of the problem is how to implement "server" notification
    of "clients" of servant abnormal termination in the simplest
    (and possibly not most efficient) way

    If the application is a process that is started by the Ice server, the best way to monitor it would be to fork the application from the server and to have the server monitor SIGCHLD (probably in a separate thread for each started application). You could call sigwait() to do this.

    If the application is a servant inside the server, there is nothing you can do if the servant dumps core because, in that case, it will take the entire server process with it, of course.

    So, given the first scenario, have the server monitor the status of the processes it starts and, when a process dies, send a message to the client via a callback object that the client passes when it initially requests the application to be started. This seems the easiest way to deal with the issue, and neither AMI nor AMD are required.

    1) the client would send an asynchronous request
    to a server to start status checking. Included in this request
    would be a callback specification that the server could use
    to notify the client of an abnormal termination.

    No need for AMI or AMD here. You can use a twoway message just as easily to do this.
    2) The server would receive the request and instantiate
    an object ( in Java, a TimerTask )
    that pinged the servant every 30 seconds. The TimerTask
    object would hold the callback object as member data.
    3) If a "ping" was not sucessful, the TimerTask would simply
    call the callback method that would indicate a bad termination
    to the client.

    I don't see how this could work. If the servant terminates abnormally (and it really is a servant, not a separate process), it will terminate the entire server, so there is no way to send a status message back in this case.

    If by "abnormal termination", you mean termination with an exception that the server can catch, then you can go back to the initial scenario: just send a message when something goes wrong.

    Unless you otherwise have a need to send status updates periodically, I would do away with this because it's more work and more complex. (But, of course, your requirements may dictate doing this.)

    1) Would AMI/AMD be a recommended way to solve this
    problem in the simplest way? If not, what would?
    2) If so, does the above proposed solution sound reasonable.

    See above. I don't see a compelling need for AMD/AMI here. (That's not to say that you can't use them though.)

    Cheers,

    Michi.
  • First of all, thanks the the thoughtful response, Michi.
    If the application is a process that is started by the Ice server, the best way to monitor it would be to fork the application from the server and to have the server monitor SIGCHLD (probably in a separate thread for each started application). You could call sigwait() to do this.

    We are using both Windows and Unix platforms, C++ and Java.
    Is this solution both platform and language-independent? ( I
    noticed that the signal handling section in 15.11 only referred
    to C++) If so, is there doc in the manual about it. If not,
    any other suggestions. We could handle two different platform
    OR language solutions, but four covering each case would
    be highly undesirable.

    If the application is a servant inside the server, there is nothing you can do if the servant dumps core because, in that case, it will take the entire server process with it, of course.

    But what if the server starts each servant in a different thread?
    I forget, in that case, would the entire process still go down?
    Is that answer to this question platform and/or language specific?

    I suppose we could not create servants, per se, and start
    all of our services as separate processes...
    So, given the first scenario, have the server monitor the status of the processes it starts and, when a process dies, send a message to the client via a callback object that the client passes when it initially requests the application to be started. This seems the easiest way to deal with the issue, and neither AMI nor AMD are required.

    No need for AMI or AMD here. You can use a twoway message just as easily to do this.

    After reading one of those articles I mentioned in my first email,
    I gathered there was some restriction on sending messages back
    to the client since the moderator suggested using Glacier to
    get around the restriction. But if we don't have firewall issues, we
    can use client callbacks without AMI or AMD?

    2) The server would receive the request and instantiate
    an object ( in Java, a TimerTask )
    that pinged the servant every 30 seconds. The TimerTask
    object would hold the callback object as member data.
    3) If a "ping" was not sucessful, the TimerTask would simply
    call the callback method that would indicate a bad termination
    to the client.
    I don't see how this could work. If the servant terminates abnormally (and it really is a servant, not a separate process), it will terminate the entire server, so there is no way to send a status message back in this case.

    Understood. If we can't use IcePack to monitor a server (because
    it is not implemented on Windows yet), how could we notify
    our client if a server (as opposed to a servant) goes down?

    Thanks again,

    Brian
  • Originally posted by brian
    First of all, thanks the the thoughtful response, Michi.



    We are using both Windows and Unix platforms, C++ and Java.
    Is this solution both platform and language-independent? ( I
    noticed that the signal handling section in 15.11 only referred
    to C++) If so, is there doc in the manual about it. If not,
    any other suggestions. We could handle two different platform
    OR language solutions, but four covering each case would
    be highly undesirable.

    No, process monitoring is never platform-independent. The mechanisms you have to use to detect process death differ for UNIX and Windows. But you only need to do this on the server side, so there are only two solutions, not four.

    Signal handling is implemented in Ice::Application for both C++ and Java. However, that mechanism won't help in your case because you need to catch fatal stuff, such as segmentation faults.
    But what if the server starts each servant in a different thread?
    I forget, in that case, would the entire process still go down?
    Is that answer to this question platform and/or language specific?

    I suppose we could not create servants, per se, and start
    all of our services as separate processes...

    It doesn't matter whether the server is threaded -- if a servant does something illegal, such as an out-of-bounds memory access, the entire process is aborted.

    If you really need to deal with such situtations, I see no option but to start each application as a separate process and to monitor the status of that process from the "real" Ice server.
    After reading one of those articles I mentioned in my first email,
    I gathered there was some restriction on sending messages back
    to the client since the moderator suggested using Glacier to
    get around the restriction. But if we don't have firewall issues, we
    can use client callbacks without AMI or AMD?

    Sure. Callbacks are independent of AMI and/or AMD. AMI and AMD only influence how the client interacts with a twoway invocation (synchronously or asynchronously) and with how a server process an incoming invocation.
    In essence, AMI allows you to make a twoway synchronous call asynchronously in the client, and AMD allows you to process an incoming call asynchronously.

    AMI is useful, in particular, if you have a synchronous blocking call (probably a long-running call as well) and you want to make an invocation of that call without blocking in the client until the call is finished. AMD is useful mainly if you have operations in which clients must block for an extendent period of time, but you cannot afford to devote a processing thread to each blocked client.

    You can get the effect of AMI by using twoway invocations but designing the interface to your objects such that an operation invocation is split into an "invoke" call and a "completed" callback. Have a look at the beginning of the AMI documentation for an example.
    Understood. If we can't use IcePack to monitor a server (because
    it is not implemented on Windows yet), how could we notify
    our client if a server (as opposed to a servant) goes down?

    When the client initially asks the server to start an application, have the client supply a callback object to the server that the server later calls back on to inform the client of progress and the eventual outcome of the application.

    Cheers,

    Michi.
  • So, given the first scenario, have the server monitor the status of the processes it starts and, when a process dies, send a message to the client via a callback object that the client passes when it initially requests the application to be started. This seems the easiest way to deal with the issue, and neither AMI nor AMD are required.

    I've been trying to do this, but isn't the implication that
    the client must also become a server and other bad things
    pointed out in chapter 17.3.1? And isn't that why using AMI is recommended?

    I tried using the ICallback method they describe in
    that section, but that requires the client to be a server, correct?

    If I am missing something a simple example either here
    or in the demos would be great.

    Thanks again,

    Brian
  • Originally posted by brian
    I've been trying to do this, but isn't the implication that
    the client must also become a server and other bad things
    pointed out in chapter 17.3.1? And isn't that why using AMI is recommended?

    AMI is useful if you have an existing interface that is written for twoway invocations, but you want to invoke asynchronously.

    For an interface that is inherently designed to be driven asynchronously (and cannot work synchronously), you don't have to use AMI -- as a matter of style, I would probably argue that, in such a case, it would be preferable to express the asynchronous nature of the interaction using normal twoway invocations, that is, make the asynchronous nature explicit in the Slice definitions.
    I tried using the ICallback method they describe in
    that section, but that requires the client to be a server, correct?

    Whenever a server wants to call back to a client, the client also has to be a server. That's in the nature of the beast because, for callbacks, client and server roles have to be reversed. Note that, to make a client a server, you don't really have to do anything special. Just register a servant for the callback object as usual and the Ice run time does the rest. In particular, for a client to act as a server, you don't need to explicitly run a dispatch loop in a separate thread.
    If I am missing something a simple example either here
    or in the demos would be great.

    The callback demo in the distribution provides an example of callbacks. Is that what you are after?

    Cheers,

    Michi.
  • The callback demo in the distribution provides an example of callbacks. Is that what you are after?

    I actually figured it out on my own before I knew this
    demo existed.

    Thanks for your patience in explaining your view to me.
    I now think I have it working...

    Thanks,

    Brian