PamGram/utils/models/lock.py

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"] = {}
_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
def __enter__(self) -> None:
# 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)