chore(server): support disable indexer plugin (#12408)

close CLOUD-220

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced a new service to handle indexing-related events and scheduled tasks, improving the management of document and workspace indexing.
  - Added support for configuring the indexer feature via the AFFINE_INDEXER_ENABLED environment variable.

- **Bug Fixes**
  - Ensured that indexing and deletion jobs are only enqueued when the indexer feature is enabled.

- **Tests**
  - Added comprehensive tests for the new indexing event service, covering various configuration scenarios.
  - Removed obsolete test related to auto-indexing scheduling.

- **Chores**
  - Updated configuration descriptions and mappings to improve clarity and environment variable support.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
fengmk2
2025-05-21 13:19:02 +00:00
parent 322bd4f76b
commit 346c0df800
11 changed files with 197 additions and 67 deletions
@@ -32,13 +32,9 @@ declare global {
docId: string;
blob: Buffer;
};
'doc.created': {
workspaceId: string;
docId: string;
editor?: string;
};
}
}
@Injectable()
export class PgWorkspaceDocStorageAdapter extends DocStorageAdapter {
protected override readonly logger = new Logger(
+2 -34
View File
@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { JobQueue, OnEvent } from '../../base';
import { OnEvent } from '../../base';
import { Models } from '../../models';
import { PgWorkspaceDocStorageAdapter } from './adapters/workspace';
import { DocReader } from './reader';
@@ -10,8 +10,7 @@ export class DocEventsListener {
constructor(
private readonly docReader: DocReader,
private readonly models: Models,
private readonly workspace: PgWorkspaceDocStorageAdapter,
private readonly queue: JobQueue
private readonly workspace: PgWorkspaceDocStorageAdapter
) {}
@OnEvent('doc.snapshot.updated')
@@ -29,17 +28,6 @@ export class DocEventsListener {
return;
}
await this.models.doc.upsertMeta(workspaceId, docId, content);
await this.queue.add(
'indexer.indexDoc',
{
workspaceId,
docId,
},
{
jobId: `indexDoc/${workspaceId}/${docId}`,
priority: 100,
}
);
} else {
// update workspace content to database
const content = this.docReader.parseWorkspaceContent(blob);
@@ -47,16 +35,6 @@ export class DocEventsListener {
return;
}
await this.models.workspace.update(workspaceId, content);
await this.queue.add(
'indexer.indexWorkspace',
{
workspaceId,
},
{
jobId: `indexWorkspace/${workspaceId}`,
priority: 100,
}
);
}
}
@@ -64,16 +42,6 @@ export class DocEventsListener {
async clearUserWorkspaces(payload: Events['user.deleted']) {
for (const workspace of payload.ownedWorkspaces) {
await this.workspace.deleteSpace(workspace);
await this.queue.add(
'indexer.deleteWorkspace',
{
workspaceId: workspace,
},
{
jobId: `deleteWorkspace/${workspace}`,
priority: 0,
}
);
}
}
}