summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2006-11-29 17:16:57 +0000
committerDwayne Boone <dwayne@zeroc.com>2006-11-29 17:16:57 +0000
commit71c26812ce4fa55801b23b8a9101f0dd83f3cccd (patch)
tree7bdc27a8bad01a30e64c4d74cee98aa8352f4eca /cpp
parentAdded start/stop of IceBox service (diff)
downloadice-71c26812ce4fa55801b23b8a9101f0dd83f3cccd.tar.bz2
ice-71c26812ce4fa55801b23b8a9101f0dd83f3cccd.tar.xz
ice-71c26812ce4fa55801b23b8a9101f0dd83f3cccd.zip
Added stop/start service to IceBox admin
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES3
-rw-r--r--cpp/demo/IceBox/hello/HelloServiceI.cpp1
-rw-r--r--cpp/slice/IceBox/IceBox.ice48
-rw-r--r--cpp/src/IceBox/Admin.cpp45
-rw-r--r--cpp/src/IceBox/ServiceManagerI.cpp119
-rw-r--r--cpp/src/IceBox/ServiceManagerI.h6
6 files changed, 208 insertions, 14 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 7c9b3e55504..552254721fc 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,6 +1,9 @@
Changes since version 3.1.1
---------------------------
+- It is now possible to start and stop individual IceBox services
+ using the IceBox admin utility.
+
- Added Communicator::propertyToProxy() which creates a proxy from
a set of properties. This function allows you to set various local
proxy settings, such as the Locator cache timeout, which cannot be
diff --git a/cpp/demo/IceBox/hello/HelloServiceI.cpp b/cpp/demo/IceBox/hello/HelloServiceI.cpp
index 170c8ea737e..af0408d3bcd 100644
--- a/cpp/demo/IceBox/hello/HelloServiceI.cpp
+++ b/cpp/demo/IceBox/hello/HelloServiceI.cpp
@@ -47,4 +47,5 @@ void
HelloServiceI::stop()
{
_adapter->deactivate();
+ _adapter->waitForDeactivate();
}
diff --git a/cpp/slice/IceBox/IceBox.ice b/cpp/slice/IceBox/IceBox.ice
index 3be9a85a175..e94ff441be6 100644
--- a/cpp/slice/IceBox/IceBox.ice
+++ b/cpp/slice/IceBox/IceBox.ice
@@ -43,6 +43,34 @@ local exception FailureException
string reason;
};
+
+/**
+ *
+ * Thrown is service is already started.
+ *
+ **/
+exception AlreadyStartedException
+{
+};
+
+/**
+ *
+ * Thrown is service is already stopped.
+ *
+ **/
+exception AlreadyStoppedException
+{
+};
+
+/**
+ *
+ * Thrown if service does not exist
+ *
+ **/
+exception NoSuchServiceException
+{
+};
+
/**
*
* An application service managed by a [ServiceManager].
@@ -101,6 +129,26 @@ interface ServiceManager
/**
*
+ * Start an individual service.
+ *
+ * @param service The service name.
+ *
+ **/
+ void startService(string service)
+ throws AlreadyStartedException, NoSuchServiceException;
+
+ /**
+ *
+ * Stop an individual service.
+ *
+ * @param service The service name.
+ *
+ **/
+ void stopService(string service)
+ throws AlreadyStoppedException, NoSuchServiceException;
+
+ /**
+ *
* Shutdown all services. This will cause [Service::stop] to be
* invoked on all configured services.
*
diff --git a/cpp/src/IceBox/Admin.cpp b/cpp/src/IceBox/Admin.cpp
index 0ecc1024fca..ce9855b64d3 100644
--- a/cpp/src/IceBox/Admin.cpp
+++ b/cpp/src/IceBox/Admin.cpp
@@ -42,6 +42,8 @@ Client::usage()
"-v, --version Display the Ice version.\n"
"\n"
"Commands:\n"
+ "start SERVICE Start a service.\n"
+ "stop SERVICE Stop a service.\n"
"shutdown Shutdown the server.\n"
;
}
@@ -134,6 +136,7 @@ Client::run(int argc, char* argv[])
}
}
+
vector<string>::const_iterator r;
for(r = commands.begin(); r != commands.end(); ++r)
{
@@ -141,6 +144,48 @@ Client::run(int argc, char* argv[])
{
manager->shutdown();
}
+ else if((*r) == "start")
+ {
+ if(++r == commands.end())
+ {
+ cerr << appName() << ": no service name specified." << endl;
+ return EXIT_FAILURE;
+ }
+
+ try
+ {
+ manager->startService(*r);
+ }
+ catch(const IceBox::NoSuchServiceException&)
+ {
+ cerr << appName() << ": unknown service `" << *r << "'" << endl;
+ }
+ catch(const IceBox::AlreadyStartedException&)
+ {
+ cerr << appName() << ": service already started." << endl;
+ }
+ }
+ else if((*r) == "stop")
+ {
+ if(++r == commands.end())
+ {
+ cerr << appName() << ": no service name specified." << endl;
+ return EXIT_FAILURE;
+ }
+
+ try
+ {
+ manager->stopService(*r);
+ }
+ catch(const IceBox::NoSuchServiceException&)
+ {
+ cerr << appName() << ": unknown service `" << *r << "'" << endl;
+ }
+ catch(const IceBox::AlreadyStoppedException&)
+ {
+ cerr << appName() << ": service already stopped." << endl;
+ }
+ }
else
{
cerr << appName() << ": unknown command `" << *r << "'" << endl;
diff --git a/cpp/src/IceBox/ServiceManagerI.cpp b/cpp/src/IceBox/ServiceManagerI.cpp
index fb656a71cec..6abe43fd097 100644
--- a/cpp/src/IceBox/ServiceManagerI.cpp
+++ b/cpp/src/IceBox/ServiceManagerI.cpp
@@ -42,7 +42,95 @@ IceBox::ServiceManagerI::getSliceChecksums(const Current&) const
}
void
-IceBox::ServiceManagerI::shutdown(const Current& current)
+IceBox::ServiceManagerI::startService(const string& name, const Current&)
+{
+ IceUtil::Mutex::Lock lock(*this);
+
+ //
+ // Search would be more efficient if services were contained in
+ // a map, but order is required for shutdown.
+ //
+ vector<ServiceInfo>::iterator p;
+ for(p = _services.begin(); p != _services.end(); ++p)
+ {
+ ServiceInfo& info = *p;
+ if(info.name == name)
+ {
+ if(info.active)
+ {
+ throw AlreadyStartedException();
+ }
+
+ try
+ {
+ info.service->start(name, info.communicator == 0 ? _communicator : info.communicator, info.args);
+ info.active = true;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Warning out(_logger);
+ out << "ServiceManager: exception in start for service " << info.name << ":\n";
+ out << ex;
+ }
+ catch(...)
+ {
+ Warning out(_logger);
+ out << "ServiceManager: unknown exception in start for service " << info.name;
+ }
+
+ return;
+ }
+ }
+
+ throw NoSuchServiceException();
+}
+
+void
+IceBox::ServiceManagerI::stopService(const string& name, const Current&)
+{
+ IceUtil::Mutex::Lock lock(*this);
+
+ //
+ // Search would be more efficient if services were contained in
+ // a map, but order is required for shutdown.
+ //
+ vector<ServiceInfo>::iterator p;
+ for(p = _services.begin(); p != _services.end(); ++p)
+ {
+ ServiceInfo& info = *p;
+ if(info.name == name)
+ {
+ if(!info.active)
+ {
+ throw AlreadyStoppedException();
+ }
+
+ try
+ {
+ info.service->stop();
+ info.active = false;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Warning out(_logger);
+ out << "ServiceManager: exception in stop for service " << info.name << ":\n";
+ out << ex;
+ }
+ catch(...)
+ {
+ Warning out(_logger);
+ out << "ServiceManager: unknown exception in stop for service " << info.name;
+ }
+
+ return;
+ }
+ }
+
+ throw NoSuchServiceException();
+}
+
+void
+IceBox::ServiceManagerI::shutdown(const Current&)
{
_communicator->shutdown();
}
@@ -208,6 +296,8 @@ IceBox::ServiceManagerI::load(const string& name, const string& value)
void
IceBox::ServiceManagerI::start(const string& service, const string& entryPoint, const StringSeq& args)
{
+ IceUtil::Mutex::Lock lock(*this);
+
//
// Create the service property set from the service arguments and
// the server arguments. The service property set will be used to
@@ -215,17 +305,18 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
// communicator, depending on the value of the
// IceBox.UseSharedCommunicator property.
//
- StringSeq serviceArgs;
+ ServiceInfo info;
+ info.name = service;
StringSeq::size_type j;
for(j = 0; j < args.size(); j++)
{
- serviceArgs.push_back(args[j]);
+ info.args.push_back(args[j]);
}
for(j = 0; j < _argv.size(); j++)
{
if(_argv[j].find("--" + service + ".") == 0)
{
- serviceArgs.push_back(_argv[j]);
+ info.args.push_back(_argv[j]);
}
}
@@ -250,8 +341,6 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
// Invoke the factory function.
//
SERVICE_FACTORY factory = (SERVICE_FACTORY)sym;
- ServiceInfo info;
- info.name = service;
try
{
info.service = factory(_communicator);
@@ -285,7 +374,7 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
if(properties->getPropertyAsInt("IceBox.UseSharedCommunicator." + service) > 0)
{
- PropertiesPtr serviceProperties = createProperties(serviceArgs, properties);
+ PropertiesPtr serviceProperties = createProperties(info.args, properties);
//
// Erase properties in 'properties'
@@ -308,12 +397,12 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
// Parse <service>.* command line options
// (the Ice command line options were parse by the createProperties above)
//
- serviceArgs = properties->parseCommandLineOptions(service, serviceArgs);
+ info.args = properties->parseCommandLineOptions(service, info.args);
}
else
{
string name = properties->getProperty("Ice.ProgramName");
- PropertiesPtr serviceProperties = createProperties(serviceArgs, properties);
+ PropertiesPtr serviceProperties = createProperties(info.args, properties);
if(name == serviceProperties->getProperty("Ice.ProgramName"))
{
@@ -333,17 +422,17 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
// Parse <service>.* command line options
// (the Ice command line options were parsed by the createProperties above)
//
- serviceArgs = serviceProperties->parseCommandLineOptions(service, serviceArgs);
+ info.args = serviceProperties->parseCommandLineOptions(service, info.args);
//
// Remaining command line options are passed to the
// communicator with argc/argv. This is necessary for Ice
// plugin properties (e.g.: IceSSL).
//
- int argc = static_cast<int>(serviceArgs.size());
+ int argc = static_cast<int>(info.args.size());
char** argv = new char*[argc + 1];
int i = 0;
- for(Ice::StringSeq::const_iterator p = serviceArgs.begin(); p != serviceArgs.end(); ++p, ++i)
+ for(Ice::StringSeq::const_iterator p = info.args.begin(); p != info.args.end(); ++p, ++i)
{
argv[i] = strdup(p->c_str());
}
@@ -367,7 +456,8 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
//
try
{
- info.service->start(service, communicator, serviceArgs);
+ info.service->start(service, communicator, info.args);
+ info.active = true;
}
catch(...)
{
@@ -429,6 +519,8 @@ IceBox::ServiceManagerI::start(const string& service, const string& entryPoint,
void
IceBox::ServiceManagerI::stopAll()
{
+ IceUtil::Mutex::Lock lock(*this);
+
//
// Services are stopped in the reverse order from which they are started.
//
@@ -444,6 +536,7 @@ IceBox::ServiceManagerI::stopAll()
try
{
info.service->stop();
+ info.active = false;
}
catch(const Ice::Exception& ex)
{
diff --git a/cpp/src/IceBox/ServiceManagerI.h b/cpp/src/IceBox/ServiceManagerI.h
index 9f820374d7e..c1d65648889 100644
--- a/cpp/src/IceBox/ServiceManagerI.h
+++ b/cpp/src/IceBox/ServiceManagerI.h
@@ -19,7 +19,7 @@
namespace IceBox
{
-class ServiceManagerI : public ServiceManager
+class ServiceManagerI : public ServiceManager, public IceUtil::Mutex
{
public:
@@ -28,6 +28,8 @@ public:
virtual Ice::SliceChecksumDict getSliceChecksums(const Ice::Current&) const;
+ virtual void startService(const std::string&, const ::Ice::Current&);
+ virtual void stopService(const std::string&, const ::Ice::Current&);
virtual void shutdown(const ::Ice::Current&);
int run();
@@ -39,6 +41,8 @@ public:
::IceInternal::DynamicLibraryPtr library;
::Ice::CommunicatorPtr communicator;
::std::string envName;
+ bool active;
+ Ice::StringSeq args;
};
bool start();