libmoost
/home/mhx/git/github/libmoost/include/moost/process/service.hpp File Reference
#include <stdexcept>
#include <cassert>
#include <boost/filesystem/path.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include "daemon.hpp"
#include "sleeper.hpp"
#include "pidfile.hpp"
#include "quit_handler.hpp"
#include "../logging/class_logger.hpp"
#include "../logging/standard_console.hpp"
#include "../service/remote_shell.h"
#include "../service/appender.h"
Include dependency graph for service.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  moost::process::NoConsoleLoggerPolicy
class  moost::process::MoostStandardConsoleLoggerPolicy
class  moost::process::service< ServiceT, ConsoleLoggerPolicy >
struct  moost::process::service< ServiceT, ConsoleLoggerPolicy >::noop_child_init_func
struct  moost::process::service< ServiceT, ConsoleLoggerPolicy >::default_parent_exit_func
class  moost::process::service< ServiceT, ConsoleLoggerPolicy >::service_wrapper
struct  moost::process::service< ServiceT, ConsoleLoggerPolicy >::enable_logger_func

Namespaces

namespace  moost
 

Creates a unique temporary directory; removed on scope exit.


namespace  moost::process

Defines

#define MPS_FM303_SHELL_CONST

Detailed Description

Copyright © 2008-2013 Last.fm Limited

This file is part of libmoost.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

The moost::process::service class hides most of the process of setting up a system service within an easy to use, yet customisable template. It takes care of:

  • daemonisation
  • pid file creation
  • setting up signal handlers
  • setting up a local and/or remote command shell
  • setting up a moost::standard_console
  • starting the service
  • shutting down the service

For this to work, a (usually very small) service class must be provided that implements the following methods:

class MyService
{
public:
   typedef MyServiceHandler HandlerType;   // a typedef for the service handler

   const std::string& name() const;        // returns the name of the service

   boost::shared_ptr<HandlerType> handler();
                                 // returns a shared pointer to the service handler object,
                                 //    which must implement the necessary methods to be used
                                 //    with moost::service::remote_shell
                                 // guaranteed not to be called before start() or after stop()

   void start();                 // performs all operations necessary to create and start the
                                 //    service handler

   void stop();                  // performs all operations necessary to stop the service
                                 //    handler
};

The service handler defined by HandlerType must be compatible with moost::service::remote_shell, i.e. it must implement the get_prompt(), show_help() and handler_command() methods. It can be, but doesn't neccessarily have to be derived from moost::fm303_cmd_shell.

With the above class, a simple service can be implemented in a couple of lines of code:

int main()
{
   MLOG_INIT();

   moost::process::service<MyService> service(new MyService);

   service.set_pidfile(pidfile);       // optional: override pid file name
   service.set_shell_port(shell_port); // optional: to enable the remote shell, set the shell port

   service.run(in_daemon_mode);        // run the service in daemon/non-daemon mode

   return 0;
}

Nothing important happens inside the service object until its run() method is called. The run method will do the following:

  • The parent process will create a pid file and exit.
  • If in_daemon_mode is true or a remote shell port has been set (i.e. if there is no local shell), it will set up a signal handler using moost::process::quit_handler.
  • It will then call the start() method of service class defined above. The start() method must return with the created service handler running in its own thread.
  • Whenever either shell exits or a terminating signal is received, the stop() method of the service class will be called.
  • Finally, the run() method returns.

The service class must ensure that its handler() method returns a valid handler object after the start() method has been called until the stop() method is called.

Here are some examples for more advanced usage:

  • You can use the set_child_init_func() method to set a boost::function object that will be passed on to moost::process::daemon and that will be called just after the child process has been forked. If the service is not daemonised, the function object will be called just after the run() method has been entered. The return value is ignored in that case. Note that the child init function is called just in time to allow further configuration of the moost::process::service instance, i.e. you can still configure all options relevant for the child process from within the child init function.
  • You can also override the exit behaviour of the parent process using set_parent_exit_func(). The function object is called with the child's process id as its only argument. The default implementation just calls exit(0). If you don't call exit() from the function object, run() will just return in the parent process and as a side effect, the pid file will be deleted as soon as the parent's instance of moost::process::service is destroyed.
  • You can override the creation of a console logger by passing a console logger policy as a template argument to moost::process::service. The default MoostStandardConsoleLoggerPolicy will create a moost::logging::standard_console instance. Use NoConsoleLoggerPolicy if you don't want a console logger. Note that the remote shell doesn't require a console logger to support logging.

If you think that your service code is too long even with moost::process::service, have a look at moost::service::skeleton.

Definition in file service.hpp.


Define Documentation

Definition at line 174 of file service.hpp.