The oslo.concurrency library provides utilities for safely running multi-thread and multi-process applications using locking mechanisms, as well as for running external processes. It is a core component of the OpenStack Oslo project, which generally follows a six-month release cadence for major OpenStack releases.
pip install oslo-concurrencyVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates how to use `oslo_concurrency.lockutils.synchronized` for inter-process locking. It configures a `lock_path` and defines a function that will be synchronized across different 'workers'. Note that for actual multi-process execution, you would typically run separate Python processes that each call `my_locked_function`.
Update import statements to directly reference `oslo_concurrency` (e.g., `from oslo_concurrency import lockutils`).
Set the `lock_path` via `lockutils.set_defaults(lock_path='/path/to/locks')` or by configuring `oslo_concurrency.lock_path` if using `oslo.config`.
Carefully review the concurrency safety guarantees of all integrated libraries. For `oslo.messaging`, use separate connection instances for concurrent read and write operations if using eventlet/green threads.
Install the library using pip: `pip install oslo-concurrency`
Examine the `stdout` and `stderr` attributes of the `ProcessExecutionError` exception for details on why the command failed. Ensure the command syntax is correct, its dependencies are met, and it runs successfully outside of the `oslo-concurrency` context. You can also specify allowed exit codes using the `check_exit_code` parameter in `execute` or `trycmd`.
Configure a `lock_path` globally using `lockutils.set_defaults(lock_path='/path/to/lock/files')` before using the decorator, or ensure the `OSLO_LOCK_PATH` environment variable is set. The specified directory must be writable by the user running the processes.
Review the lock acquisition and release logic to ensure consistent ordering and proper error handling that guarantees lock release. If using `multiprocessing`, consider setting the start method to 'spawn' or 'forkserver' (e.g., `multiprocessing.set_start_method('spawn', force=True)` at the beginning of your main script) to avoid issues related to inherited resources from the parent process.