将通讯录刷新与头像缓存同步改为异步处理

This commit is contained in:
liuwei
2026-04-27 09:30:21 +08:00
parent a3e20db554
commit 4dbf390c65
3 changed files with 138 additions and 52 deletions

View File

@@ -18,6 +18,8 @@ message_thread_pool = ThreadPoolExecutor(max_workers=10, thread_name_prefix="mes
# 创建共享的事件循环
shared_loop = None
loop_lock = threading.Lock()
contacts_refresh_lock = threading.Lock()
contacts_refresh_running = False
_EMOJI_MD5_RE = re.compile(r'md5\s*=\s*[\"\']([0-9a-fA-F]{16,64})[\"\']', re.IGNORECASE)
_EMOJI_TOTALLEN_RE = re.compile(r'(?:totallen|total_len|len)\s*=\s*[\"\'](\d+)[\"\']', re.IGNORECASE)
@@ -70,6 +72,30 @@ def run_member_context_refresh_in_thread(func, *args, **kwargs):
message_thread_pool.submit(run)
def run_contacts_refresh_in_thread(server):
"""将通讯录刷新放到后台线程执行,避免阻塞后台请求与系统主链路。"""
global contacts_refresh_running
with contacts_refresh_lock:
if contacts_refresh_running:
return False
contacts_refresh_running = True
def run():
global contacts_refresh_running
try:
logger.info("通讯录后台刷新任务开始执行")
asyncio.run(server.robot.refresh_contacts_db())
logger.info("通讯录后台刷新任务执行完成")
except Exception as e:
logger.error(f"通讯录后台刷新任务执行失败: {e}")
finally:
with contacts_refresh_lock:
contacts_refresh_running = False
message_thread_pool.submit(run)
return True
def _safe_text(value):
return "" if value is None else str(value)
@@ -616,12 +642,14 @@ def api_contacts_update():
"""更新通讯录信息API"""
try:
server = current_app.dashboard_server
# 假设 contact_manager 有 update_contacts 方法用于同步通讯录
result = asyncio.run(server.robot.refresh_contacts_db())
if result:
return jsonify({"success": True, "message": "通讯录更新成功"})
else:
return jsonify({"success": False, "message": "通讯录更新失败"}), 500
# 通讯录刷新改成后台异步任务:
# 1. 远端拉联系人详情 + 群成员详情 + 头像缓存同步都可能较慢;
# 2. 若接口同步等待,会直接卡住后台请求线程,影响整体使用体验;
# 3. 这里提交任务后立刻返回,等后台线程慢慢完成刷新。
submitted = run_contacts_refresh_in_thread(server)
if submitted:
return jsonify({"success": True, "message": "通讯录更新任务已提交,请稍后手动刷新查看结果"})
return jsonify({"success": True, "message": "通讯录更新任务已在执行中,请稍后再刷新"})
except Exception as e:
logger.error(f"更新通讯录失败: {e}")
return jsonify({"success": False, "message": f"更新通讯录失败: {str(e)}"}), 500

View File

@@ -964,7 +964,11 @@
},
updateContacts() {
this.$message.info('正在更新通讯录...');
axios.post('/contacts/api/update').then(res => { if (res.data.success) { this.$message.success('通讯录更新成功!'); this.refreshContacts(); } else { this.$message.error(res.data.message || '通讯录更新失败'); } }).catch(() => { this.$message.error('通讯录更新请求失败'); });
// 通讯录刷新已改成后台异步任务:
// 1. 点击后只提交任务,不再阻塞等待全部联系人与头像同步完成;
// 2. 因为结果是异步落库,这里不再立刻 refreshContacts避免用户误以为没生效
// 3. 任务完成后用户手动点“刷新数据”即可看到最新结果。
axios.post('/contacts/api/update').then(res => { if (res.data.success) { this.$message.success(res.data.message || '通讯录更新任务已提交'); } else { this.$message.error(res.data.message || '通讯录更新失败'); } }).catch(() => { this.$message.error('通讯录更新请求失败'); });
},
refreshContacts() { this.loadContactsData(); this.$message.success('联系人数据已刷新'); },
handleTabClick() { this.currentPage = 1; },