MCPcopy Create free account
hub / github.com/Openpanel-dev/openpanel / main

Function main

packages/db/scripts/check-sessions.ts:222–419  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

220}
221
222async function main() {
223 const args = process.argv.slice(2);
224 const verbose = args.includes('--verbose');
225 const projectIdx = args.indexOf('--project');
226 const projectFilter = projectIdx >= 0 ? args[projectIdx + 1] : null;
227 const hoursIdx = args.indexOf('--hours');
228 const hours = hoursIdx >= 0 ? Number(args[hoursIdx + 1]) : 24;
229
230 const redis = getRedisCache();
231
232 console.log('═'.repeat(70));
233 console.log('SESSION LIFECYCLE HEALTH CHECK');
234 console.log(`time: ${new Date().toISOString()}`);
235 console.log(`deadman: ${DEADMAN_MS / 60_000} min`);
236 console.log(`stuck cutoff: ${STUCK_CUTOFF_MS / 60_000} min (deadman + 3 reaper ticks)`);
237 console.log(`ch window: ${hours}h`);
238 if (projectFilter) console.log(`project: ${projectFilter}`);
239 console.log('═'.repeat(70));
240
241 // 1. Redis inventory
242 const allProjects = await redis.smembers('session:projects');
243 const projects = projectFilter
244 ? [projectFilter]
245 : allProjects.slice().sort();
246
247 header('REDIS — active sessions');
248 console.log(` ${allProjects.length} projects in session:projects`);
249
250 const redisInfo = await inspectRedis(projects);
251 console.log(` ${redisInfo.total} total active sessions`);
252 console.log(` ${redisInfo.totalEligible} past deadman (expected to reap soon)`);
253 console.log(
254 ` ${redisInfo.totalStuck} past deadman + ${STUCK_GRACE_MS / 60_000}min (stuck — reaper is behind)`
255 );
256 console.log(
257 ` ${redisInfo.totalOrphans} wallclock entries with no blob (in sampled ${SAMPLE_SIZE_PER_PROJECT}/project)`
258 );
259
260 if (verbose && redisInfo.stats.length > 0) {
261 console.log('');
262 console.log(
263 ` ${'project'.padEnd(40)} ${'active'.padStart(8)} ${'eligible'.padStart(10)} ${'stuck'.padStart(8)} ${'orphans'.padStart(8)} ${'oldest'.padStart(10)}`
264 );
265 for (const s of redisInfo.stats.sort((a, b) => b.active - a.active)) {
266 console.log(
267 ` ${s.project.padEnd(40)} ${fmt(s.active, 8)} ${fmt(s.eligible, 10)} ${fmt(s.stuck, 8)} ${fmt(s.orphans, 8)} ${s.oldestAgeMin.toFixed(1).padStart(8)}m`
268 );
269 }
270 }
271
272 // 2. Sessions queue
273 header('SESSIONS QUEUE — createSessionEnd jobs');
274 const queue = await inspectQueue();
275 console.log(` waiting: ${queue.waiting}`);
276 console.log(` delayed: ${queue.delayed}`);
277 console.log(` active: ${queue.active}`);
278 console.log(` failed: ${queue.failed}`);
279 console.log(` completed: ${queue.completed} (removed-on-complete)`);

Callers 1

check-sessions.tsFile · 0.70

Calls 13

getRedisCacheFunction · 0.90
headerFunction · 0.85
inspectRedisFunction · 0.85
inspectQueueFunction · 0.85
inspectBuffersFunction · 0.85
inspectSessionEndClaimsFunction · 0.85
inspectClickhouseFunction · 0.85
sampleOldestSessionFunction · 0.85
closeMethod · 0.80
fmtFunction · 0.70
logMethod · 0.45
someMethod · 0.45

Tested by

no test coverage detected