oslo_concurrency.lockutils

class oslo_concurrency.lockutils.FairLocks

Bases: object

A garbage collected container of fair locks.

With a fair lock, contending lockers will get the lock in the order in which they tried to acquire it.

This collection internally uses a weak value dictionary so that when a lock is no longer in use (by any threads) it will automatically be removed from this container by the garbage collector.

get(name)

Gets (or creates) a lock with a given name.

Parameters

name – The lock name to get/create (used to associate previously created names with the same lock).

Returns an newly constructed lock (or an existing one if it was already created for the given name).

class oslo_concurrency.lockutils.ReaderWriterLock(condition_cls=<class 'threading.Condition'>, current_thread_functor=None)

Bases: object

A reader/writer lock.

This lock allows for simultaneous readers to exist but only one writer to exist for use-cases where it is useful to have such types of locks.

Currently a reader can not escalate its read lock to a write lock and a writer can not acquire a read lock while it is waiting on the write lock.

In the future these restrictions may be relaxed.

This can be eventually removed if http://bugs.python.org/issue8800 ever gets accepted into the python standard threading library…

READER = 'r'

Reader owner type/string constant.

WRITER = 'w'

Writer owner type/string constant.

property has_pending_writers

Returns if there are writers waiting to become the one writer.

is_reader()

Returns if the caller is one of the readers.

is_writer(check_pending=True)

Returns if the caller is the active writer or a pending writer.

property owner

Returns whether the lock is locked by a writer or reader.

read_lock()

Context manager that grants a read lock.

Will wait until no active or pending writers.

Raises a RuntimeError if a pending writer tries to acquire a read lock.

write_lock()

Context manager that grants a write lock.

Will wait until no active readers. Blocks readers after acquiring.

Raises a RuntimeError if an active reader attempts to acquire a lock.

class oslo_concurrency.lockutils.Semaphores

Bases: object

A garbage collected container of semaphores.

This collection internally uses a weak value dictionary so that when a semaphore is no longer in use (by any threads) it will automatically be removed from this container by the garbage collector.

New in version 0.3.

get(name)

Gets (or creates) a semaphore with a given name.

Parameters

name – The semaphore name to get/create (used to associate previously created names with the same semaphore).

Returns an newly constructed semaphore (or an existing one if it was already created for the given name).

oslo_concurrency.lockutils.external_lock(name, lock_file_prefix=None, lock_path=None)
oslo_concurrency.lockutils.get_lock_path(conf)

Return the path used for external file-based locks.

Parameters

conf (oslo_config.cfg.ConfigOpts) – Configuration object

New in version 1.8.

oslo_concurrency.lockutils.internal_fair_lock(name)
oslo_concurrency.lockutils.internal_lock(name, semaphores=None)
oslo_concurrency.lockutils.lock(name, lock_file_prefix=None, external=False, lock_path=None, do_log=True, semaphores=None, delay=0.01, fair=False)

Context based lock

This function yields a threading.Semaphore instance (if we don’t use eventlet.monkey_patch(), else semaphore.Semaphore) unless external is True, in which case, it’ll yield an InterProcessLock instance.

Parameters
  • lock_file_prefix – The lock_file_prefix argument is used to provide lock files on disk with a meaningful prefix.

  • external – The external keyword argument denotes whether this lock should work across multiple processes. This means that if two different workers both run a method decorated with @synchronized(‘mylock’, external=True), only one of them will execute at a time.

  • lock_path – The path in which to store external lock files. For external locking to work properly, this must be the same for all references to the lock.

  • do_log – Whether to log acquire/release messages. This is primarily intended to reduce log message duplication when lock is used from the synchronized decorator.

  • semaphores – Container that provides semaphores to use when locking. This ensures that threads inside the same application can not collide, due to the fact that external process locks are unaware of a processes active threads.

  • delay – Delay between acquisition attempts (in seconds).

  • fair – Whether or not we want a “fair” lock where contending lockers will get the lock in the order in which they tried to acquire it.

Changed in version 0.2: Added do_log optional parameter.

Changed in version 0.3: Added delay and semaphores optional parameters.

oslo_concurrency.lockutils.main()
oslo_concurrency.lockutils.remove_external_lock_file(name, lock_file_prefix=None, lock_path=None, semaphores=None)

Remove an external lock file when it’s not used anymore This will be helpful when we have a lot of lock files

oslo_concurrency.lockutils.remove_external_lock_file_with_prefix(lock_file_prefix)

Partial object generator for the remove lock file function.

Redefine remove_external_lock_file_with_prefix in each project like so:

(in nova/utils.py)
from oslo_concurrency import lockutils

synchronized = lockutils.synchronized_with_prefix('nova-')
synchronized_remove = lockutils.remove_external_lock_file_with_prefix(
    'nova-')

(in nova/foo.py)
from nova import utils

@utils.synchronized('mylock')
def bar(self, *args):
   ...

<eventually call synchronized_remove('mylock') to cleanup>

The lock_file_prefix argument is used to provide lock files on disk with a meaningful prefix.

oslo_concurrency.lockutils.set_defaults(lock_path)

Set value for lock_path.

This can be used by tests to set lock_path to a temporary directory.

oslo_concurrency.lockutils.synchronized(name, lock_file_prefix=None, external=False, lock_path=None, semaphores=None, delay=0.01, fair=False)

Synchronization decorator.

Decorating a method like so:

@synchronized('mylock')
def foo(self, *args):
   ...

ensures that only one thread will execute the foo method at a time.

Different methods can share the same lock:

@synchronized('mylock')
def foo(self, *args):
   ...

@synchronized('mylock')
def bar(self, *args):
   ...

This way only one of either foo or bar can be executing at a time.

Changed in version 0.3: Added delay and semaphores optional parameter.

oslo_concurrency.lockutils.synchronized_with_prefix(lock_file_prefix)

Partial object generator for the synchronization decorator.

Redefine @synchronized in each project like so:

(in nova/utils.py)
from oslo_concurrency import lockutils

synchronized = lockutils.synchronized_with_prefix('nova-')


(in nova/foo.py)
from nova import utils

@utils.synchronized('mylock')
def bar(self, *args):
   ...

The lock_file_prefix argument is used to provide lock files on disk with a meaningful prefix.