Archived

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

simplifing building ICE applications

Dear Zeroc people,

I have three questions that require some context resulting on a long posting, my apologies.

I'm trying to simplify writing Ice programs by hiding most of the complexity in a class which I call 'IAS_Application' and is derived of Ice::Application. This class exposes (among others) the following four functions.

Ice::ObjectPrx registerObject(Ice::ObjectPtr object,string name);
Ice::ObjectPrx getRegisteredObject(string name);
Ice::ObjectPrx publishTopic(string topicName);
Ice::ObjectPrx subscribeToTopic(Ice::ObjectPtr object,string topicName);

With these I'm able to write both client/server and publish/subscribe programs like below (where I only show all the lines of code in the IAS_Application::run() function):


# Server
registerObject(new HelloI(communicator()),"hello1");
waitForShutdown();


# Client
HelloPrx hello = HelloPrx::checkedCast(getRegisteredObject("hello1"));
hello->sayHello();


# Subscriber
subscribeToTopic(new HelloI(),"hello2");
waitForShutdown();


# Publisher
HelloPrx hello = HelloPrx::uncheckedCast(publishTopic("hello2"));
hello->sayHello();


Ofcourse simplifying like this has the advantage that writing programs is easiers but has the disadvantage that you have less control. However, it seems very helpfull for people that quickly want to write (simple) distributed systems and don't care about the underlaying details. If you are interested I'm happy to share my code but it's pretty straightforward.

QUESTION 1: Why doesn't ICE supply a similar simplification in the distribution?



I have one problem with the approach described above. When the Subscriber receives a CTRL_C signal it should unsubscribe all subscribed objects automatically, similar to Ice-2.1.1/demo/IceStorm/clock/Subscriber.cpp. However, as I want to use the destroyOnInterrupt() in contrast to the shutdownOnInterrupt() it seems to me that I have to unsubscribe before the communicator is destroyed by the Ice::Application class. I have not yet succeeded in doing this.

QUESTION 2: How can I unsubscribe in the destroyOnInterrupt() mode before the communicator is destroyed (for example in Ice-2.1.1/demo/IceStorm/clock/Subscriber.cpp)?



I guess (and I could be wrong) the problem here is that the _ctrlCHandler of class Ice::Application has a callback to a static global function in contrast to a method of class Ice::Application that could be redefined/overloaded by any class inheriting from it. The code below shows how the callback of the IceUtil::CtrlCHandler class can be set to the cleanUp() method of the App class which can and is overloaded by class IAS_App. This would solve my problem I guess but I ran into difficulties rewritting the Ice::Application class, so before I continue I would like some expert advise to prevent wasting time.

QUESTION 3: Is there a good reason why Ice::Application doesn't provide such an overloadable cleanUp() method? If not, are you interested in such a rewrite of the Ice::Application class?



#include <Ice/Ice.h>
#include <IceUtil/CtrlCHandler.h>

using namespace std;

class App;

App *callbackObject;

void setCallbackObject(App *object)
{ callbackObject=object;}

App *getCallbackObject()
{ return callbackObject;}


class App
{
public:
App()
{
setCallbackObject(this);
IAS_ctrlCHandler.reset(new IceUtil::CtrlCHandler);
IAS_ctrlCHandler->setCallback(destroyOnInterruptCallback);
}

virtual ~App(){}

virtual void cleanUp()
{
cout<<"destroy communicator"<<endl;
}

static void destroyOnInterruptCallback(int signal)
{
getCallbackObject()->cleanUp();
}

private:
auto_ptr<IceUtil::CtrlCHandler> IAS_ctrlCHandler;
};


class IAS_App: virtual public App
{
public:

virtual ~IAS_App(){}

virtual void cleanUp()
{
cout<<"unsubscribe all objects"<<endl;
App::destroy();
}
};

int main()
{
IAS_App app;
cout<<"CTRL_C now!!"<<endl;
sleep(10);
cout<<"end"<<endl;
return 1;
}


Thank you for your time,

best regards,
Bas Terwijn