Refactor server session selection logic to incorporate maxApps limits and improve error handling
- Enhanced selectAvailableServer function to consider maxApps when selecting available servers for both stream and local sessions. - Added dynamic import of serverService to avoid circular dependencies. - Improved error messages for unavailable servers based on session type. - Updated startApplication function to check session status before launching and handle session termination more gracefully. - Ensured proper session management by processing ending sessions before starting new ones.
This commit is contained in:
@@ -226,19 +226,57 @@ export const serverSessionService = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Выбрать доступный сервер
|
||||
* Выбрать доступный сервер с учетом maxApps
|
||||
*/
|
||||
async selectAvailableServer(mode: SessionMode): Promise<string | undefined> {
|
||||
// Импортируем serverService динамически чтобы избежать циклических зависимостей
|
||||
const { serverService } = await import("../server");
|
||||
|
||||
if (mode === "stream") {
|
||||
const server = await db.query.servers.findFirst({
|
||||
where: and(eq(servers.type, "stream"), eq(servers.tier, "prod")),
|
||||
});
|
||||
return server?.id;
|
||||
// Для stream-сессий используем логику из assignServer
|
||||
const tier = undefined; // Для selectAvailableServer используем prod по умолчанию
|
||||
const availableServers = await serverService.findAvailableStreamServers(tier);
|
||||
|
||||
if (availableServers.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Проверяем количество активных сессий на каждом сервере
|
||||
for (const server of availableServers) {
|
||||
const maxApps = server.maxApps ?? 1;
|
||||
const activeSessions = await this.findByServerId(server.id, {});
|
||||
const activeCount = activeSessions.filter(
|
||||
(s) => s.status === "starting" || s.status === "started"
|
||||
).length;
|
||||
|
||||
if (activeCount < maxApps) {
|
||||
return server.id;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
} else {
|
||||
const server = await db.query.servers.findFirst({
|
||||
where: eq(servers.type, "local"),
|
||||
});
|
||||
return server?.id;
|
||||
// Для local-сессий проверяем maxApps
|
||||
const availableLocalServers = await serverService.findAvailableLocalServers();
|
||||
|
||||
if (availableLocalServers.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Проверяем количество активных сессий на каждом сервере
|
||||
for (const server of availableLocalServers) {
|
||||
const maxApps = server.maxApps ?? 1;
|
||||
const activeSessions = await this.findByServerId(server.id, {});
|
||||
const activeCount = activeSessions.filter(
|
||||
(s) => s.status === "starting" || s.status === "started"
|
||||
).length;
|
||||
|
||||
if (activeCount < maxApps) {
|
||||
return server.id;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -283,13 +321,53 @@ export const serverSessionService = {
|
||||
);
|
||||
}
|
||||
|
||||
// Для local-сессий выбираем сервер сразу
|
||||
// Для stream-сессий сервер будет назначен динамически при запуске
|
||||
// Проверить доступность серверов перед созданием сессии
|
||||
// Импортируем serverService динамически чтобы избежать циклических зависимостей
|
||||
const { serverService } = await import("../server");
|
||||
|
||||
let selectedServerId = serverId;
|
||||
if (mode === "local" && !selectedServerId) {
|
||||
selectedServerId = await this.selectAvailableServer(mode);
|
||||
|
||||
if (mode === "local") {
|
||||
// Для local-сессий выбираем сервер сразу с проверкой maxApps
|
||||
if (!selectedServerId) {
|
||||
throw new Error(`Нет доступных серверов для режима ${mode}`);
|
||||
selectedServerId = await this.selectAvailableServer(mode);
|
||||
if (!selectedServerId) {
|
||||
throw new Error(
|
||||
`Нет доступных local серверов (все серверы достигли лимита активных сессий)`
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Для stream-сессий проверяем наличие доступных серверов перед созданием сессии
|
||||
const preferredTier = tier || (userId ? undefined : "demo");
|
||||
const availableServers = await serverService.findAvailableStreamServers(preferredTier);
|
||||
|
||||
if (availableServers.length === 0) {
|
||||
const serverType = preferredTier === "demo" ? "demo " : "";
|
||||
throw new Error(
|
||||
`Нет доступных ${serverType}stream серверов (проверьте, что stream серверы зарегистрированы)`
|
||||
);
|
||||
}
|
||||
|
||||
// Проверяем, есть ли хотя бы один сервер с доступным местом
|
||||
let hasAvailableServer = false;
|
||||
for (const server of availableServers) {
|
||||
const maxApps = server.maxApps ?? 1;
|
||||
const activeSessions = await this.findByServerId(server.id, {});
|
||||
const activeCount = activeSessions.filter(
|
||||
(s) => s.status === "starting" || s.status === "started"
|
||||
).length;
|
||||
|
||||
if (activeCount < maxApps) {
|
||||
hasAvailableServer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAvailableServer) {
|
||||
throw new Error(
|
||||
`Нет доступных stream серверов (все серверы достигли лимита активных сессий)`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user