fix: fix missing timeouts

This commit is contained in:
Steve Korshakov 2025-09-01 11:57:27 -07:00
parent 15762fc706
commit 2dada58228
3 changed files with 43 additions and 19 deletions

View File

@ -51,7 +51,7 @@ declare module 'fastify' {
}
export async function startApi(): Promise<{ app: FastifyInstance; io: Server }> {
export async function startApi(eventRouter: EventRouter): Promise<{ app: FastifyInstance; io: Server }> {
// Configure
log('Starting API...');
@ -249,9 +249,6 @@ export async function startApi(): Promise<{ app: FastifyInstance; io: Server }>
}
});
// Initialize event router
const eventRouter = new EventRouter();
// Auth schema
typed.post('/v1/auth', {
schema: {

View File

@ -1,10 +1,10 @@
import { pubsub } from "@/services/pubsub";
import { db } from "@/storage/db";
import { delay } from "@/utils/delay";
import { forever } from "@/utils/forever";
import { shutdownSignal } from "@/utils/shutdown";
import { buildMachineActivityEphemeral, buildSessionActivityEphemeral, EventRouter } from "@/modules/eventRouter";
export function startTimeout() {
export function startTimeout(eventRouter: EventRouter) {
forever('session-timeout', async () => {
while (true) {
// Find timed out sessions
@ -17,16 +17,41 @@ export function startTimeout() {
}
});
for (const session of sessions) {
await db.session.update({
where: { id: session.id },
const updated = await db.session.updateManyAndReturn({
where: { id: session.id, active: true },
data: { active: false }
});
pubsub.emit('update-ephemeral', session.accountId, {
type: 'activity',
id: session.id,
active: false,
activeAt: session.lastActiveAt.getTime(),
thinking: false
if (updated.length === 0) {
continue;
}
eventRouter.emitEphemeral({
userId: session.accountId,
payload: buildSessionActivityEphemeral(session.id, false, updated[0].lastActiveAt.getTime(), false),
recipientFilter: { type: 'all-user-authenticated-connections' }
});
}
// Find timed out machines
const machines = await db.machine.findMany({
where: {
active: true,
lastActiveAt: {
lte: new Date(Date.now() - 1000 * 60 * 10) // 10 minutes
}
}
});
for (const machine of machines) {
const updated = await db.machine.updateManyAndReturn({
where: { id: machine.id, active: true },
data: { active: false }
});
if (updated.length === 0) {
continue;
}
eventRouter.emitEphemeral({
userId: machine.accountId,
payload: buildMachineActivityEphemeral(machine.id, false, updated[0].lastActiveAt.getTime()),
recipientFilter: { type: 'all-user-authenticated-connections' }
});
}

View File

@ -11,6 +11,7 @@ import { startDatabaseMetricsUpdater } from "@/modules/metrics";
import { initEncrypt } from "./modules/encrypt";
import { initGithub } from "./modules/github";
import { loadFiles } from "./storage/files";
import { EventRouter } from "./modules/eventRouter";
async function main() {
@ -25,6 +26,7 @@ async function main() {
await redis.ping();
// Initialize auth module
const eventRouter = new EventRouter();
await initEncrypt();
await initGithub();
await loadFiles();
@ -34,10 +36,10 @@ async function main() {
// Start
//
await startApi();
await startApi(eventRouter);
await startMetricsServer();
startDatabaseMetricsUpdater();
startTimeout();
startTimeout(eventRouter);
//
// Ready