sqlalchemy_dlock.lock.postgresql module

class sqlalchemy_dlock.lock.postgresql.PostgresqlAsyncSadLock(connection_or_session, key, **kwargs)[source]

Bases: PostgresqlSadLockMixin, BaseAsyncSadLock[int, AsyncConnection | AsyncSession | async_scoped_session]

Async IO version of PostgresqlSadLock

Parameters:
  • key (Any) –

    PostgreSQL advisory lock requires the key given by INT64.

    • When key is int, the constructor tries to ensure it to be INT64. OverflowError is raised if too big or too small for that.

    • When key is str or bytes or alike, the constructor calculates its checksum by hashlib.blake2b(), and takes the hash result integer value as actual key.

    • Or you can specify a convert function to that argument:

      def convert(val: Any) -> int:
          int64_key: int = do_sth(val)
          return int64_key
      

  • sharedshared

  • xactxact

  • convert – Custom function to covert key to required data type.

  • connection_or_session (AsyncConnection | AsyncSession | async_scoped_session)

async close()[source]

Deprecated since version 0.8.1.

Use aclose() instead. Will be removed in 0.9.0.

async do_acquire(block=True, timeout=None, interval=None, *args, **kwargs)[source]
Return type:

bool

Parameters:
async do_release()[source]
class sqlalchemy_dlock.lock.postgresql.PostgresqlSadLock(connection_or_session, key, **kwargs)[source]

Bases: PostgresqlSadLockMixin, BaseSadLock[Any, Connection | Session | scoped_session]

A distributed lock implemented by PostgreSQL advisory lock

Tip

Locks can be either shared or exclusive: a shared lock does not conflict with other shared locks on the same resource, only with exclusive locks. Locks can be taken at session level (so that they are held until released or the session ends) or at transaction level (so that they are held until the current transaction ends; there is no provision for manual release). Multiple session-level lock requests stack, so that if the same resource identifier is locked three times there must then be three unlock requests to release the resource in advance of session end.

Parameters:
close()[source]

Same as release()

Except that the ValueError is NOT raised when invoked on an unlocked lock.

An invocation of this method is equivalent to:

if not some_lock.locked:
    some_lock.release()

This method maybe useful together with contextlib.closing(), when we need a with statement, but don’t want it to acquire at the beginning of the block.

Example

# ...

from contextlib import closing
from sqlalchemy_dlock import create_sadlock

# ...

with closing(create_sadlock(some_connection, some_key)) as lock:
    # will **NOT** acquire at the begin of with-block
    assert not lock.locked
    # ...
    # lock when need
    lock.acquire()
    assert lock.locked
    # ...

# `close` will be called at the end with-block
assert not lock.locked
do_acquire(block=True, timeout=None, interval=None, *args, **kwargs)[source]

Attention

PostgreSQL’s advisory lock has no timeout mechanism in itself. When timeout is a non-negative number, we simulate it by looping and sleeping.

The interval argument specifies the sleep seconds(1 by default).

That is:

The actual timeout won’t be precise when interval is big; while small interval will cause high CPU usage and frequent SQL execution.

Return type:

bool

Parameters:
do_release()[source]
class sqlalchemy_dlock.lock.postgresql.PostgresqlSadLockMixin(*, key, convert=None, shared=False, xact=False, **kwargs)[source]

Bases: AbstractLockMixin[KTV, int]

A Mix-in class for PostgreSQL advisory lock

Parameters:
  • key (TypeVar(KTV, bound= Any)) –

    PostgreSQL advisory lock requires the key given by INT64.

    • When key is int, the constructor tries to ensure it to be INT64. OverflowError is raised if too big or too small for that.

    • When key is str or bytes or alike, the constructor calculates its checksum by hashlib.blake2b(), and takes the hash result integer value as actual key.

    • Or you can specify a convert function to that argument:

      def convert(val: Any) -> int:
          int64_key: int = do_sth(val)
          return int64_key
      

  • shared (bool) – shared

  • xact (bool) – xact

  • convert (Callable[[TypeVar(KTV, bound= Any)], int] | None) – Custom function to covert key to required data type.

classmethod convert(k)[source]

The default key converter for PostgreSQL advisory lock

Return type:

int

Parameters:

k (bytes | bytearray | memoryview | str | int | float)

classmethod ensure_int64(i)[source]

ensure the integer in PostgreSQL advisory lock’s range (Signed INT64)

  • max of signed int64: 2**63-1 (+0x7FFF_FFFF_FFFF_FFFF)

  • min of signed int64: -2**63 (-0x8000_0000_0000_0000)

Return type:

int

Returns:

Signed int64 key

Parameters:

i (int)

get_actual_key()[source]

The actual key used in MySQL named lock

Return type:

int

property shared: bool

Is the advisory lock shared or exclusive

property xact: bool

Is the advisory lock transaction level or session level