Module¶
pglock
¶
pglock.Cancel
¶
Cancel(**filters: Any)
Bases: PrioritizeSideEffect
The side effect for canceling blocking locks
when using pglock.prioritize.
Calls cancel_blocking_activity on the
blocked lock queryset.
Supply a duration to only cancel queries lasting greater than the duration.
Source code in pglock/core.py
pglock.PrioritizeSideEffect
¶
PrioritizeSideEffect(**filters: Any)
Bases: SideEffect
Base class for pglock.prioritize side effects.
Must override the worker method, which takes
a pglock.models.BlockedPGLock queryset of all locks
that are blocking the prioritized process.
Return the process IDs or blocked locks that were handled.
Prioritize side effects take optional filters when initialize, which are passed to the underlying pglock.models.BlockedPGLock queryset.
Source code in pglock/core.py
pglock.Raise
¶
Bases: SideEffect
The side effect for raising an error on lock acquisition
failure when using pglock.advisory or pglock.model.
pglock.Return
¶
Bases: SideEffect
The side effect for returning the lock status when
using pglock.advisory or pglock.model.
pglock.SideEffect
¶
The base class for side effects
pglock.Skip
¶
Bases: SideEffect
The side effect for skipping wrapped code on lock acquisition error
when using pglock.advisory as a decorator.
pglock.Terminate
¶
Terminate(**filters: Any)
Bases: PrioritizeSideEffect
The side effect for terminating blocking locks
when using pglock.prioritize.
Calls teminate_blocking_activity on the
blocked lock queryset.
Supply a duration to only terminate queries lasting greater than the duration.
Source code in pglock/core.py
pglock.advisory
¶
advisory(
lock_id: int | str | None = None,
*,
shared: bool = False,
xact: bool = False,
using: str = DEFAULT_DB_ALIAS,
timeout: float | timedelta | _Unset | None = _unset,
side_effect: _AdvisorySideEffect | None = None
)
Bases: ContextDecorator
Obtain an advisory lock.
When using the default side effect, returns True if the lock was acquired or False if not.
Consult the
Postgres docs <https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS>__
for more information on shared and transactional locks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lock_id
|
Union[str, int], default=None
|
The ID of the lock. When using the decorator, it defaults to the full module path and function name of the wrapped function. It must be supplied to the context manager or function calls. |
None
|
shared
|
bool, default=False
|
When |
False
|
xact
|
bool, default=False
|
When |
False
|
using
|
str, default="default"
|
The database to use. |
DEFAULT_DB_ALIAS
|
timeout
|
Union[int, float, timedelta, None]
|
Set a timeout when waiting
for the lock. This timeout only applies to the lock acquisition statement and not the
wrapped code. If 0, |
_unset
|
side_effect
|
type[SideEffect] | SideEffect | None
|
Adjust the runtime behavior when using a timeout.
|
None
|
Raises:
| Type | Description |
|---|---|
OperationalError
|
When a lock cannot be acquired or a timeout happens
when using |
ValueError
|
If an invalid |
TypeError
|
If the lock ID is not a string or int. |
Source code in pglock/core.py
acquire
¶
acquire() -> bool
Acquire an advisory lock, returning the lock status.
Raises:
| Type | Description |
|---|---|
ValueError
|
When:
- |
RuntimeError
|
When acquiring outside of a transaction for |
OperationalError
|
When a lock cannot be acquired or a timeout happens
when |
Source code in pglock/core.py
release
¶
Release an advisory lock.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
When releasing a lock with |
Source code in pglock/core.py
pglock.advisory_id
¶
Given a lock ID, return the (classid, objid) tuple that Postgres uses for the advisory lock in the pg_locks table,
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lock_id
|
Union[str, int]
|
The lock ID |
required |
Returns:
| Type | Description |
|---|---|
tuple[int, int]
|
The (classid, objid) tuple |
Source code in pglock/core.py
pglock.model
¶
model(
*models: str | type[Model] | Model,
mode: str = ACCESS_EXCLUSIVE,
using: str = DEFAULT_DB_ALIAS,
timeout: int | float | timedelta | _Unset | None = _unset,
side_effect: _ModelSideEffect = Return
) -> bool
Lock model(s).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*models
|
str | type[Model] | Model
|
Model paths (e.g. "app_label.Model") or classes to lock. |
()
|
mode
|
str
|
The lock mode. See the
Postgres docs
for a list of all modes and what they mean. There is a constant for each one in the
|
ACCESS_EXCLUSIVE
|
using
|
str
|
The database to use. |
DEFAULT_DB_ALIAS
|
timeout
|
int | float | timedelta | _Unset | None
|
Set a timeout when waiting for the lock. If 0, |
_unset
|
side_effect
|
_ModelSideEffect
|
Adjust the runtime behavior when using a timeout. |
Return
|
Returns:
| Type | Description |
|---|---|
bool
|
When using the default side effect, returns |
Raises:
| Type | Description |
|---|---|
OperationalError
|
If |
RuntimeError
|
When running code outside of a transaction. |
ValueError
|
When |
TypeError
|
When |
Source code in pglock/core.py
pglock.prioritize
¶
prioritize(
*,
interval: int | float | timedelta = 1,
periodic: bool = True,
using: str = DEFAULT_DB_ALIAS,
timeout: timedelta | int | float | _Unset | None = _unset,
side_effect: type[PrioritizeSideEffect] | PrioritizeSideEffect = Terminate
) -> Generator[None]
Kill any blocking locks.
pglock.prioritize has a periodic background worker thread that checks for blocking activity
and terminates it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
interval
|
int | float | timedelta
|
The interval (in seconds) at which the background worker runs. |
1
|
periodic
|
bool
|
If the worker should be ran periodically. If False, blocking locks are only killed once after the initial interval has happened. |
True
|
using
|
str
|
The database to use. |
DEFAULT_DB_ALIAS
|
timeout
|
timedelta | int | float | _Unset | None
|
The lock timeout to apply to the wrapped code. This is synonymous with using with
|
_unset
|
side_effect
|
type[PrioritizeSideEffect] | PrioritizeSideEffect
|
The side effect called by the background worker. Supplied a |
Terminate
|
Raises:
| Type | Description |
|---|---|
OperationalError
|
If |
Source code in pglock/core.py
pglock.timeout
¶
timeout(
timeout: timedelta | int | float | _Unset | None = _unset,
*,
using: str = DEFAULT_DB_ALIAS,
**timedelta_kwargs: Unpack[_TimeDeltaKwargs]
) -> Generator[None]
Set the lock timeout as a decorator or context manager.
A value of None will set an infinite lock timeout.
A value of less than a millisecond is not permitted.
Nested invocations will successfully apply and rollback the timeout to the previous value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
timeout
|
timedelta | int | float | _Unset | None
|
The number of seconds as an integer or float. Use a timedelta object to
precisely specify the timeout interval. Use |
_unset
|
using
|
str
|
The database to use. |
DEFAULT_DB_ALIAS
|
**timedelta_kwargs
|
Unpack[_TimeDeltaKwargs]
|
Keyword arguments to directly supply to
datetime.timedelta to create an interval. E.g.
|
{}
|
Raises:
| Type | Description |
|---|---|
OperationalError
|
When a timeout occurs |
TypeError
|
When the timeout interval is an incorrect type |
Source code in pglock/core.py
pglock.models
¶
pglock.models.BlockedPGLock
¶
Bases: BasePGLock
Models a blocked lock.
Uses Postgres's pg_blocking_pids function to unnest and
denormalize any blocking activity for a lock, returning both
the activity and blocking activity as a row.
Attributes:
| Name | Type | Description |
|---|---|---|
blocking_activity |
ForeignKey[PGActivity]
|
The activity that's blocking the lock. |
pglock.models.BlockedPGLockQuerySet
¶
Bases: PGLockQuerySet
The Queryset for the BlockedPGLock model. Inherits PGLockQuerySet
Source code in pglock/models.py
pglock.models.PGLock
¶
Bases: BasePGLock
Wraps Postgres's pg_locks view.
Attributes:
| Name | Type | Description |
|---|---|---|
type |
CharField
|
The type of lock. One of RELATION, EXTEND, FROZENID, PAGE, TUPLE, TRANSACTIONID, VIRTUALXID, SPECTOKEN, OBJECT, USERLOCK, or ADVISORY. |
activity |
ForeignKey[PGActivity]
|
The activity
from |
mode |
CharField
|
The mode of lock. One of ACCESS_SHARE, ROW_SHARE, ROW_EXCLUSIVE, SHARE_UPDATE_EXCLUSIVE, SHARE, SHARE_ROW_EXCLUSIVE, EXCLUSIVE, ACCESS_EXCLUSIVE. |
granted |
BooleanField
|
|
wait_start |
DateTimeField
|
When the lock started waiting. Only available in Postgres 14 and up. |
wait_duration |
DurationField
|
How long the lock has been blocked. Only available in Postgres 14 and up |
rel_kind |
CharField
|
The kind of relation being locked. One of TABLE, INDEX, SEQUENCE, TOAST, VIEW, MATERIALIZED_VIEW, COMPOSITE_TYPE, FOREIGN_TABLE, PARTITIONED_TABLE, or PARTITIONED_INDEX. |
rel_name |
CharField
|
The name of the relation. E.g. the table name
when |
pglock.models.PGLockQuerySet
¶
Bases: PGTableQuerySet
The Queryset for the PGLock model.
Source code in pglock/models.py
cancel_activity
¶
Cancel all PIDs in the activity field of the filtered queryset
config
¶
Use a config name from settings.PGLOCK_CONFIGS to apply filters.
Config overrides can be provided in the keyword arguments.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the config. Must be a key from |
required |
**overrides
|
Any
|
Any overrides to apply to the final config dictionary. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
The configuration |
Source code in pglock/models.py
on
¶
Set the relations to filter against.
Currently model names or classes are accepted.
terminate_activity
¶
Terminate all PIDs in the activity field of the filtered queryset