Files
gitops/ts/cache/classes.cachedb.ts

83 lines
2.3 KiB
TypeScript

import * as plugins from '../plugins.ts';
import { logger } from '../logging.ts';
export interface ICacheDbOptions {
storagePath?: string;
dbName?: string;
debug?: boolean;
}
/**
* Singleton wrapper around LocalTsmDb + SmartdataDb.
* Provides a managed MongoDB-compatible cache database.
*/
export class CacheDb {
private static instance: CacheDb | null = null;
private localTsmDb: InstanceType<typeof plugins.smartmongo.LocalTsmDb> | null = null;
private smartdataDb: InstanceType<typeof plugins.smartdata.SmartdataDb> | null = null;
private options: Required<ICacheDbOptions>;
private constructor(options: ICacheDbOptions = {}) {
this.options = {
storagePath: options.storagePath ?? './.nogit/cachedb',
dbName: options.dbName ?? 'gitops_cache',
debug: options.debug ?? false,
};
}
static getInstance(options?: ICacheDbOptions): CacheDb {
if (!CacheDb.instance) {
CacheDb.instance = new CacheDb(options);
}
return CacheDb.instance;
}
static resetInstance(): void {
CacheDb.instance = null;
}
async start(): Promise<void> {
logger.info('Starting CacheDb...');
this.localTsmDb = new plugins.smartmongo.LocalTsmDb({
folderPath: this.options.storagePath,
});
const { connectionUri } = await this.localTsmDb.start();
this.smartdataDb = new plugins.smartdata.SmartdataDb({
mongoDbUrl: connectionUri,
mongoDbName: this.options.dbName,
});
await this.smartdataDb.init();
logger.success(`CacheDb started (db: ${this.options.dbName})`);
}
async stop(): Promise<void> {
logger.info('Stopping CacheDb...');
if (this.smartdataDb) {
await this.smartdataDb.close();
this.smartdataDb = null;
}
if (this.localTsmDb) {
// localDb.stop() may hang under Deno — fire-and-forget with timeout
const stopPromise = this.localTsmDb.stop().catch(() => {});
await Promise.race([
stopPromise,
new Promise<void>((resolve) => {
const id = setTimeout(resolve, 3000);
Deno.unrefTimer(id);
}),
]);
this.localTsmDb = null;
}
logger.success('CacheDb stopped');
}
getDb(): InstanceType<typeof plugins.smartdata.SmartdataDb> {
if (!this.smartdataDb) {
throw new Error('CacheDb not started. Call start() first.');
}
return this.smartdataDb;
}
}