cinder.coordination module

Coordination and locking utilities.

class Coordinator(agent_id: str | None = None, prefix: str = '')

Bases: object

Tooz coordination wrapper.

Coordination member id is created from concatenated prefix and agent_id parameters.

Parameters:
  • agent_id (str) – Agent identifier

  • prefix (str) – Used to provide member identifier with a meaningful prefix.

get_lock(name: str)

Return a Tooz backend lock.

Parameters:

name (str) – The lock name that is used to identify it across all nodes.

remove_lock(glob_name)
start() None
stop() None

Disconnect from coordination backend and stop heartbeat.

synchronized(*lock_names: str, blocking: bool = True, coordinator: ~cinder.coordination.Coordinator = <cinder.coordination.Coordinator object>) Callable

Synchronization decorator.

Parameters:
  • lock_names (str) – Arbitrary number of Lock names.

  • blocking – If True, blocks until the lock is acquired. If False, raises exception when not acquired. Otherwise, the value is used as a timeout value and if lock is not acquired after this number of seconds exception is raised. This is a keyword only argument.

  • coordinator – Coordinator class to use when creating lock. Defaults to the global coordinator. This is a keyword only argument.

Raises:

tooz.coordination.LockAcquireFailed – if lock is not acquired

Decorating a method like so:

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

ensures that only one process 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.

Lock name can be formatted using Python format string syntax:

@synchronized('{f_name}-{vol.id}-{snap[name]}')
def foo(self, vol, snap):
   ...

Multiple locks can be requested simultaneously and the decorator will reorder the names by rendered lock names to prevent potential deadlocks.

@synchronized(‘{f_name}-{vol.id}-{snap[name]}’,

‘{f_name}-{vol.id}.delete’)

def foo(self, vol, snap):

Available field names are: decorated function parameters and f_name as a decorated function name.

synchronized_remove(glob_name, coordinator=<cinder.coordination.Coordinator object>)