Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apps/platform-cloudflare/__tests__/scheduled-config_test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions apps/platform-node/__tests__/scheduled-maintenance_test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 2 additions & 17 deletions apps/platform-node/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ setGlobalDispatcher(new Agent({

import { bootstrapNodePlatform } from './src/bootstrap.ts';
import { applyMigrations } from './src/migrate.ts';
import { startScheduledMaintenance } from './src/scheduled-maintenance.ts';
import {
app,
initBackgroundSchedulerResolver,
initRepo,
initResponsesWebSocketUpgradeResolver,
runScheduledMaintenance,
SqlRepo,
} from '@floway-dev/gateway';
import { getEnvOptional } from '@floway-dev/platform';
Expand Down Expand Up @@ -59,25 +59,10 @@ if (process.env.NODE_ENV === 'production' && !process.env.ADMIN_KEY) {
process.exit(1);
}

const SCHEDULED_INTERVAL_MS = 60 * 60 * 1000;

await applyMigrations(db);
initRepo(new SqlRepo(db));

// Run the scheduled maintenance job once after a short startup delay and
// then every hour. Without the startup run, a process that restarts more
// often than the interval (crash loop, frequent deploys) would never run
// maintenance and the responses-items expiry sweep would silently lag. The
// 30s delay keeps the very first request after boot from racing the sweep.
// unref() on both timers lets the process exit cleanly on SIGINT.
const STARTUP_DELAY_MS = 30 * 1000;
const sweep = (): void => {
runScheduledMaintenance().catch(err => {
console.error('[scheduled-maintenance] sweep failed:', err);
});
};
setTimeout(sweep, STARTUP_DELAY_MS).unref();
setInterval(sweep, SCHEDULED_INTERVAL_MS).unref();
startScheduledMaintenance();

serve({
fetch: app.fetch,
Expand Down
30 changes: 30 additions & 0 deletions apps/platform-node/src/scheduled-maintenance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { runScheduledMaintenance } from '@floway-dev/gateway';

interface TimerHandle {
unref(): void;
}

interface MaintenanceTimers {
setTimeout(callback: () => void, delayMs: number): TimerHandle;
setInterval(callback: () => void, delayMs: number): TimerHandle;
}

// The startup tick avoids waiting the full interval when a process stays alive
// for at least 30 seconds. Minute cadence increases bounded cleanup throughput
// and spreads its writes across the hour. Both timers are unreferenced so
// maintenance never keeps the Node process alive by itself.
const STARTUP_DELAY_MS = 30 * 1000;
const MAINTENANCE_INTERVAL_MS = 60 * 1000;

export const startScheduledMaintenance = (
runMaintenance: () => Promise<void> = runScheduledMaintenance,
timers: MaintenanceTimers = { setTimeout, setInterval },
): void => {
const sweep = (): void => {
runMaintenance().catch(err => {
console.error('[scheduled-maintenance] sweep failed:', err);
});
};
timers.setTimeout(sweep, STARTUP_DELAY_MS).unref();
timers.setInterval(sweep, MAINTENANCE_INTERVAL_MS).unref();
};
26 changes: 26 additions & 0 deletions packages/gateway/__tests__/repo/memory.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions packages/gateway/__tests__/repo/scheduled-maintenance_test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 35 additions & 2 deletions packages/gateway/__tests__/scheduled/expiration-sweeps_test.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading