use queue to allow send vscode_ws when it is none

This commit is contained in:
Cai
2025-11-03 13:51:15 +08:00
parent 6c38e9067d
commit ce88ae645e
8 changed files with 220 additions and 413 deletions

View File

@@ -14,6 +14,8 @@ from dataclasses import dataclass, field
from typing import Dict, Optional
import subprocess
import threading
from collections import deque
from eventlet.semaphore import Semaphore
from apps.utils import *
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
@@ -47,7 +49,9 @@ class ChatManager:
self.function_manager = FunctionManager()
self.bb = None
self.chat_historys = None
pass
self.vscode_ws = None
self._vscode_queue = deque()
self._lock = Semaphore(1)
def init(self,user_uuid,ase_client,raw_markdown,raw_markdown_prompts,raw_score_prompts,material_id,chapter_name, lesson_name, max_iter = 5, app=None, socketio=None):
@@ -65,8 +69,41 @@ class ChatManager:
self.bb = None
self.chat_historys = []
def send_to_vscode(self, event: str, data: dict, room: str = None, namespace: str = '/vscode'):
"""统一发送入口:未就绪则入队,就绪则直接 emit。"""
if room is None:
room = self.user_uuid
with self._lock:
if self.vscode_ws is not None:
# 已就绪,直接发
self.vscode_ws.emit(event, data, room=room, namespace=namespace)
else:
# 未就绪,入队缓存
self._vscode_queue.append((event, data, room, namespace))
def set_vscode_ws(self, ws):
"""在 on_login 时调用,注册 websocket 并立刻 flush 队列。"""
with self._lock:
self.vscode_ws = ws
self._flush_vscode_queue_locked()
def _flush_vscode_queue_locked(self):
"""发送缓存的消息(需在持锁状态下调用)。"""
while self._vscode_queue:
event, data, room, namespace = self._vscode_queue.popleft()
# 这里假设 ws 仍然有效;如果发送失败可以考虑 try/except 并回滚入队
self.vscode_ws.emit(event, data, room=room, namespace=namespace)
def mark_vscode_disconnected(self):
"""可在 on_disconnect 里调用,标记断开(之后会继续缓存)。"""
with self._lock:
self.vscode_ws = None
self._vscode_queue.clear()
def disconnect(self, uuid):
try:
self.mark_vscode_disconnected()
self.stop(uuid)
self.ase_client.disconnect()
except Exception as e:
@@ -77,7 +114,7 @@ class ChatManager:
nowchapter_content = self.chapter_chain[self.chapter_chain_now].chapter
code_texts = extract_code_blocks(nowchapter_content)
for code_text in code_texts:
self.vscode_ws.emit('code-file', {'type':'create', 'data':code_text, 'chapter_title': self.chapter_chain[self.chapter_chain_now].title}, room=self.user_uuid ,namespace='/vscode')
self.send_to_vscode('code-file', {'type':'create', 'data':code_text, 'chapter_title': self.chapter_chain[self.chapter_chain_now].title}, room=self.user_uuid ,namespace='/vscode')
def next_chapter(self):