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
@@ -0,0 +1,86 @@
import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { Config, JobQueue, OnEvent } from '../../base';
@Injectable()
export class IndexerEvent {
constructor(
private readonly queue: JobQueue,
private readonly config: Config
) {}
@OnEvent('doc.updated')
async indexDoc({ workspaceId, docId }: Events['doc.updated']) {
if (!this.config.indexer.enabled) {
return;
}
await this.queue.add(
'indexer.indexDoc',
{
workspaceId,
docId,
},
{
jobId: `indexDoc/${workspaceId}/${docId}`,
priority: 100,
}
);
}
@OnEvent('workspace.updated')
async indexWorkspace({ id }: Events['workspace.updated']) {
if (!this.config.indexer.enabled) {
return;
}
await this.queue.add(
'indexer.indexWorkspace',
{
workspaceId: id,
},
{
jobId: `indexWorkspace/${id}`,
priority: 100,
}
);
}
@OnEvent('user.deleted')
async deleteUserWorkspaces(payload: Events['user.deleted']) {
if (!this.config.indexer.enabled) {
return;
}
for (const workspace of payload.ownedWorkspaces) {
await this.queue.add(
'indexer.deleteWorkspace',
{
workspaceId: workspace,
},
{
jobId: `deleteWorkspace/${workspace}`,
priority: 0,
}
);
}
}
@Cron(CronExpression.EVERY_30_SECONDS)
async autoIndexWorkspaces() {
if (!this.config.indexer.enabled) {
return;
}
await this.queue.add(
'indexer.autoIndexWorkspaces',
{},
{
// make sure only one job is running at a time
delay: 30 * 1000,
jobId: 'autoIndexWorkspaces',
}
);
}
}