Welcome to Padlock’s documentation!

Padlock is a Python library that provides a lock through a single, simple interface and offers several backends (actually, for now, only one, until someone contributes another) so you can choose the backend that best fits your needs.

The Interface

padlock.get(name, **kwargs)

Returns a factory named by name. If **kwargs are provided, an instance will be constructed and the kwargs will be passed to the class desired.

For instance, to construct a cassandra lock:

>>> import padlock, pycassa
>>> pool = pycassa.ConnectionPool('my_keyspace')
>>> lock = padlock.get('cassandra', pool=pool, column_family='MyColumnFamily')
>>> with lock:
...     do_some_stuff()
"stuff"
>>>
Parameters:name (string) – The lock class desired (see Backends)
Return type:an ILock
interface padlock.ILock[source]

Your average, run of the mill, generic lock interface.

acquire(self)[source]

Acquires the lock.

release(self)[source]

Releases the lock.

__enter__(self)[source]

ILock is also a context manager, so you can use the convenient with: syntax

__exit__(self, exc_type, exc_val, exc_tb)[source]

The exit functionality for context managers (catches exceptions, releases the lock and whatnot)

The Cassandra Backend

The Cassandra lock is a lock implemented in a cassandra row. It’s best used when also using cassandra for some other purpose and contention would likely not be an issue anyway (the lock provides the extra safety gear necessary to perform some operation).

To use the cassandra lock, instantiate using the padlock.get() function. You’ll also need a recent version of pycassa installed:

import padlock, pycassa
pool = pycassa.ConnectionPool('my_keyspsace'
with padlock.get('cassandra', pool=pool, column_family='my_column_family'):
    do_some_important_shit()

Success! Please read through the class documentation to get a feel of how to use the lock. It will likely be a little specific to your implementation.

class padlock.distributed.cassandra.StaleLockException[source]

Raised old, stale locks exist on a row and we don’t want them to have existed.

class padlock.distributed.cassandra.BusyLockException[source]

Raised when a lock is already taken on this row.

class padlock.distributed.cassandra.CassandraDistributedRowLock(pool, column_family, key, **kwargs)[source]

A lock that is implemented in a row of a Cassandra column family. It’s good to use this type of lock when you want to lock a single row in cassandra for some purpose in a scenario where there will not be a lot of lock contention.

Shamelessly lifted from: Netflix’s Astynax library. Take a look at the implementation (in Java).

Parameters:
  • pool (pycassa.pool.ConnectionPool) – A pycassa ConnectionPool. It will be used to facilitate communication with cassandra.
  • column_family (string) – Either a string (which will then be made into a pycassa.column_family.ColumnFamily instance) or an already configured instance of ColumnFamily (which will be used directly).
  • key (string) – The row key for this lock. The lock can co-exist with other columns on an existing row if desired.

The following paramters are optional and all come with defaults:

Parameters:
  • prefix (str) – The column prefix. Defaults to _lock_
  • lock_id (str) – A unique string, should probably be a UUIDv1 if provided at all. Defaults to a UUIDv1 provided by time-uuid
  • fail_on_stale_lock (bool) – Whether or not to fail when stale locks are found. Otherwise they’ll just be cleaned up.
  • timeout (float) – How long to wait until the lock is considered stale. You should set this to as much time as you think the work will take using the lock.
  • ttl (float) – How many seconds until cassandra will automatically clean up stale locks. It must be greater than timeout.
  • backoff_policy (IRetryPolicy) – a padlock.distributed.retry_policy.IRetryPolicy instance. Governs the retry policy of acquiring the lock.
  • allow_retry (bool) – Whether or not to allow retry. Defaults to True

You can also provide the following keyword arguments which will be passed directly to the ColumnFamily constructor if you didn’t provide the instance yourself:

  • read_consistency_level
  • write_consistency_level
  • autopack_names
  • autopack_values
  • autopack_keys
  • column_class_name
  • super_column_name_class
  • default_validation_class
  • column_validators
  • key_validation_class
  • dict_class
  • buffer_size
  • column_bufer_size
  • timestamp
acquire()[source]

Acquire the lock on this row. It will then read immediatly from cassandra, potentially retrying, potentially sleeping the executing thread.

fill_lock_mutation(mutation, time, ttl)[source]

Used internally - fills out pycassa.batch.CfMutator with the necessary steps to acquire the lock.

fill_release_mutation(mutation, exclude_current_lock=False)[source]

Used internally - used to fill out a pycassa.batch.CfMutator with the necessary steps to release the lock.

generate_timeout_value(timeout_val)[source]

Used internally - serialize a timeout value (a long) to be inserted into a cassandra as a string.

read_lock_columns()[source]

Return all columns in this row with the timeout value deserialized into a long

Return type:dict
read_timeout_value(col)[source]

Used internally - deserialize a timeout value that was stored in cassandra as a string back into a long.

release()[source]

Allow this row to be locked by something (or someone) else. Performs a single write (round trip) to Cassandra.

release_locks(force=False)[source]

Clean up after ourselves. Removes all lock columns (everything returned by read_lock_columns()) that is not stale.

Parameters:force – Remove even non-stale locks
utcnow()[source]

Used internally - return the current time, as microseconds from the unix epoch (Jan 1 1970 UTC)

Return type:long
verify_lock(cur_time)[source]

Whether or not the lock can be verified by reading the row and ensuring the paramters of the lock according to the current CassandraDistributedRowLock instance’s configuration is valid.

This must only be called after acquire() is called, or else you will get a ValueError

Parameters:cur_time (long) – The current time in microseconds
Return type:None

Indices and tables

Table Of Contents

This Page