Archived

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

Question on proper way to signal problem in IceBox start

Hi,

what is the proper way to signal an initialization problem on IceBox::Service::start? Checked the manual but couldn't really find any answers in there. According to the source code in case of an exception there will be a log message (and in case of an Ice::Exception the content of the exception will be logged as well).

Is there any specific exception that you recommend to throw in such a scenario (in case of my example this is a missing property required when configuring the IceBox service, right now I write a log message and simply issue a return - which for IceBox seems to signal that all is ok). So I would prefer to throw a meaningful exception in that case, ideally the chapter on IceBox should cover this.

So in my case imagine the following code snippet:
void MyServiceI::start(const std::string& name, 
const Ice::CommunicatorPtr& communicator, const Ice::StringSeq& args)
{
  if (communicator->getProperties()->getProperty("ImportantProperty").empty())  
  {
    throw Ice::WhichExceptionToThrow("ImportantPropertyNotSet");
  }

  _adapter = communicator->createObjectAdapter(name);
  _adapter->add(new MyFactoryI());  
  _adapter->activate();
}  

For convenience I attached the source of the relevant part in ServiceManagerI.cpp below.

cheers
Michael
    bool started = false;
    try
    {
        info.service->start(name, info.communicator == 0 ? _sharedCommunicator : info.communicator, info.args);
        started = 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;
    }
    
    {
        IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);

        vector<ServiceInfo>::iterator p;
        for(p = _services.begin(); p != _services.end(); ++p)
        {
            if(p->name == name)
            {
                if(started)
                {
                    p->status = Started;

                    vector<string> services;
                    services.push_back(name);
                    servicesStarted(services, _observers);
                }
                else
                {
                    p->status = Stopped;
                }
                break;
            }
        }
        _pendingStatusChanges = false;
        notifyAll();

Comments

  • benoit
    benoit Rennes, France
    Hi,

    You can throw an IceBox::FailureException:
    if (communicator->getProperties()->getProperty("ImportantProperty").empty())  
    {
        throw IceBox::FailureException(__FILE__, __LINE__, "invalid property");
    }
    

    Cheers,
    Benoit.
  • Hi Benoit

    thanks for your answer, so would you recommend FailureException as best practice is that scenario? I think the IceBox manual could use a short paragraph on the topic.

    Thanks
    Michael
  • mes
    mes California
    grembo wrote: »
    thanks for your answer, so would you recommend FailureException as best practice is that scenario? I think the IceBox manual could use a short paragraph on the topic.
    Yes, using FailureException is the simplest solution. We'll update the manual accordingly.

    Mark
  • Will do, thanks.
  • Just realized, that FailureException is actually defined and documented in IceBox.ice
    /**
     *
     * An application service managed by a {@link ServiceManager}.
     *
     **/
    local interface Service
    {
        /**
         *
         * Start the service. The given communicator is created by the
         * {@link ServiceManager} for use by the service. This communicator may
         * also be used by other services, depending on the service
         * configuration.
         *
         * <p class="Note">The {@link ServiceManager} owns this communicator, and is
         * responsible for destroying it.
         *
         * @param name The service's name, as determined by the
         * configuration.
         *
         * @param communicator A communicator for use by the service.
         *
         * @param args The service arguments that were not converted into
         * properties.
         *
         * @throws FailureException Raised if {@link #start} failed.
         *
         **/
        void start(string name, Ice::Communicator communicator, Ice::StringSeq args);
    
        /**
         *
         * Stop the service.
         *
         **/
        void stop();
    };
    

    I will make sure to consult the individual documentation in slices as well in the future.