This commit is contained in:
2025-10-10 19:23:53 +05:00
parent b5dc953d6b
commit 7bb50a4ee5
13 changed files with 961 additions and 79 deletions
+47 -22
View File
@@ -377,13 +377,15 @@ async function startApplication(session: SessionData): Promise<void> {
try {
console.log(
`[${new Date().toISOString()}] 🚀 Запуск приложения "${app.name}" для сессии ${sessionId} (активных процессов: ${activeProcesses.size})`
`[${new Date().toISOString()}] 🚀 Запуск приложения "${
app.name
}" для сессии ${sessionId} (активных процессов: ${activeProcesses.size})`
);
// Формируем путь к exe файлу приложения
// Путь: C:\apps\{appName}\{appName}.exe
const appPath = `C:\\apps\\${app.name}\\${app.name}.exe`;
console.log(
`[${new Date().toISOString()}] 📂 Путь к приложению: ${appPath}`
);
@@ -397,12 +399,23 @@ async function startApplication(session: SessionData): Promise<void> {
// Запускаем exe приложение
// Используем 'pipe' для stderr чтобы видеть ошибки, но 'ignore' для stdin/stdout
const appProcess = spawn(appPath, [], {
detached: false,
stdio: ["ignore", "ignore", "pipe"], // stdin: ignore, stdout: ignore, stderr: pipe
windowsHide: true, // Скрывать окно консоли на Windows
cwd: `C:\\apps\\${app.name}`, // Устанавливаем рабочую директорию приложения
});
const appProcess = spawn(
appPath,
[
"-PixelStreamingURL=ws://127.0.0.1:8888",
"-ForceRes",
"-ResX=1920",
"-ResY=1080",
"-Unattended",
"-RenderOffScreen",
],
{
detached: false,
stdio: ["ignore", "ignore", "pipe"], // stdin: ignore, stdout: ignore, stderr: pipe
windowsHide: true, // Скрывать окно консоли на Windows
cwd: `C:\\apps\\${app.name}`, // Устанавливаем рабочую директорию приложения
}
);
const appPid = appProcess.pid;
@@ -417,7 +430,9 @@ async function startApplication(session: SessionData): Promise<void> {
if (appProcess.stderr) {
appProcess.stderr.on("data", (data) => {
console.error(
`[${new Date().toISOString()}] 🔴 STDERR [${sessionId}]: ${data.toString().trim()}`
`[${new Date().toISOString()}] 🔴 STDERR [${sessionId}]: ${data
.toString()
.trim()}`
);
});
}
@@ -425,15 +440,17 @@ async function startApplication(session: SessionData): Promise<void> {
// Обработка завершения процесса
appProcess.on("exit", async (code, signal) => {
console.log(
`[${new Date().toISOString()}] 🛑 Приложение для сессии ${sessionId} завершилось с кодом ${code}${signal ? ` (сигнал: ${signal})` : ""}`
`[${new Date().toISOString()}] 🛑 Приложение для сессии ${sessionId} завершилось с кодом ${code}${
signal ? ` (сигнал: ${signal})` : ""
}`
);
if (code !== 0 && code !== null) {
console.error(
`[${new Date().toISOString()}] ⚠️ Приложение завершилось с ошибкой! Код выхода: ${code}`
);
}
activeProcesses.delete(sessionId);
// Обновить статус на "ended"
@@ -446,7 +463,7 @@ async function startApplication(session: SessionData): Promise<void> {
error
);
activeProcesses.delete(sessionId);
// Обновить статус на "ended" в случае ошибки
await updateSessionStatus(sessionId, "ended");
});
@@ -455,7 +472,9 @@ async function startApplication(session: SessionData): Promise<void> {
await updateSessionStatus(sessionId, "started", appPid);
console.log(
`[${new Date().toISOString()}] ✅ Приложение запущено с PID ${appPid} (всего активных: ${activeProcesses.size})`
`[${new Date().toISOString()}] ✅ Приложение запущено с PID ${appPid} (всего активных: ${
activeProcesses.size
})`
);
} catch (error) {
console.error(
@@ -518,7 +537,9 @@ async function stopApplication(session: SessionData): Promise<void> {
try {
console.log(
`[${new Date().toISOString()}] 🛑 Остановка приложения для сессии ${sessionId} (PID: ${appPid || appProcess?.pid || "неизвестен"})`
`[${new Date().toISOString()}] 🛑 Остановка приложения для сессии ${sessionId} (PID: ${
appPid || appProcess?.pid || "неизвестен"
})`
);
// Используем PID из базы данных если он есть, иначе из процесса
@@ -576,31 +597,35 @@ async function checkSessions(): Promise<void> {
const startAt = new Date(s.startAt);
return startAt <= now;
});
// Логировать запланированные сессии, которые ещё не пришло время запускать
// Логируем не чаще раза в 10 секунд для каждой сессии, чтобы не спамить логами
const scheduledSessions = allStartingSessions.filter((s) => {
const startAt = new Date(s.startAt);
return startAt > now;
});
if (scheduledSessions.length > 0) {
for (const session of scheduledSessions) {
const lastLogTime = lastScheduledLogTime.get(session.id) || 0;
const timeSinceLastLog = now.getTime() - lastLogTime;
// Логируем только если прошло больше 10 секунд с последнего лога
if (timeSinceLastLog > 10000) {
const startAt = new Date(session.startAt);
const timeUntilStart = Math.round((startAt.getTime() - now.getTime()) / 1000);
const timeUntilStart = Math.round(
(startAt.getTime() - now.getTime()) / 1000
);
console.log(
`[${new Date().toISOString()}] ⏰ Сессия ${session.id} (${session.app.name}) запланирована через ${timeUntilStart} сек`
`[${new Date().toISOString()}] ⏰ Сессия ${session.id} (${
session.app.name
}) запланирована через ${timeUntilStart} сек`
);
lastScheduledLogTime.set(session.id, now.getTime());
}
}
}
// Очистить карту логирования для сессий, которые больше не запланированы
const scheduledSessionIds = new Set(scheduledSessions.map((s) => s.id));
for (const sessionId of lastScheduledLogTime.keys()) {
@@ -608,7 +633,7 @@ async function checkSessions(): Promise<void> {
lastScheduledLogTime.delete(sessionId);
}
}
for (const session of startingSessions) {
await startApplication(session);
}