66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
/**
|
|
* AI 어시스턴트 서비스를 자식 프로세스로 기동
|
|
* - backend-node 서버 기동 시 함께 띄우고, 종료 시 함께 종료 (한 번에 킬)
|
|
*/
|
|
import path from "path";
|
|
import { spawn, ChildProcess } from "child_process";
|
|
import { logger } from "./logger";
|
|
|
|
const AI_PORT = process.env.AI_ASSISTANT_SERVICE_PORT || "3100";
|
|
|
|
let aiAssistantProcess: ChildProcess | null = null;
|
|
|
|
/** ERP-node/ai-assistant 경로 (backend-node 기준 상대) */
|
|
function getAiAssistantDir(): string {
|
|
return path.resolve(process.cwd(), "..", "ai-assistant");
|
|
}
|
|
|
|
/**
|
|
* AI 어시스턴트 서비스 기동 (있으면 띄움, 실패해도 backend는 계속 동작)
|
|
*/
|
|
export function startAiAssistant(): void {
|
|
const aiDir = getAiAssistantDir();
|
|
const appPath = path.join(aiDir, "src", "app.js");
|
|
|
|
try {
|
|
const fs = require("fs");
|
|
if (!fs.existsSync(appPath)) {
|
|
logger.info(`⏭️ AI 어시스턴트 스킵 (경로 없음: ${appPath})`);
|
|
return;
|
|
}
|
|
} catch {
|
|
return;
|
|
}
|
|
|
|
aiAssistantProcess = spawn("node", ["src/app.js"], {
|
|
cwd: aiDir,
|
|
stdio: "inherit",
|
|
env: { ...process.env, PORT: AI_PORT },
|
|
shell: true, // Windows에서 node 경로 인식
|
|
});
|
|
|
|
aiAssistantProcess.on("error", (err) => {
|
|
logger.warn(`⚠️ AI 어시스턴트 프로세스 에러: ${err.message}`);
|
|
});
|
|
|
|
aiAssistantProcess.on("exit", (code, signal) => {
|
|
aiAssistantProcess = null;
|
|
if (code != null && code !== 0) {
|
|
logger.warn(`⚠️ AI 어시스턴트 종료 (code=${code}, signal=${signal})`);
|
|
}
|
|
});
|
|
|
|
logger.info(`🤖 AI 어시스턴트 서비스 기동 (포트 ${AI_PORT}, cwd: ${aiDir})`);
|
|
}
|
|
|
|
/**
|
|
* AI 어시스턴트 프로세스 종료 (SIGTERM/SIGINT 시 호출)
|
|
*/
|
|
export function stopAiAssistant(): void {
|
|
if (aiAssistantProcess && aiAssistantProcess.kill) {
|
|
aiAssistantProcess.kill("SIGTERM");
|
|
aiAssistantProcess = null;
|
|
logger.info("🤖 AI 어시스턴트 프로세스 종료");
|
|
}
|
|
}
|