diff --git a/packages/backend/server/src/modules/doc/manager.ts b/packages/backend/server/src/modules/doc/manager.ts index e82932a8e7..154546da33 100644 --- a/packages/backend/server/src/modules/doc/manager.ts +++ b/packages/backend/server/src/modules/doc/manager.ts @@ -5,6 +5,7 @@ import { OnModuleDestroy, OnModuleInit, } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { Snapshot, Update } from '@prisma/client'; import { chunk } from 'lodash-es'; import { defer, retry } from 'rxjs'; @@ -70,7 +71,8 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { private readonly db: PrismaService, private readonly config: Config, private readonly metrics: Metrics, - private readonly cache: Cache + private readonly cache: Cache, + private readonly event: EventEmitter2 ) {} onModuleInit() { @@ -411,7 +413,7 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { workspaceId: string, guid: string, doc: Doc, - seq?: number + initialSeq?: number ) { const blob = Buffer.from(encodeStateAsUpdate(doc)); const state = Buffer.from(encodeStateVector(doc)); @@ -435,7 +437,7 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { workspaceId, blob, state, - seq, + seq: initialSeq, }, update: { blob, @@ -479,6 +481,10 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { ...updates.map(u => u.blob) ); + if (snapshot) { + this.event.emit('doc:manager:snapshot:beforeUpdate', snapshot); + } + await this.upsert(workspaceId, id, doc, last.seq); this.logger.debug( `Squashed ${updates.length} updates for ${id} in workspace ${workspaceId}` @@ -519,6 +525,9 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { // reset if (seq >= MAX_SEQ_NUM) { await this.db.snapshot.update({ + select: { + seq: true, + }, where: { id_workspaceId: { workspaceId, diff --git a/packages/backend/server/src/modules/index.ts b/packages/backend/server/src/modules/index.ts index 600c5154b2..2574e4de42 100644 --- a/packages/backend/server/src/modules/index.ts +++ b/packages/backend/server/src/modules/index.ts @@ -11,7 +11,11 @@ import { WorkspaceModule } from './workspaces'; const { SERVER_FLAVOR } = process.env; -const BusinessModules: (Type | DynamicModule)[] = []; +const BusinessModules: (Type | DynamicModule)[] = [ + EventEmitterModule.forRoot({ + global: true, + }), +]; switch (SERVER_FLAVOR) { case 'sync': @@ -19,9 +23,6 @@ switch (SERVER_FLAVOR) { break; case 'graphql': BusinessModules.push( - EventEmitterModule.forRoot({ - global: true, - }), GqlModule, WorkspaceModule, UsersModule, @@ -33,9 +34,6 @@ switch (SERVER_FLAVOR) { case 'allinone': default: BusinessModules.push( - EventEmitterModule.forRoot({ - global: true, - }), GqlModule, WorkspaceModule, UsersModule, diff --git a/packages/backend/server/tests/doc.spec.ts b/packages/backend/server/tests/doc.spec.ts index 2ca8ced837..9a08909691 100644 --- a/packages/backend/server/tests/doc.spec.ts +++ b/packages/backend/server/tests/doc.spec.ts @@ -1,6 +1,7 @@ import { mock } from 'node:test'; import type { INestApplication } from '@nestjs/common'; +import { EventEmitterModule } from '@nestjs/event-emitter'; import { Test, TestingModule } from '@nestjs/testing'; import test from 'ava'; import { register } from 'prom-client'; @@ -20,6 +21,7 @@ const createModule = () => { PrismaModule, MetricsModule, CacheModule, + EventEmitterModule.forRoot(), ConfigModule.forRoot(), DocModule.forRoot(), ],