=======
 Usage
=======

To use oslo.service in a project::

    import oslo_service

Migrating to oslo.service
=========================

The ``oslo.service`` library no longer assumes a global configuration object is
available. Instead the following functions and classes have been
changed to expect the consuming application to pass in an ``oslo.config``
configuration object:

* :func:`~oslo_service.eventlet_backdoor.initialize_if_enabled`
* :py:class:`oslo_service.periodic_task.PeriodicTasks`
* :func:`~oslo_service.service.launch`
* :py:class:`oslo_service.service.ProcessLauncher`
* :py:class:`oslo_service.service.ServiceLauncher`
* :func:`~oslo_service.sslutils.is_enabled`
* :func:`~oslo_service.sslutils.wrap`

When using service from oslo-incubator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    from foo.openstack.common import service

    launcher = service.launch(service, workers=2)

When using oslo.service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    from oslo_config import cfg
    from oslo_service import service

    CONF = cfg.CONF
    launcher = service.launch(CONF, service, workers=2)

Using oslo.service with oslo-config-generator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``oslo.service`` provides several entry points to generate a configuration
files.

* :func:`oslo.service.service <oslo_service.service.list_opts>`
    The options from the service and eventlet_backdoor modules for
    the [DEFAULT] section.

* :func:`oslo.service.periodic_task <oslo_service.periodic_task.list_opts>`
    The options from the periodic_task module for the [DEFAULT] section.

* :func:`oslo.service.sslutils <oslo_service.sslutils.list_opts>`
    The options from the sslutils module for the [ssl] section.

**ATTENTION:** The library doesn't provide an oslo.service entry point.

.. code-block:: bash

    $ oslo-config-generator --namespace oslo.service.service \
    --namespace oslo.service.periodic_task \
    --namespace oslo.service.sslutils

Launching and controlling services
==================================

oslo_service.service module provides tools for launching OpenStack services and controlling their lifecycles.

A service is an instance of any class that subclasses :py:class:`oslo_service.service.ServiceBase`.
:py:class:`ServiceBase <oslo_service.service.ServiceBase>` is an abstract class that defines an interface every
service should implement. :py:class:`oslo_service.service.Service` can serve as a base for constructing new services.

Launchers
~~~~~~~~~

oslo_service.service module provides two launchers for running services:

    * :py:class:`oslo_service.service.ServiceLauncher` - used for running one or more service in
      a parent process.
    * :py:class:`oslo_service.service.ProcessLauncher` - forks a given number of workers in which
      service(s) are then started.

It is possible to initialize whatever launcher is needed and then launch a service using it.

::

    from oslo_config import cfg
    from oslo_service import service

    CONF = cfg.CONF


    service_launcher = service.ServiceLauncher(CONF)
    service_launcher.launch_service(service.Service())

    process_launcher = service.ProcessLauncher(CONF, wait_interval=1.0)
    process_launcher.launch_service(service.Service(), workers=2)

Or one can simply call :func:`oslo_service.service.launch` which will automatically pick an appropriate launcher
based on a number of workers that are passed to it (ServiceLauncher in case workers=1 or None and ProcessLauncher in
other case).

::

    from oslo_config import cfg
    from oslo_service import service

    CONF = cfg.CONF

    launcher = service.launch(CONF, service.Service(), workers=3)

*NOTE:* Please be informed that it is highly recommended to use no more than one instance of ServiceLauncher and
ProcessLauncher classes per process.

Signal handling
~~~~~~~~~~~~~~~

oslo_service.service provides handlers for such signals as SIGTERM and SIGHUP.

SIGTERM is used for graceful termination of services. This can allow a server to wait for all clients to close
connections while rejecting new incoming requests. To force instantaneous termination SIGINT signal must be sent.

On receiving SIGHUP configuration files are reloaded and a service is being reset and started again.Thus, SIGHUP
can be used for changing config options on the go. To achieve this each service should implement a *reset* method
which actually enforces changes to config options values.

Below is the example of a service with a reset method that allows reloading logging options by sending a SIGHUP.

::

    from oslo_config import cfg
    from oslo_log import log as logging
    from oslo_service import service

    CONF = cfg.CONF

    LOG = logging.getLogger(__name__)

    class FooService(service.ServiceBase):

        def start(self):
            pass

        def wait(self):
            pass

        def stop(self):
            pass

        def reset(self):
            logging.setup(cfg.CONF, 'foo')


