Home Help Center

how to send last message before server terminates in Ice::Application class?

Hello,

I am using the help class Ice::Application and I would like to inform the clients about the fact that server is going to terminate. It means, when I call ctrl-c to terminate my server first a message should be send to the clients and then the communicator should be destroyed. The problem is that in the run() function I should use:
communicator()-> waitForShutdown();
Well this works fine but it deletes also the communicator- so I can't send anything afterwards.
In the forum thread on : http://www.zeroc.com/vbulletin/showthread.php?t=1554
I read in the post #9 about a function
virtual bool interrupt(int sig);
. I think that is exactly what I need... the problem is just that I think this function doesn't really exists, at least I couldn't find it in the manual. Can I initialize such function on my own? I mean this function should be in the Ice::Application class. Or is it already there? ...or should I better use another method to solve this problem?

thanks a lot for your answer

ondrej

Comments

  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    waitForShutdown() does not destroy the communicator. It only waits until all object adapters are destroyed. The client side of Ice is not affected by this, i.e., you can continue to send requests after waitForShutdown().
  • mesmes CaliforniaAdministrators, ZeroC Staff Mark SpruiellOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    Also be aware that Ice::Application destroys the communicator by default on receipt of a signal, so your application should call shutdownOnInterrupt if you need to use the communicator after an interrupt occurs.

    Take care,
    - Mark
  • ondrejondrej Member
    Thanks a lot for the fast reply,

    but I can't still bring it to work. I am little confused with shutdownOnInterrupt(); because I don't know where in code I should use it- before or after communicator()-> waitForShutdown(); ? Or am I thinking in wrong way?

    Here my code:
    int MudServer::run(int argc, char * argv[]){
    
    Ice::ObjectAdapterPtr object_adapter = communicator()->createObjectAdapter("SeLinuxMudAdapter");
    
    //create servant & add servant to adapter's map of servants-> it will be done in the constructor of the object WorldI
    IceUtil::Handle<WorldI> mud_world = new WorldI("SeLinuxMud", object_adapter);
    
    object_adapter->activate();
    
    //critical part:
    
    destroyOnInterrupt();                                //lineA
    
    //the next function should send a message to clients to inform them about termination of the server
    mud_world->last_message_to_clients();    //lineB
    
    communicator()-> waitForShutdown();  //lineC
    
    return 0;
    }
    
    int main(int argc, char * argv[])
    {	
      //class MudServer : virtual public Ice::Application 
    		MudServer mud_server;
    		return mud_server.main(argc, argv);
    }
    

    When I don't use communicator()->waitForShutdown(); logically my server will not wait for clients and terminates. When I use it and put after it the code as in "lineB" I get this message by terminating the server: Instance.cpp:189: Ice::CommunicatorDestroyedException:
    communicator object destroyed . That's why I was thinking that when I use the function waitForShutdown() in Ice::Application also the communicator will be destroyed.

    When I use destroyOnInterrupt(); like in the code I wrote now, it's the same as it would be not there.

    Could be the problem that I want to use the function from the Ice Object "WorldI"? should I better give the function last_message_to_clients(); to an object that is not an Ice object?

    When I should use shutdownOnInterrupt(); How I should use it? I know what this function should do- but I don't know how to use it right. Or am I doing somewhere a trivial mistake?

    Thanks a lot for your answer and time.

    ondrej
  • ondrejondrej Member
    ooh, I tried right now another possible combination and it was working:
    shutdownOnInterrupt();
    communicator()-> waitForShutdown();
    mud_world->kill_players();
    

    OK now I think I know how it works- the functions like shutdownOnInterrupt(); or destroyOnInterrupt() I should put always before communicator()-> waitForShutdown(); to set the behaviour of the application when it receives the signal. right?

    thanks

    ondrej
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    Correct. You must use shutdownOnInterrupt() so that communicator->shutdown() is called upon interrupt. This way, waitForShutdown() will return, but your communicator will not be destroyed, and you can still invoke requests.

    With destroyOnInterrupt(), an interrupt triggers communicator->destroy(), which destroys both the client and the server side of your application. That's why you get a CommunicatorDestroyedException if you attempt to invoke any requests after the interrupt.
  • ondrejondrej Member
    does it mean also that I should destroy the communicator afterwards explicitly when it is not destroyed by calling the function shutdownOnInterrupt()?

    shutdownOnInterrupt();
    communicator()-> waitForShutdown();
    mud_world->kill_players(); //last_message_to_clients will be send
    communicator()->destroy(); //<<<<????

    I tried it with and without communicator()->destroy(); and there was no difference when I terminated the server- better said, I didn't get any exceptions. But it is better to call it? or it is not necessary?

    thanks a lot

    ondrej
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    Yes, you must destroy the communicator for a clean application termination. Otherwise resources are not cleaned up. For instance, without a call to destroy(), connections will not be closed gracefully, but abortive.
  • mesmes CaliforniaAdministrators, ZeroC Staff Mark SpruiellOrganization: ZeroC, Inc.Project: Ice Developer ZeroC Staff
    Marc is correct, in general you must always destroy the communicator instance. However, this is not necessary when you use Ice::Application because the communicator is destroyed after run() returns (but there is no harm in calling destroy on the communicator more than once).

    Take care,
    - Mark
  • bernardbernard Jupiter, FLAdministrators, ZeroC Staff Bernard NormierOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    If you don't destroy the communicator, Ice threads continue to run during static destruction which can lead to a crash of the application.

    Cheers,
    Bernard
Sign In or Register to comment.