PaiGram/utils/models/lock.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

51 lines
1.4 KiB
Python
Raw Normal View History

import asyncio
from asyncio import Task
from multiprocessing import RLock as Lock
from typing import Any, Dict, TYPE_CHECKING
if TYPE_CHECKING:
from multiprocessing.synchronize import RLock as LockType
__all__ = ("HashLock",)
_lock: "LockType" = Lock()
_locks: Dict[int, "LockType"] = {}
2023-11-06 08:10:47 +00:00
_clean_lock_task_map: Dict[int, Task] = {}
async def delete_lock(target: int) -> None:
await asyncio.sleep(3)
with _lock:
del _locks[target]
del _clean_lock_task_map[target] # pylint: disable=E0602
class HashLock:
"""可以根据 hash 来获取锁的类"""
target: int
@property
def lock(self) -> "LockType":
# noinspection PyTypeChecker
with _lock:
if self.target not in _locks:
# noinspection PyTypeChecker
_locks[self.target] = Lock()
else:
_clean_lock_task_map[self.target].cancel()
_clean_lock_task_map.update({self.target: asyncio.create_task(delete_lock(self.target))})
return _locks[self.target]
def __init__(self, target: Any) -> None:
if not isinstance(target, int):
target = hash(target)
self.target = target
2023-11-06 08:10:47 +00:00
def __enter__(self) -> bool:
# noinspection PyTypeChecker
return self.lock.__enter__()
def __exit__(self, exc_type=None, exc_val=None, exc_tb=None):
return self.lock.__exit__(exc_type, exc_val, exc_tb)