PamGram/utils/models/lock.py
洛水居室 233e7ab58d
♻️ PaiGram V4
Co-authored-by: luoshuijs <luoshuijs@outlook.com>
Co-authored-by: Karako <karakohear@gmail.com>
Co-authored-by: xtaodada <xtao@xtaolink.cn>
2023-03-14 09:27:22 +08:00

51 lines
1.4 KiB
Python

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)