Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions utils/AuthIdManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,44 @@ class AuthIdManager(metaclass=Singleton):
提供了用户唯一标识生成、标识缓存的管理类
"""
_uids: Dict[str, bytes] = {}
_ttl: float = 86400 # Time-to-live for cache

def __init__(self):
"""
设置锁机制和启动一个后台线程来定期清理过期的缓存条目
"""
self._lock = threading.Lock()
self._cleanup_thread = threading.Thread(target=self._cleanup, daemon=True)
self._cleanup_thread.start()

def add_uid(self, auth: str, sid: str, name: str) -> bytes:
if sid in self._uids.keys():
return self.get_uid(sid)
with self._lock:
if sid in self._uids.keys():
return self.get_uid(sid)

sh = sha3_256()
sh.update((auth + name + sid).encode('utf-8'))
result = sh.digest()
self._uids[sid] = result
return result
sh = sha3_256()
sh.update((auth + name + sid).encode('utf-8'))
result = sh.digest()
self._uids[sid] = (result,time.time())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果从节省内存的角度考虑,给每一项多存一个float值带来的内存增加是否会超过定时清理节省下来的内存?介于ttl一般是一个比较大的整数,在我们已经认为几百上千个string带来的内存占用应该被节省的情况下,将time.time()返回值直接转为整数是否更符合我们修改的预期?(这里不进行更改也可以通过review,改进了更好)

return result

def get_uid(self, sid: str) -> bytes:
return self._uids.get(sid)
with self._lock:
entry = self._uids.get(sid)
if entry:
uid,timestamp = entry
if time.time() - timestamp < self._ttl:
return uid
else:
del self._uids[sid]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个类主要是提供了一个用户ID集中缓存的地方,资源清理是为了自动释放长时间未使用的uid节省内存,所以在一个uid被访问、检测到过期时,正确的行为应该是更新uid的过期时间而非删除uid返回None。前者是无意义的,且会导致一次额外的教务网访问,后者则可以正确清理不频繁访问的uid——频繁访问的uid会被不断更新时间戳而延后清理

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

而且更新字典的时候也没有加锁……


return None

def _cleanup(self):
while True:
time.sleep(self._ttl)
with self._lock:
now = time.time()
expired_keys = [sid for sid,(uid,timestamp) in self._uids.items() if now - timestamp >= self._ttl]
for key in expired_keys:
del self._uids[key]