{"id":7484,"library":"oslo-service","title":"Oslo Service","description":"oslo.service is a Python library that provides a robust framework for defining and running long-running services within the OpenStack ecosystem. It encapsulates patterns for service management, including handling concurrency, periodic operations, WSGI applications, and integration with systemd. The library is actively maintained as part of the OpenStack Oslo project, with version 4.5.1 being the latest as of February 2026, and receives regular updates.","status":"active","version":"4.5.1","language":"en","source_language":"en","source_url":"https://github.com/openstack/oslo.service","tags":["OpenStack","service management","daemon","concurrency","WSGI","systemd","oslo"],"install":[{"cmd":"pip install oslo-service","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Fundamental for configuration management within Oslo projects.","package":"oslo.config"},{"reason":"Provides common utility functions like encoding, exception handling, and time management.","package":"oslo.utils"},{"reason":"Helpers to maintain useful information about a request context, often populated in WSGI pipelines.","package":"oslo.context"},{"reason":"Historically a core dependency for concurrency (green threads), but is being phased out in future versions (see warnings).","package":"eventlet","optional":true}],"imports":[{"note":"Primary module for service base classes and launcher functions.","symbol":"service","correct":"from oslo_service import service"},{"note":"Commonly used alongside oslo.service for configuration, often aliased as 'cfg'.","symbol":"cfg","correct":"from oslo_config import cfg"}],"quickstart":{"code":"import os\nfrom oslo_config import cfg\nfrom oslo_service import service\n\n# Define a simple configuration option\nservice_opts = [\n    cfg.IntOpt('workers', default=1, min=1, help='Number of worker processes')\n]\nCONF = cfg.CONF\nCONF.register_opts(service_opts, group='my_service')\n\nclass MyService(service.ServiceBase):\n    def __init__(self, conf):\n        super().__init__(conf)\n        self.conf = conf\n        self.should_stop = False\n        print(f\"Service initialized with {self.conf.my_service.workers} workers.\")\n\n    def start(self):\n        print(f\"Service worker {os.getpid()} starting...\")\n        # Simulate some work\n        # In a real service, this would be a long-running loop or event listener\n\n    def stop(self):\n        self.should_stop = True\n        print(f\"Service worker {os.getpid()} stopping...\")\n\n    def wait(self):\n        # In a real service, this would block until stop() is called\n        import time\n        while not self.should_stop:\n            time.sleep(0.1)\n\ndef main():\n    CONF(args=[], project='my_app') # Pass empty args to avoid argparse errors if not parsing CLI\n    \n    # Instantiate your service\n    my_service_instance = MyService(CONF)\n\n    # Launch the service with workers\n    # Note: oslo.service's launch function creates a Launcher internally\n    # and manages worker processes if `workers` > 1.\n    # For a simple example, we often directly call the Service's methods.\n    # For multi-process, `service.launch` is key.\n    launcher = service.launch(CONF, my_service_instance, workers=CONF.my_service.workers)\n    print(f\"Launcher started for PID {os.getpid()} with {CONF.my_service.workers} workers.\")\n\n    # Wait for the service to complete (e.g., via signal handler or internal logic)\n    launcher.wait()\n    print(\"All services stopped.\")\n\nif __name__ == '__main__':\n    # To run this, you might need to install oslo.config and oslo.service\n    # and ideally run with python -m your_script_name\n    # This example demonstrates the basic structure, but running actual\n    # multi-worker services requires more robust signal handling and process management\n    # which oslo.service provides internally.\n    main()\n","lang":"python","description":"This quickstart demonstrates how to define a basic service using `oslo_service.service.ServiceBase` and launch it with `oslo_service.service.launch`. It includes integration with `oslo_config` for defining and reading configuration options, such as the number of worker processes. The `start`, `stop`, and `wait` methods illustrate the service lifecycle."},"warnings":[{"fix":"Review OpenStack's 'remove-eventlet-from-oslo-service' specification for migration strategies and alternative concurrency models. Services might need to re-architect parts of their concurrent operations.","message":"Future versions of oslo.service are removing the Eventlet dependency, which will significantly impact services heavily relying on Eventlet's green thread model for concurrency (e.g., `loopingcall`, `periodic task`, `wsgi`, `threadgroup`). This is a mandatory architectural shift within OpenStack.","severity":"breaking","affected_versions":"Versions after 4.x (exact target version for full removal is in flux, but migration is ongoing)."},{"fix":"Ensure that configuration options are registered only once. This can often occur due to improper import ordering or multiple components attempting to register the same option. Refactor imports or use `cfg.CONF.register_opts(..., enforce_type=False)` (use with caution) or check `cfg.CONF.list_opts()` before registering.","message":"Encountering 'oslo_config.cfg.DuplicateOptError' when defining configuration options, especially in complex OpenStack deployments or when integrating multiple oslo libraries.","severity":"gotcha","affected_versions":"All versions using oslo.config."},{"fix":"Verify RabbitMQ service status and connectivity. Check RabbitMQ logs for 'missed heartbeats' or 'queue not found' errors. Ensure correct `transport_url` configuration in `oslo.config` and proper RabbitMQ user permissions and policies. Increase heartbeat timeouts if network latency is a factor.","message":"Services using `oslo.messaging` may encounter `OSError: Server unexpectedly closed connection` or `oslo_messaging.exceptions.MessageUndeliverable` errors, often related to RabbitMQ issues or network instability.","severity":"gotcha","affected_versions":"All versions using oslo.messaging for RPC."}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Check network connectivity between the service and RabbitMQ. Review RabbitMQ logs for errors like 'missed heartbeats from client'. Consider increasing `rabbit_heartbeat_timeout_threshold` in `oslo.config` to tolerate brief network hiccups.","cause":"Often indicates a dropped connection to the message broker (e.g., RabbitMQ) due to network issues, broker overload, or missed heartbeats.","error":"OSError: Server unexpectedly closed connection"},{"fix":"Ensure the receiving service is running and its message queues are properly initialized. Verify that the routing keys and topics configured for message publication match the expected queue bindings on the consumer side. Check RabbitMQ management interface for queue existence.","cause":"A message could not be delivered to its intended recipient, typically because the target queue does not exist or the connection was lost before delivery.","error":"oslo_messaging.exceptions.MessageUndeliverable"}]}