Reference

Module that imports helpers.

class dspinlock.DSpinlockBase(obj: Any, sess: Redis | None = None, redis_params: RedisParameters | None = None, fail_if_key_exists: bool = False, cached_if_computed: bool = False)[source]

Class that ensures the query isolation in case of parallel requests.

max_spinlock_tries: int = 10

The spinlock max retries, by default 10 tries.

spinlock_sleep_thresh: float = 0.5

The spinlock sleep threshold, by default 0.5 seconds.

expire_at_timedelta: timedelta = datetime.timedelta(seconds=3600)

The expire_at timedelta value, by default 1 hour.

max_block_time: timedelta = datetime.timedelta(seconds=1800)

The max block time allowed for a query mutex to be held, if not released it is forcefully unblocked.

__init__(obj: Any, sess: Redis | None = None, redis_params: RedisParameters | None = None, fail_if_key_exists: bool = False, cached_if_computed: bool = False)[source]

The constructor which takes

Parameters:
  • obj (Any) – The object to create the lock for.

  • sess (redis.Redis | None = None) – The session to redis, which can be None.

  • redis_params (RedisParameters | None = None) – If the sess above is None then if this flag is raised, we create the connection using sample params.

  • fail_if_key_exists (bool = False) – Indicates if we fail should the key already exists - i.e. in cases when we want to block computation for a certain period.

  • cached_if_computed (bool = False) – Indicates if the result is computed can be returned from a cache. Thus, we do not have to wait for its computation; hence, we can return immediately _without_ practically getting the lock.

abstract get_key() str[source]

Fetches the base key for the page.

Returns:

The key to store the value in redis.

Return type:

str

delete_atomic_query_mutex_state() bool[source]

Attempt to delete a specific mutex state for a given key from the global state stored within redis.

Returns:

Returns True if we managed to successfully delete the mutex state, False otherwise.

Return type:

bool

class dspinlock.HashDSpinlock(obj: Any, sess: Redis | None = None, redis_params: RedisParameters | None = None, fail_if_key_exists: bool = False, cached_if_computed: bool = False)[source]

A Hash-based Distributed Spinlock, which works on any object that implements Hashable.

get_key() str[source]

Gets the key for the entry. For this particular implementation, it has the following format,

key = {self._key_prefix}{self.tag_sep}{self._obj_hash}

Where the following values normally hold - unless overriden,

  • _key_prefix: dspinlock

  • _obj_hash: the result of using the hash function with the object instance - _i.e._: hash(obj)

By default, each segment of the key is separated by a comma - though internally this can be configured by adjusting the _key_sep variable.

Note that the _key_prefix value can also be adjusted, but as mentioned above, the default is: dspinlock.

Returns:

The entry key.

Return type:

str

exception dspinlock.AtomicQueryInvalidStateException[source]

Raised when we encounter an invalid state during AtomicQuery execution.

exception dspinlock.InvalidMutexReleaseEncountered[source]

Raised when we try to release a mutex that is not ours.

exception dspinlock.RedisNotInitializedException[source]

Raised when redis instance is not initialised properly.

exception dspinlock.SpinlockTriesExceeded[source]

Raised when we exhaust our spinlock tries due to query taking very long.

exception dspinlock.InvalidValueEncounteredDuringUnpacking[source]

Raised when the unpacked value of the mutex cannot be parsed.

exception dspinlock.FailIfKeyExistsIsEnabled[source]

Raised when we try to acquire a lock when the key already exists and the flag to fail is so is True

exception dspinlock.ProvidedObjectIsNotHashable[source]

Raised when the object passed does not implement Hashable.