@randombenj/dbsync
Version:
Display, search and copy LXD-images using a web interface.
122 lines (109 loc) • 3.92 kB
text/typescript
import { DatabaseService, SyncRun } from '@lxdhub/db';
import {
Injectable,
Logger,
Inject,
OnApplicationShutdown
} from '@nestjs/common';
import { AliasService } from './alias';
import { ArchitectureService } from './architecture';
import { ImageService } from './image';
import { ImageAvailabilityService } from './image-availability';
import { OperatingSystemService } from './operating-system';
import { OsArchService } from './os-arch';
import { RemoteService } from './remote';
import { SyncRunService } from './sync-run';
import { LXDHubDbSyncSettings } from './dbsync-settings.interface';
import { SETTINGS } from './app.tokens';
/**
* The app services orchastrates the database synchronizer
*/
export class AppService implements OnApplicationShutdown {
private logger: Logger;
private syncRun?: SyncRun;
/**
* Initializes the app service
*/
constructor(
private readonly remoteService: RemoteService,
private readonly operatingSystemService: OperatingSystemService,
private readonly architectureService: ArchitectureService,
private readonly imageService: ImageService,
private readonly aliasService: AliasService,
private readonly osArchService: OsArchService,
private readonly imageAvailabilityService: ImageAvailabilityService,
private readonly databaseService: DatabaseService,
private readonly syncRunService: SyncRunService,
private readonly settings: LXDHubDbSyncSettings
) {
this.logger = new Logger('Database Synchronizer');
}
private async run() {
if (this.settings.force) {
this.syncRunService.resetAllSyncStates();
} else {
const currentlyRunningSyncs = await this.syncRunService.getCurrentlyRunningSyncs();
if (currentlyRunningSyncs.length > 1) {
const logMessage =
`There are currently ${
currentlyRunningSyncs.length
} other synchronization tasks running.\n` +
currentlyRunningSyncs
.map(sync => `- Sync #${sync.id} started at ${sync.started}`)
.join('\n') +
`You can enforce this database synchronization run by adding the "FORCE=true" environment variable.`;
this.logger.error(logMessage);
throw new Error(logMessage);
}
}
await this.syncRunService.startSyncRun(this.syncRun.id);
this.logger.log(`==> Started synchronization #${this.syncRun.id}`);
// Run the synchronizers
await this.remoteService.synchronize();
await this.imageService.synchronize();
await this.operatingSystemService.synchronize();
await this.architectureService.synchronize();
await this.aliasService.synchronize();
await this.osArchService.synchronize();
await this.imageAvailabilityService.synchronize();
}
/**
* Start the database synchronizer.
*/
async synchronize() {
this.syncRun = await this.syncRunService.createSyncRun();
this.logger.log(
`==> Starting database synchronization #${this.syncRun.id}`
);
try {
await this.run();
await this.syncRunService.finishSyncRun(this.syncRun.id);
} catch (ex) {
await this.syncRunService.failSyncRun(
this.syncRun.id,
ex ? (ex as Error).message : ''
);
}
// Closes the database connection
this.logger.log(
`==> Finished database synchronization #${this.syncRun.id}`
);
}
async onApplicationShutdown(signal?: string) {
this.logger.error(`Database sync shutting down ${signal}`);
try {
await this.databaseService.connection.connect();
await this.syncRunService.failSyncRun(
this.syncRun.id,
`Database synchronization shutdown ${signal}`
);
await this.databaseService.closeConnection();
} catch (ex) {
this.logger.error(
`Failed gracefully shutting down dbsync: ${ex.message}`
);
}
process.exit(1);
}
}