From 797cd5c6ebcb834495236e50f1b8f80fe55d44b6 Mon Sep 17 00:00:00 2001 From: liuyi Date: Wed, 13 Dec 2023 02:12:37 +0000 Subject: [PATCH] fix(server): avoid repeatly register providers (#5265) --- packages/backend/server/src/config/def.ts | 7 ++++ packages/backend/server/src/config/default.ts | 6 ++- packages/backend/server/src/config/index.ts | 1 + packages/backend/server/src/event/index.ts | 6 +-- packages/backend/server/src/modules/config.ts | 4 +- .../backend/server/src/modules/doc/index.ts | 38 +++---------------- .../backend/server/src/modules/doc/manager.ts | 5 +-- packages/backend/server/src/modules/index.ts | 11 +++--- .../src/modules/sync/events/events.module.ts | 2 +- .../server/src/modules/workspaces/index.ts | 2 +- packages/backend/server/src/throttler.ts | 3 +- packages/backend/server/tests/doc.spec.ts | 2 +- 12 files changed, 34 insertions(+), 53 deletions(-) diff --git a/packages/backend/server/src/config/def.ts b/packages/backend/server/src/config/def.ts index 1b9a065d9a..725e616e56 100644 --- a/packages/backend/server/src/config/def.ts +++ b/packages/backend/server/src/config/def.ts @@ -16,6 +16,8 @@ export enum ExternalAccount { firebase = 'firebase', } +export type ServerFlavor = 'allinone' | 'graphql' | 'sync' | 'selfhosted'; + type EnvConfigType = 'string' | 'int' | 'float' | 'boolean'; type ConfigPaths = LeafPaths< Omit< @@ -345,6 +347,11 @@ export interface AFFiNEConfig { doc: { manager: { + /** + * Whether auto merge updates into doc snapshot. + */ + enableUpdateAutoMerging: boolean; + /** * How often the [DocManager] will start a new turn of merging pending updates into doc snapshot. * diff --git a/packages/backend/server/src/config/default.ts b/packages/backend/server/src/config/default.ts index 04e6aaacc3..b89f4f68b6 100644 --- a/packages/backend/server/src/config/default.ts +++ b/packages/backend/server/src/config/default.ts @@ -7,9 +7,12 @@ import { join } from 'node:path'; import parse from 'parse-duration'; import pkg from '../../package.json' assert { type: 'json' }; -import type { AFFiNEConfig } from './def'; +import type { AFFiNEConfig, ServerFlavor } from './def'; import { applyEnvToConfig } from './env'; +export const SERVER_FLAVOR = (process.env.SERVER_FLAVOR ?? + 'allinone') as ServerFlavor; + // Don't use this in production export const examplePrivateKey = `-----BEGIN EC PRIVATE KEY----- MHcCAQEEIEtyAJLIULkphVhqXqxk4Nr8Ggty3XLwUJWBxzAWCWTMoAoGCCqGSM49 @@ -206,6 +209,7 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => { }, doc: { manager: { + enableUpdateAutoMerging: SERVER_FLAVOR !== 'sync', updatePollInterval: 3000, experimentalMergeWithJwstCodec: false, }, diff --git a/packages/backend/server/src/config/index.ts b/packages/backend/server/src/config/index.ts index 812cbe6e1e..cdd76a91bb 100644 --- a/packages/backend/server/src/config/index.ts +++ b/packages/backend/server/src/config/index.ts @@ -73,3 +73,4 @@ export class ConfigModule { } export type { AFFiNEConfig } from './def'; +export { SERVER_FLAVOR } from './default'; diff --git a/packages/backend/server/src/event/index.ts b/packages/backend/server/src/event/index.ts index 0c70582e59..21db47d2bb 100644 --- a/packages/backend/server/src/event/index.ts +++ b/packages/backend/server/src/event/index.ts @@ -28,12 +28,10 @@ export class EventEmitter { } } -export const OnEvent = ( +export const OnEvent = RawOnEvent as ( event: Event, opts?: Parameters[1] -) => { - return RawOnEvent(event, opts); -}; +) => MethodDecorator; @Global() @Module({ diff --git a/packages/backend/server/src/modules/config.ts b/packages/backend/server/src/modules/config.ts index be9261f2a1..5d9b05e790 100644 --- a/packages/backend/server/src/modules/config.ts +++ b/packages/backend/server/src/modules/config.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common'; import { Field, ObjectType, Query } from '@nestjs/graphql'; -export const { SERVER_FLAVOR } = process.env; +import { SERVER_FLAVOR } from '../config'; @ObjectType() export class ServerConfigType { @@ -19,7 +19,7 @@ export class ServerConfigResolver { serverConfig(): ServerConfigType { return { version: AFFiNE.version, - flavor: SERVER_FLAVOR || 'allinone', + flavor: SERVER_FLAVOR, }; } } diff --git a/packages/backend/server/src/modules/doc/index.ts b/packages/backend/server/src/modules/doc/index.ts index bc4b719f5e..52e00763a1 100644 --- a/packages/backend/server/src/modules/doc/index.ts +++ b/packages/backend/server/src/modules/doc/index.ts @@ -1,38 +1,12 @@ -import { DynamicModule } from '@nestjs/common'; +import { Module } from '@nestjs/common'; import { DocHistoryManager } from './history'; import { DocManager } from './manager'; -export class DocModule { - /** - * @param automation whether enable update merging automation logic - */ - private static defModule(automation = true): DynamicModule { - return { - module: DocModule, - providers: [ - { - provide: 'DOC_MANAGER_AUTOMATION', - useValue: automation, - }, - DocManager, - DocHistoryManager, - ], - exports: [DocManager, DocHistoryManager], - }; - } - - static forRoot() { - return this.defModule(); - } - - static forSync(): DynamicModule { - return this.defModule(false); - } - - static forFeature(): DynamicModule { - return this.defModule(false); - } -} +@Module({ + providers: [DocManager, DocHistoryManager], + exports: [DocManager, DocHistoryManager], +}) +export class DocModule {} export { DocHistoryManager, DocManager }; diff --git a/packages/backend/server/src/modules/doc/manager.ts b/packages/backend/server/src/modules/doc/manager.ts index e2306d083a..4ac2424f92 100644 --- a/packages/backend/server/src/modules/doc/manager.ts +++ b/packages/backend/server/src/modules/doc/manager.ts @@ -1,5 +1,4 @@ import { - Inject, Injectable, Logger, OnModuleDestroy, @@ -97,8 +96,6 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { private busy = false; constructor( - @Inject('DOC_MANAGER_AUTOMATION') - private readonly automation: boolean, private readonly db: PrismaService, private readonly config: Config, private readonly cache: Cache, @@ -106,7 +103,7 @@ export class DocManager implements OnModuleInit, OnModuleDestroy { ) {} onModuleInit() { - if (this.automation) { + if (this.config.doc.manager.enableUpdateAutoMerging) { this.logger.log('Use Database'); this.setup(); } diff --git a/packages/backend/server/src/modules/index.ts b/packages/backend/server/src/modules/index.ts index 422b276265..92bc986c92 100644 --- a/packages/backend/server/src/modules/index.ts +++ b/packages/backend/server/src/modules/index.ts @@ -1,8 +1,9 @@ import { DynamicModule, Type } from '@nestjs/common'; import { ScheduleModule } from '@nestjs/schedule'; +import { SERVER_FLAVOR } from '../config'; import { GqlModule } from '../graphql.module'; -import { SERVER_FLAVOR, ServerConfigModule } from './config'; +import { ServerConfigModule } from './config'; import { DocModule } from './doc'; import { PaymentModule } from './payment'; import { SelfHostedModule } from './self-hosted'; @@ -14,7 +15,7 @@ const BusinessModules: (Type | DynamicModule)[] = []; switch (SERVER_FLAVOR) { case 'sync': - BusinessModules.push(SyncModule, DocModule.forSync()); + BusinessModules.push(SyncModule, DocModule); break; case 'selfhosted': BusinessModules.push( @@ -25,7 +26,7 @@ switch (SERVER_FLAVOR) { WorkspaceModule, UsersModule, SyncModule, - DocModule.forRoot() + DocModule ); break; case 'graphql': @@ -35,7 +36,7 @@ switch (SERVER_FLAVOR) { GqlModule, WorkspaceModule, UsersModule, - DocModule.forRoot(), + DocModule, PaymentModule ); break; @@ -48,7 +49,7 @@ switch (SERVER_FLAVOR) { WorkspaceModule, UsersModule, SyncModule, - DocModule.forRoot(), + DocModule, PaymentModule ); break; diff --git a/packages/backend/server/src/modules/sync/events/events.module.ts b/packages/backend/server/src/modules/sync/events/events.module.ts index cf2fbb9ff3..82681955ce 100644 --- a/packages/backend/server/src/modules/sync/events/events.module.ts +++ b/packages/backend/server/src/modules/sync/events/events.module.ts @@ -5,7 +5,7 @@ import { PermissionService } from '../../workspaces/permission'; import { EventsGateway } from './events.gateway'; @Module({ - imports: [DocModule.forFeature()], + imports: [DocModule], providers: [EventsGateway, PermissionService], }) export class EventsModule {} diff --git a/packages/backend/server/src/modules/workspaces/index.ts b/packages/backend/server/src/modules/workspaces/index.ts index 58a9f377af..22ee57988f 100644 --- a/packages/backend/server/src/modules/workspaces/index.ts +++ b/packages/backend/server/src/modules/workspaces/index.ts @@ -8,7 +8,7 @@ import { PermissionService } from './permission'; import { PagePermissionResolver, WorkspaceResolver } from './resolver'; @Module({ - imports: [DocModule.forFeature()], + imports: [DocModule], controllers: [WorkspacesController], providers: [ WorkspaceResolver, diff --git a/packages/backend/server/src/throttler.ts b/packages/backend/server/src/throttler.ts index 439b054985..76cf0e5720 100644 --- a/packages/backend/server/src/throttler.ts +++ b/packages/backend/server/src/throttler.ts @@ -9,14 +9,13 @@ import { import Redis from 'ioredis'; import { ThrottlerStorageRedisService } from 'nestjs-throttler-storage-redis'; -import { Config, ConfigModule } from './config'; +import { Config } from './config'; import { getRequestResponseFromContext } from './utils/nestjs'; @Global() @Module({ imports: [ ThrottlerModule.forRootAsync({ - imports: [ConfigModule], inject: [Config], useFactory: (config: Config): ThrottlerModuleOptions => { const options: ThrottlerModuleOptions = { diff --git a/packages/backend/server/tests/doc.spec.ts b/packages/backend/server/tests/doc.spec.ts index 76ff2a1ca1..ac5262748a 100644 --- a/packages/backend/server/tests/doc.spec.ts +++ b/packages/backend/server/tests/doc.spec.ts @@ -26,7 +26,7 @@ const createModule = () => { CacheModule, EventModule, ConfigModule.forRoot(), - DocModule.forRoot(), + DocModule, ], }).compile(); };