The cinder.coordination Module

Coordination and locking utilities.

class Coordinator(agent_id=None, prefix='')

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)

Return a Tooz backend lock.

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

Coordinator heartbeat.

Method that every couple of seconds (config: coordination.heartbeat) sends heartbeat to prove that the member is not dead.

If connection to coordination backend is broken it tries to reconnect every couple of seconds (config: coordination.initial_reconnect_backoff up to coordination.max_reconnect_backoff)

is_active()
start()

Connect to coordination backend and start heartbeat.

stop()

Disconnect from coordination backend and stop heartbeat.

class Lock(lock_name, lock_data=None, coordinator=None)

Bases: tooz.locking.Lock

Lock with dynamic name.

Parameters:
  • lock_name (str) – Lock name.
  • lock_data (dict) – Data for lock name formatting.
  • coordinator – Coordinator class to use when creating lock. Defaults to the global coordinator.

Using it like so:

with Lock('mylock'):
   ...

ensures that only one process at a time will execute code in context. Lock name can be formatted using Python format string syntax:

Lock('foo-{volume.id}, {'volume': ...,})

Available field names are keys of lock_data.

acquire(blocking=None)

Attempts to acquire lock.

Parameters:blocking – If True, blocks until the lock is acquired. If False, returns right away. Otherwise, the value is used as a timeout value and the call returns maximum after this number of seconds.
Returns:returns true if acquired (false if not)
Return type:bool
name
release()

Attempts to release lock.

The behavior of releasing a lock which was not acquired in the first place is undefined.

synchronized(lock_name, blocking=True, coordinator=None)

Synchronization decorator.

Parameters:
  • lock_name (str) – Lock name.
  • 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.
  • coordinator – Coordinator class to use when creating lock. Defaults to the global coordinator.
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):
   ...

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