Сохранение журнала событий в couchdb

This commit is contained in:
Pavel Gnedov 2022-08-09 00:16:57 +07:00
parent 39fe3c7a79
commit 03dc905439
3 changed files with 81 additions and 8 deletions

View file

@ -15,6 +15,9 @@ import { CurrentUserEnhancer } from './issue-enhancers/current-user-enhancer';
import { CustomFieldsEnhancer } from './issue-enhancers/custom-fields-enhancer';
import { PersonalNotificationsService } from './notifications/personal-notifications.service';
import { StatusChangeNotificationsService } from './notifications/status-change-notifications.service';
import { ChangesCacheWriterService } from './changes-cache-writer/changes-cache-writer.service';
import { Issues } from '@app/event-emitter/couchdb-datasources/issues';
import { Users } from '@app/event-emitter/couchdb-datasources/users';
@Module({
imports: [
@ -32,6 +35,7 @@ import { StatusChangeNotificationsService } from './notifications/status-change-
StatusChangeNotificationsService,
Changes,
RedminePublicUrlConverter,
ChangesCacheWriterService,
],
})
export class AppModule implements OnModuleInit {
@ -45,9 +49,14 @@ export class AppModule implements OnModuleInit {
private customFieldsEnhancer: CustomFieldsEnhancer,
private currentUserEnhancer: CurrentUserEnhancer,
private statusChangeNotificationsService: StatusChangeNotificationsService,
private changesCacheWriterService: ChangesCacheWriterService,
) {}
onModuleInit() {
Issues.getDatasource();
Users.getDatasource();
Changes.getDatasource();
this.enhancerService.addEnhancer([
this.timestampEnhancer,
this.customFieldsEnhancer,
@ -93,15 +102,25 @@ export class AppModule implements OnModuleInit {
switchMap(async (saveResult) => {
// eslint-disable-next-line prettier/prettier
this.logger.debug(`statusChangeNotificationsService.getChanges started`);
await this.statusChangeNotificationsService.getChanges(saveResult);
const changes =
await this.statusChangeNotificationsService.getChanges(saveResult);
// eslint-disable-next-line prettier/prettier
this.logger.debug(`statusChangeNotificationsService.getChanges successed`);
return saveResult;
return { changes, saveResult };
}),
switchMap(async (args) => {
this.logger.debug(`Save changes in couchdb started`);
const promises = args.changes.map((c) =>
this.changesCacheWriterService.saveChange(c),
);
await Promise.all(promises);
this.logger.debug('Save changes in couchdb successed');
return args;
}),
)
.subscribe(async (saveResult) => {
.subscribe(async (args) => {
this.logger.debug(
`Save result process success finished, issue_id = ${saveResult.current.id}`,
`Save result process success finished, issue_id = ${args.saveResult.current.id}`,
);
});
}

View file

@ -0,0 +1,54 @@
import { Injectable, Logger } from '@nestjs/common';
import { randomUUID } from 'crypto';
import nano from 'nano';
import { Subject } from 'rxjs';
import { Changes } from 'src/couchdb-datasources/changes';
import { Change } from 'src/models/change.model';
@Injectable()
export class ChangesCacheWriterService {
private logger = new Logger(ChangesCacheWriterService.name);
subject = new Subject<Change>();
constructor(private changes: Changes) {}
async saveChange(change: Change): Promise<void> {
this.logger.debug(
`saveChange started, ` +
`issue_id = ${change.issue_id}, ` +
`initiator.name = ${change.initiator.name}`,
);
if (!change) {
this.logger.debug(`saveChange successed, no data for saving`);
return;
}
const changesDb = await this.changes.getDatasource();
if (!changesDb) {
this.logger.error(`saveChange failed, changesDb is undefined or null`);
return;
}
const item: Change & nano.MaybeDocument = { ...change };
item._id = this.getId();
if (!item) {
this.logger.debug(`saveChange successed, no data for saving`);
return;
}
try {
await changesDb.insert(item);
} catch (ex) {
this.logger.error(`saveChange failed, error = ${ex}`);
return;
}
this.subject.next(change);
this.logger.debug(
`saveChange successed, ` +
`issue_id = ${change.issue_id}, ` +
`initiator.name = ${change.initiator.name}`,
);
}
private getId(): string {
return randomUUID();
}
}

View file

@ -1,6 +1,7 @@
import { CouchDb } from '@app/event-emitter/couchdb-datasources/couchdb';
import { Injectable, Logger } from '@nestjs/common';
import nano from 'nano';
import { Change } from 'src/models/change.model';
import configuration from '../configs/app';
const config = configuration();
@ -11,9 +12,7 @@ export class Changes {
private static changesDb = null;
private static initilized = false;
// TODO: Указать полные типы данных
static async getDatasource(): Promise<nano.DocumentScope<any>> {
static async getDatasource(): Promise<nano.DocumentScope<Change>> {
if (Changes.initilized) {
return Changes.changesDb;
}
@ -25,11 +24,12 @@ export class Changes {
await n.db.create(changesDbName);
}
Changes.changesDb = await n.db.use(changesDbName);
Changes.initilized = true;
Changes.logger.log(`Connected to changes db - ${changesDbName}`);
return Changes.changesDb;
}
async getDatasource(): Promise<nano.DocumentScope<any>> {
async getDatasource(): Promise<nano.DocumentScope<Change>> {
return await Changes.getDatasource();
}
}