feat: refresh shared chat and server workflows
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
||||
} from './notification-message-service.js';
|
||||
import { extractChatMessageParts, type ChatMessagePart } from './chat-message-parts.js';
|
||||
import { resolveMainProjectRoot } from './main-project-root-service.js';
|
||||
import { isRuntimeDraining, trackWebSocketConnectionClosed, trackWebSocketConnectionOpened } from './runtime-drain-service.js';
|
||||
import {
|
||||
findLatestPlanItem,
|
||||
findPlanItemByPreviewUrl,
|
||||
@@ -322,6 +323,14 @@ export function getActiveChatService() {
|
||||
return activeChatService;
|
||||
}
|
||||
|
||||
type ChatServiceRuntimeSnapshot = {
|
||||
activeRequestCount: number;
|
||||
queuedRequestCount: number;
|
||||
connectedSessionCount: number;
|
||||
activeSocketCount: number;
|
||||
canAcceptNewRequests: boolean;
|
||||
};
|
||||
|
||||
function getSessionSocketReadyState(session: ChatSessionState) {
|
||||
for (const socket of session.sockets) {
|
||||
if (socket.readyState === SOCKET_READY_STATE_OPEN) {
|
||||
@@ -4362,6 +4371,38 @@ export class ChatService {
|
||||
};
|
||||
}
|
||||
|
||||
getRuntimeSnapshot(): ChatServiceRuntimeSnapshot {
|
||||
let activeRequestCount = 0;
|
||||
let queuedRequestCount = 0;
|
||||
let activeSocketCount = 0;
|
||||
let connectedSessionCount = 0;
|
||||
|
||||
for (const session of this.sessions.values()) {
|
||||
activeRequestCount += session.activeRequestCount;
|
||||
queuedRequestCount += session.queue.length;
|
||||
|
||||
let sessionHasOpenSocket = false;
|
||||
for (const socket of session.sockets) {
|
||||
if (socket.readyState === SOCKET_READY_STATE_OPEN) {
|
||||
activeSocketCount += 1;
|
||||
sessionHasOpenSocket = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (sessionHasOpenSocket) {
|
||||
connectedSessionCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
activeRequestCount,
|
||||
queuedRequestCount,
|
||||
connectedSessionCount,
|
||||
activeSocketCount,
|
||||
canAcceptNewRequests: !isRuntimeDraining(),
|
||||
};
|
||||
}
|
||||
|
||||
close() {
|
||||
activeRuntimeController = null;
|
||||
if (activeChatService === this) {
|
||||
@@ -5267,6 +5308,7 @@ export class ChatService {
|
||||
session.sockets.add(socket);
|
||||
session.lastSeenAt = Date.now();
|
||||
this.clientStates.set(socket, session);
|
||||
trackWebSocketConnectionOpened();
|
||||
|
||||
socket.on('message', (raw: RawData) => {
|
||||
this.handleMessage(socket, raw);
|
||||
@@ -5275,12 +5317,14 @@ export class ChatService {
|
||||
socket.on('close', () => {
|
||||
this.clientStates.delete(socket);
|
||||
session.sockets.delete(socket);
|
||||
trackWebSocketConnectionClosed();
|
||||
});
|
||||
|
||||
socket.on('error', (error: Error) => {
|
||||
this.logger.error(error, 'chat websocket error');
|
||||
this.clientStates.delete(socket);
|
||||
session.sockets.delete(socket);
|
||||
trackWebSocketConnectionClosed();
|
||||
});
|
||||
|
||||
await this.initializeSession(session);
|
||||
@@ -5640,6 +5684,16 @@ export class ChatService {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isRuntimeDraining()) {
|
||||
this.sendToSession(state, {
|
||||
type: 'chat:error',
|
||||
payload: {
|
||||
message: '현재 서버가 배포 전환 중이라 새 AI 요청을 받지 않습니다. 잠시 후 다시 시도해 주세요.',
|
||||
},
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
if (contextOverride) {
|
||||
const mergedContext = {
|
||||
...(state.context ?? {
|
||||
|
||||
Reference in New Issue
Block a user