import { Module, type OnApplicationShutdown, Inject, Optional } from '@nestjs/common'; import { createQueue, type QueueHandle } from '@mosaicstack/queue'; import type { MosaicConfig } from '@mosaicstack/config'; import { MOSAIC_CONFIG } from '../config/config.module.js'; import { SessionGCService } from './session-gc.service.js'; import { REDIS } from './gc.tokens.js'; const GC_QUEUE_HANDLE = 'GC_QUEUE_HANDLE'; @Module({ providers: [ { provide: GC_QUEUE_HANDLE, useFactory: (config: MosaicConfig | null): QueueHandle | null => { // On Local tier there is no Redis — skip the ioredis connection entirely. // The Valkey GC sweep is a no-op on Local (no session keys stored there). if (config?.queue?.type === 'local') return null; return createQueue(); }, inject: [MOSAIC_CONFIG], }, { provide: REDIS, useFactory: (handle: QueueHandle | null) => handle?.redis ?? null, inject: [GC_QUEUE_HANDLE], }, SessionGCService, ], exports: [SessionGCService], }) export class GCModule implements OnApplicationShutdown { constructor( @Optional() @Inject(GC_QUEUE_HANDLE) private readonly handle: QueueHandle | null, ) {} async onApplicationShutdown(): Promise { await this.handle?.close().catch(() => {}); } }