upd
This commit is contained in:
+140
-13
@@ -2,14 +2,13 @@ import "dotenv/config";
|
||||
import connectDB from "./config/db";
|
||||
import express, { json } from "express";
|
||||
import cors from "cors";
|
||||
import os from "os";
|
||||
import util from "util";
|
||||
import { exec, execFile } from "child_process";
|
||||
import treeKill from "tree-kill";
|
||||
import SessionServer from "./models/SessionServer";
|
||||
import ActiveSession from "./models/ActiveSession";
|
||||
import got from "got-cjs";
|
||||
import Build from "./models/Build";
|
||||
import { AccessToken } from "livekit-server-sdk";
|
||||
import cron from "node-cron";
|
||||
import { differenceInMinutes } from "date-fns";
|
||||
|
||||
connectDB();
|
||||
|
||||
@@ -25,14 +24,31 @@ async function getBuild(name: string) {
|
||||
return build;
|
||||
}
|
||||
|
||||
app.get("/active_sessions", async (req, res) => {
|
||||
const activeSessions = await ActiveSession.find();
|
||||
|
||||
res.json(activeSessions);
|
||||
});
|
||||
|
||||
app.get("/start", async (req, res) => {
|
||||
const location = req.query.location as string;
|
||||
const buildName = req.query.build as string;
|
||||
const ownerIp = req.headers["x-real-ip"];
|
||||
let type = req.query.type as string;
|
||||
|
||||
console.log("location", location);
|
||||
console.log("buildName", buildName);
|
||||
|
||||
if (!location || !buildName) {
|
||||
return res.json({ error: 1 });
|
||||
}
|
||||
|
||||
if (type !== "prod") {
|
||||
type = "demo";
|
||||
}
|
||||
|
||||
console.log("type", type);
|
||||
|
||||
const build = await getBuild(buildName);
|
||||
|
||||
if (!build) {
|
||||
@@ -41,18 +57,35 @@ app.get("/start", async (req, res) => {
|
||||
|
||||
console.log(build);
|
||||
|
||||
const activeSessionsWithBuild = await ActiveSession.find({ buildName });
|
||||
const activeSessionsWithBuild = await ActiveSession.find({
|
||||
location,
|
||||
buildName,
|
||||
type,
|
||||
});
|
||||
|
||||
console.log("type", type);
|
||||
console.log("activeSessionsWithBuild", activeSessionsWithBuild);
|
||||
|
||||
if (
|
||||
build.launchLimit &&
|
||||
activeSessionsWithBuild.length >= build.launchLimit
|
||||
type === "demo" &&
|
||||
build.demoLaunchLimit &&
|
||||
activeSessionsWithBuild.length >= build.demoLaunchLimit
|
||||
) {
|
||||
return res.json({ error: "Build launch limit reached" });
|
||||
return res.json({ error: "The demo build launch limit has been reached." });
|
||||
}
|
||||
|
||||
const sessionServers = await SessionServer.find({ location, type: "demo" });
|
||||
if (
|
||||
type === "prod" &&
|
||||
build.prodLaunchLimit &&
|
||||
activeSessionsWithBuild.length >= build.prodLaunchLimit
|
||||
) {
|
||||
return res.json({ error: "The prod build launch limit has been reached." });
|
||||
}
|
||||
|
||||
const sessionServers = await SessionServer.find({ location, type });
|
||||
|
||||
if (sessionServers.length === 0) {
|
||||
console.log("sessionServers.length", sessionServers.length);
|
||||
return res.json({ error: 2 });
|
||||
}
|
||||
|
||||
@@ -62,21 +95,25 @@ app.get("/start", async (req, res) => {
|
||||
if (gpuMemoryFree < build.gpuMemoryUsed!) {
|
||||
continue;
|
||||
}
|
||||
// const sessionServerUrl = `https://${location}.sess.stream.graff.tech/${sessionServer}`;
|
||||
const sessionServerUrl = "http://localhost:3000";
|
||||
|
||||
const sessionServerUrl = `https://${location}.sess.stream.graff.tech/${sessionServer.name}`;
|
||||
// const sessionServerUrl = "http://localhost:3000";
|
||||
|
||||
console.log(`${sessionServerUrl}/start`);
|
||||
|
||||
try {
|
||||
const result = await got
|
||||
const result: any = await got
|
||||
.post(`${sessionServerUrl}/start`, {
|
||||
json: {
|
||||
buildName,
|
||||
ownerIp,
|
||||
},
|
||||
})
|
||||
.json();
|
||||
|
||||
console.log("Result: ", result);
|
||||
|
||||
return res.json({ result });
|
||||
return res.json({ stream: result.id });
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
return res.json({ error: error.message });
|
||||
@@ -90,6 +127,96 @@ app.get("/start", async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/end", async (req, res) => {
|
||||
const activeSessionId = req.body.activeSessionId;
|
||||
console.log("activeSessionId", activeSessionId);
|
||||
const activeSession = await ActiveSession.findById(activeSessionId);
|
||||
console.log("activeSession", activeSession);
|
||||
|
||||
if (!activeSession) {
|
||||
return res.json({ error: "A session with this ID was not found" });
|
||||
}
|
||||
|
||||
const result = await got
|
||||
.post(
|
||||
`https://${activeSession.location}.sess.stream.graff.tech/${activeSession.name}/end`,
|
||||
{ json: { activeSessionId } }
|
||||
)
|
||||
.json();
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
|
||||
const createToken = (roomName: string, participantName: string) => {
|
||||
const at = new AccessToken("prodkey", "ZUwD12h0hsBfhgnYadHyHENaBGlFSVZJ", {
|
||||
identity: participantName,
|
||||
});
|
||||
at.addGrant({ roomJoin: true, room: roomName });
|
||||
|
||||
return at.toJwt();
|
||||
};
|
||||
|
||||
app.get("/getToken", (req, res) => {
|
||||
if (!req.query.roomName && !req.query.participantName) {
|
||||
return res.json({ error: "roomName or participantName is not defined" });
|
||||
}
|
||||
|
||||
try {
|
||||
const token = createToken(
|
||||
req.query.roomName as string,
|
||||
req.query.participantName as string
|
||||
);
|
||||
res.json({ token });
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/session_servers", async (req, res) => {
|
||||
try {
|
||||
const sessionServers = await SessionServer.find();
|
||||
res.json(sessionServers);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is listening on port ${port}`);
|
||||
});
|
||||
|
||||
async function checkActiveSessions() {
|
||||
const activeSessions = await ActiveSession.find();
|
||||
|
||||
for (const activeSession of activeSessions) {
|
||||
if (
|
||||
!activeSession.connectedPlayersCount &&
|
||||
differenceInMinutes(new Date(), activeSession.updatedAt) > 2
|
||||
) {
|
||||
const activeSessionId = activeSession.id;
|
||||
|
||||
try {
|
||||
const result = await got
|
||||
.post(
|
||||
`https://${activeSession.location}.sess.stream.graff.tech/${activeSession.name}/end`,
|
||||
{ json: { activeSessionId } }
|
||||
)
|
||||
.json();
|
||||
|
||||
console.log("Result:", result);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
console.log({ error });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cron.schedule("* * * * *", () => {
|
||||
checkActiveSessions();
|
||||
});
|
||||
|
||||
@@ -11,6 +11,9 @@ const activeSessionSchema = new Schema(
|
||||
buildName: {
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
uePort: {
|
||||
type: Number,
|
||||
},
|
||||
@@ -23,6 +26,12 @@ const activeSessionSchema = new Schema(
|
||||
cirrusProcessId: {
|
||||
type: Number,
|
||||
},
|
||||
ownerIp: {
|
||||
type: String,
|
||||
},
|
||||
connectedPlayersCount: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
|
||||
+4
-1
@@ -5,7 +5,10 @@ const buildSchema = new Schema(
|
||||
name: {
|
||||
type: String,
|
||||
},
|
||||
launchLimit: {
|
||||
demoLaunchLimit: {
|
||||
type: Number,
|
||||
},
|
||||
prodLaunchLimit: {
|
||||
type: Number,
|
||||
},
|
||||
gpuMemoryUsed: {
|
||||
|
||||
Reference in New Issue
Block a user