-
Notifications
You must be signed in to change notification settings - Fork 2
为AuthIdManager提供定期清理和线程安全特性 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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()) | ||
| 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] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这个类主要是提供了一个用户ID集中缓存的地方,资源清理是为了自动释放长时间未使用的uid节省内存,所以在一个uid被访问、检测到过期时,正确的行为应该是更新uid的过期时间而非删除uid返回None。前者是无意义的,且会导致一次额外的教务网访问,后者则可以正确清理不频繁访问的uid——频繁访问的uid会被不断更新时间戳而延后清理
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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] | ||
There was a problem hiding this comment.
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,改进了更好)