Remove deprecated Nginx configuration for stream.graff.estate and update package dependencies in session-server and client

- Deleted the Nginx configuration file for stream.graff.estate.
- Updated bun.lock files in both client and session-server to include new dependencies and version updates.
- Added 'tree-kill' dependency to session-server for improved process management.
- Refactored process termination logic in session-server to utilize 'tree-kill' for reliable process termination.
This commit is contained in:
2026-02-20 12:46:15 +05:00
parent 2a58a47077
commit 0243284da0
6 changed files with 68 additions and 139 deletions
+4
View File
@@ -1,10 +1,12 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "strem.graff.tech-session-server",
"dependencies": {
"got": "^14.4.9",
"tree-kill": "^1.2.2",
},
"devDependencies": {
"bun-types": "latest",
@@ -66,6 +68,8 @@
"responselike": ["responselike@3.0.0", "", { "dependencies": { "lowercase-keys": "^3.0.0" } }, "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg=="],
"tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
"undici-types": ["undici-types@7.14.0", "", {}, "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA=="],
+2 -1
View File
@@ -12,6 +12,7 @@
"start": "bun ./dist/index.js"
},
"dependencies": {
"got": "^14.4.9"
"got": "^14.4.9",
"tree-kill": "^1.2.2"
}
}
Binary file not shown.
+57 -86
View File
@@ -5,6 +5,8 @@ import { existsSync } from "fs";
import { createServer } from "net";
import { fileURLToPath } from "url";
import { dirname, join } from "path";
// @ts-ignore - tree-kill не имеет типов
import treeKill from "tree-kill";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
@@ -593,7 +595,7 @@ async function startApplication(session: SessionData): Promise<void> {
console.log(
`[${new Date().toISOString()}] 🛑 Остановка Cirrus для завершённой сессии ${sessionId}`
);
killProcessTree(cirrus.pid);
await killProcessTree(cirrus.pid);
activeCirrusProcesses.delete(sessionId);
}
}
@@ -620,7 +622,7 @@ async function startApplication(session: SessionData): Promise<void> {
if (mode === "stream") {
const cirrus = activeCirrusProcesses.get(sessionId);
if (cirrus && cirrus.pid) {
killProcessTree(cirrus.pid);
await killProcessTree(cirrus.pid);
activeCirrusProcesses.delete(sessionId);
}
}
@@ -672,7 +674,7 @@ async function startApplication(session: SessionData): Promise<void> {
if (mode === "stream") {
const cirrus = activeCirrusProcesses.get(sessionId);
if (cirrus && cirrus.pid) {
killProcessTree(cirrus.pid);
await killProcessTree(cirrus.pid);
activeCirrusProcesses.delete(sessionId);
}
}
@@ -685,74 +687,59 @@ async function startApplication(session: SessionData): Promise<void> {
}
/**
* Убить процесс и всё его дерево дочерних процессов (для Windows)
* Принудительное завершение без попыток мягкого закрытия
* Убить процесс и всё его дерево дочерних процессов
* Использует tree-kill для надёжного завершения всего дерева процессов
*/
function killProcessTree(pid: number): void {
try {
// Принудительное завершение с /F
function killProcessTree(pid: number): Promise<void> {
return new Promise((resolve) => {
console.log(
`[${new Date().toISOString()}] 🔄 Принудительное завершение процесса PID ${pid}...`
);
execSync(`taskkill /pid ${pid} /T /F`, {
stdio: "ignore",
timeout: 30000, // Таймаут 30 секунд
windowsHide: true,
killSignal: "SIGKILL",
treeKill(pid, "SIGKILL", (err: Error | undefined) => {
if (err) {
// Проверяем, действительно ли процесс всё ещё существует
const processExists = checkProcessExists(pid);
if (!processExists) {
console.log(
`[${new Date().toISOString()}] ✅ Процесс PID ${pid} уже завершён`
);
resolve();
return;
}
console.error(
`[${new Date().toISOString()}] ⚠️ Ошибка при завершении дерева процессов PID ${pid}:`,
err.message
);
// Fallback: попытка через taskkill
try {
console.log(
`[${new Date().toISOString()}] 🔄 Попытка завершения через taskkill для PID ${pid}`
);
execSync(`taskkill /pid ${pid} /T /F`, {
stdio: "ignore",
timeout: 10000,
windowsHide: true,
});
console.log(
`[${new Date().toISOString()}] ✅ Процесс PID ${pid} завершён через taskkill`
);
} catch (fallbackErr) {
console.error(
`[${new Date().toISOString()}] ❌ Не удалось завершить процесс PID ${pid}:`,
fallbackErr instanceof Error ? fallbackErr.message : fallbackErr
);
}
} else {
console.log(
`[${new Date().toISOString()}] ✅ Дерево процессов для PID ${pid} успешно завершено`
);
}
resolve();
});
console.log(
`[${new Date().toISOString()}] ✅ Дерево процессов для PID ${pid} успешно завершено принудительно`
);
} catch (error) {
// Проверяем, действительно ли процесс всё ещё существует
const processExists = checkProcessExists(pid);
if (!processExists) {
console.log(
`[${new Date().toISOString()}] ✅ Процесс PID ${pid} уже завершён`
);
return;
}
console.error(
`[${new Date().toISOString()}] ⚠️ Ошибка при завершении дерева процессов PID ${pid}:`,
error instanceof Error ? error.message : error
);
// Попытка принудительного завершения через PowerShell как последний вариант
try {
console.log(
`[${new Date().toISOString()}] 🔄 Попытка принудительного завершения через PowerShell для PID ${pid}`
);
// Используем агрессивный PowerShell скрипт для принудительного завершения
const psScript = `
$proc = Get-Process -Id ${pid} -ErrorAction SilentlyContinue;
if ($proc) {
# Принудительно завершаем процесс и все дочерние
Stop-Process -Id ${pid} -Force -ErrorAction SilentlyContinue;
# Завершаем все дочерние процессы
Get-Process | Where-Object { $_.Parent.Id -eq ${pid} } | Stop-Process -Force -ErrorAction SilentlyContinue;
}
`.replace(/\n/g, " ");
execSync(
`powershell -Command "${psScript}"`,
{
stdio: "ignore",
timeout: 15000,
windowsHide: true,
}
);
console.log(
`[${new Date().toISOString()}] ✅ Процесс PID ${pid} завершён через PowerShell`
);
} catch (psError) {
console.error(
`[${new Date().toISOString()}] ❌ Не удалось завершить процесс PID ${pid} даже через PowerShell:`,
psError instanceof Error ? psError.message : psError
);
}
}
});
}
/**
@@ -822,16 +809,7 @@ async function stopApplication(session: SessionData): Promise<void> {
// Останавливаем UE приложение
const pidToKill = appPid || appProcess?.pid;
if (pidToKill) {
killPromises.push(
new Promise<void>((resolve) => {
// Запускаем killProcessTree в отдельном потоке через setTimeout
// чтобы не блокировать основной поток
setTimeout(() => {
killProcessTree(pidToKill);
resolve();
}, 0);
})
);
killPromises.push(killProcessTree(pidToKill));
} else {
console.warn(
`[${new Date().toISOString()}] ⚠️ Не удалось получить PID приложения для сессии ${sessionId}`
@@ -842,14 +820,7 @@ async function stopApplication(session: SessionData): Promise<void> {
if (mode === "stream") {
const cirrusPidToKill = cirrusPid || cirrusProcess?.pid;
if (cirrusPidToKill) {
killPromises.push(
new Promise<void>((resolve) => {
setTimeout(() => {
killProcessTree(cirrusPidToKill);
resolve();
}, 0);
})
);
killPromises.push(killProcessTree(cirrusPidToKill));
} else {
console.warn(
`[${new Date().toISOString()}] ⚠️ Не удалось получить PID Cirrus для сессии ${sessionId}`
@@ -1011,14 +982,14 @@ async function checkSessions(): Promise<void> {
`[${new Date().toISOString()}] ⚠️ Найден процесс для неактивной сессии ${sessionId}, остановка`
);
if (process.pid) {
killProcessTree(process.pid);
await killProcessTree(process.pid);
}
activeProcesses.delete(sessionId);
// Также останавливаем Cirrus если есть
const cirrusProcess = activeCirrusProcesses.get(sessionId);
if (cirrusProcess && cirrusProcess.pid) {
killProcessTree(cirrusProcess.pid);
await killProcessTree(cirrusProcess.pid);
activeCirrusProcesses.delete(sessionId);
}
}