Сохранение журнала событий в couchdb
This commit is contained in:
parent
39fe3c7a79
commit
03dc905439
3 changed files with 81 additions and 8 deletions
|
|
@ -15,6 +15,9 @@ import { CurrentUserEnhancer } from './issue-enhancers/current-user-enhancer';
|
||||||
import { CustomFieldsEnhancer } from './issue-enhancers/custom-fields-enhancer';
|
import { CustomFieldsEnhancer } from './issue-enhancers/custom-fields-enhancer';
|
||||||
import { PersonalNotificationsService } from './notifications/personal-notifications.service';
|
import { PersonalNotificationsService } from './notifications/personal-notifications.service';
|
||||||
import { StatusChangeNotificationsService } from './notifications/status-change-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({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -32,6 +35,7 @@ import { StatusChangeNotificationsService } from './notifications/status-change-
|
||||||
StatusChangeNotificationsService,
|
StatusChangeNotificationsService,
|
||||||
Changes,
|
Changes,
|
||||||
RedminePublicUrlConverter,
|
RedminePublicUrlConverter,
|
||||||
|
ChangesCacheWriterService,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AppModule implements OnModuleInit {
|
export class AppModule implements OnModuleInit {
|
||||||
|
|
@ -45,9 +49,14 @@ export class AppModule implements OnModuleInit {
|
||||||
private customFieldsEnhancer: CustomFieldsEnhancer,
|
private customFieldsEnhancer: CustomFieldsEnhancer,
|
||||||
private currentUserEnhancer: CurrentUserEnhancer,
|
private currentUserEnhancer: CurrentUserEnhancer,
|
||||||
private statusChangeNotificationsService: StatusChangeNotificationsService,
|
private statusChangeNotificationsService: StatusChangeNotificationsService,
|
||||||
|
private changesCacheWriterService: ChangesCacheWriterService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
onModuleInit() {
|
onModuleInit() {
|
||||||
|
Issues.getDatasource();
|
||||||
|
Users.getDatasource();
|
||||||
|
Changes.getDatasource();
|
||||||
|
|
||||||
this.enhancerService.addEnhancer([
|
this.enhancerService.addEnhancer([
|
||||||
this.timestampEnhancer,
|
this.timestampEnhancer,
|
||||||
this.customFieldsEnhancer,
|
this.customFieldsEnhancer,
|
||||||
|
|
@ -93,15 +102,25 @@ export class AppModule implements OnModuleInit {
|
||||||
switchMap(async (saveResult) => {
|
switchMap(async (saveResult) => {
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
this.logger.debug(`statusChangeNotificationsService.getChanges started`);
|
this.logger.debug(`statusChangeNotificationsService.getChanges started`);
|
||||||
|
const changes =
|
||||||
await this.statusChangeNotificationsService.getChanges(saveResult);
|
await this.statusChangeNotificationsService.getChanges(saveResult);
|
||||||
// eslint-disable-next-line prettier/prettier
|
// eslint-disable-next-line prettier/prettier
|
||||||
this.logger.debug(`statusChangeNotificationsService.getChanges successed`);
|
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(
|
this.logger.debug(
|
||||||
`Save result process success finished, issue_id = ${saveResult.current.id}`,
|
`Save result process success finished, issue_id = ${args.saveResult.current.id}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
54
src/changes-cache-writer/changes-cache-writer.service.ts
Normal file
54
src/changes-cache-writer/changes-cache-writer.service.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { CouchDb } from '@app/event-emitter/couchdb-datasources/couchdb';
|
import { CouchDb } from '@app/event-emitter/couchdb-datasources/couchdb';
|
||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import nano from 'nano';
|
import nano from 'nano';
|
||||||
|
import { Change } from 'src/models/change.model';
|
||||||
import configuration from '../configs/app';
|
import configuration from '../configs/app';
|
||||||
|
|
||||||
const config = configuration();
|
const config = configuration();
|
||||||
|
|
@ -11,9 +12,7 @@ export class Changes {
|
||||||
private static changesDb = null;
|
private static changesDb = null;
|
||||||
private static initilized = false;
|
private static initilized = false;
|
||||||
|
|
||||||
// TODO: Указать полные типы данных
|
static async getDatasource(): Promise<nano.DocumentScope<Change>> {
|
||||||
|
|
||||||
static async getDatasource(): Promise<nano.DocumentScope<any>> {
|
|
||||||
if (Changes.initilized) {
|
if (Changes.initilized) {
|
||||||
return Changes.changesDb;
|
return Changes.changesDb;
|
||||||
}
|
}
|
||||||
|
|
@ -25,11 +24,12 @@ export class Changes {
|
||||||
await n.db.create(changesDbName);
|
await n.db.create(changesDbName);
|
||||||
}
|
}
|
||||||
Changes.changesDb = await n.db.use(changesDbName);
|
Changes.changesDb = await n.db.use(changesDbName);
|
||||||
|
Changes.initilized = true;
|
||||||
Changes.logger.log(`Connected to changes db - ${changesDbName}`);
|
Changes.logger.log(`Connected to changes db - ${changesDbName}`);
|
||||||
return Changes.changesDb;
|
return Changes.changesDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDatasource(): Promise<nano.DocumentScope<any>> {
|
async getDatasource(): Promise<nano.DocumentScope<Change>> {
|
||||||
return await Changes.getDatasource();
|
return await Changes.getDatasource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue