Coverage for slidge / util / lock.py: 100%
27 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-02-15 09:02 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-02-15 09:02 +0000
1import asyncio
2import logging
3from collections.abc import AsyncIterator, Hashable
4from contextlib import asynccontextmanager
5from typing import Any
8class NamedLockMixin:
9 def __init__(self, *a: Any, **k: Any) -> None:
10 super().__init__(*a, **k)
11 self.__locks = dict[Hashable, asyncio.Lock]()
13 @asynccontextmanager
14 async def lock(self, id_: Hashable) -> AsyncIterator[None]:
15 log.trace("getting %s", id_) # type:ignore
16 locks = self.__locks
17 if not locks.get(id_):
18 locks[id_] = asyncio.Lock()
19 try:
20 async with locks[id_]:
21 log.trace("acquired %s", id_) # type:ignore
22 yield
23 finally:
24 log.trace("releasing %s", id_) # type:ignore
25 waiters = locks[id_]._waiters
26 if not waiters:
27 del locks[id_]
28 log.trace("erasing %s", id_) # type:ignore
30 def get_lock(self, id_: Hashable) -> asyncio.Lock | None:
31 return self.__locks.get(id_)
34log = logging.getLogger(__name__)