This repository has been archived on 2025-08-19. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
coinstorge/website/src/hooks.server.ts

77 lines
No EOL
2.7 KiB
TypeScript

import { auth } from "$lib/auth";
import { resolveExpiredQuestions, processAccountDeletions } from "$lib/server/job";
import { svelteKitHandler } from "better-auth/svelte-kit";
import { redis } from "$lib/server/redis";
import { building } from '$app/environment';
async function initializeScheduler() {
if (building) return;
try {
const lockKey = 'hopium:scheduler';
const lockValue = `${process.pid}-${Date.now()}`;
const lockTTL = 300; // 5 minutes
const result = await redis.set(lockKey, lockValue, {
NX: true,
EX: lockTTL
});
if (result === 'OK') {
console.log(`🕐 Starting scheduler (PID: ${process.pid})`);
// Renew lock periodically
const renewInterval = setInterval(async () => {
try {
const currentValue = await redis.get(lockKey);
if (currentValue === lockValue) {
await redis.expire(lockKey, lockTTL);
} else {
// Lost the lock, stop scheduler
clearInterval(renewInterval);
clearInterval(schedulerInterval);
console.log('Lost scheduler lock, stopping...');
}
} catch (error) {
console.error('Failed to renew scheduler lock:', error);
}
}, (lockTTL / 2) * 1000); // Renew at half the TTL
resolveExpiredQuestions().catch(console.error);
processAccountDeletions().catch(console.error);
const schedulerInterval = setInterval(() => {
resolveExpiredQuestions().catch(console.error);
processAccountDeletions().catch(console.error);
}, 5 * 60 * 1000);
// Cleanup on process exit
const cleanup = async () => {
clearInterval(renewInterval);
clearInterval(schedulerInterval);
const currentValue = await redis.get(lockKey);
if (currentValue === lockValue) {
await redis.del(lockKey);
}
};
process.on('SIGTERM', cleanup);
process.on('SIGINT', cleanup);
process.on('beforeExit', cleanup);
} else {
console.log('📋 Scheduler already running');
}
} catch (error) {
console.error('Failed to initialize scheduler:', error);
}
}
initializeScheduler();
export async function handle({ event, resolve }) {
// event.setHeaders({
// 'Cache-Control': 'private, no-cache, no-store, must-revalidate'
// });
return svelteKitHandler({ event, resolve, auth });
}