## ADDED Requirements ### Requirement: 笔记列表缓存读写受互斥锁保护 模块级全局变量 `_cached_proactive_entries` 和 `_cached_my_note_entries` 的所有读写操作 SHALL 在 `threading.RLock` 的保护下执行,以防止 Gradio 回调并发调用时产生数据竞态。 #### Scenario: 并发刷新时缓存更新不出现竞态 - **WHEN** 两个 Gradio 回调线程同时调用 `_fetch_and_cache()` - **THEN** 最终缓存状态为其中一次完整写入的结果,不出现部分更新或列表长度异常 #### Scenario: 读取缓存时不被并发写入中断 - **WHEN** `_pick_from_cache()` 正在迭代缓存列表时,另一线程触发缓存更新 - **THEN** 迭代过程不抛出 `RuntimeError: list changed size during iteration` ### Requirement: 缓存操作封装为受保护的工具函数 模块 SHALL 提供 `_set_cache(name, entries)` 和 `_get_cache(name)` 两个内部函数,统一管理缓存读写,不在业务函数中直接赋值全局列表。 #### Scenario: 缓存写入通过统一接口 - **WHEN** 任意函数需要更新笔记缓存 - **THEN** 必须调用 `_set_cache(name, entries)` 而非直接赋值 `_cached_*` 变量