From b71371cd1c57191cf4117d305b0abaa344b797b2 Mon Sep 17 00:00:00 2001 From: WangDL Date: Sun, 24 May 2026 12:14:14 +0800 Subject: [PATCH] fix: lazy-init Qdrant connection to prevent app startup hang VectorService.onModuleInit() was blocking NestJS startup trying to connect to Qdrant, causing systemd restart timeout. Changed to lazy initialization: Qdrant client connects on first actual request only. Co-Authored-By: Claude Opus 4.7 --- src/modules/vector/vector.service.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/modules/vector/vector.service.ts b/src/modules/vector/vector.service.ts index d5d912a..1d22da8 100644 --- a/src/modules/vector/vector.service.ts +++ b/src/modules/vector/vector.service.ts @@ -45,6 +45,7 @@ const VECTOR_SIZE = 1024; export class VectorService implements OnModuleInit { private readonly logger = new Logger(VectorService.name); private client: QdrantClient; + private initialized = false; constructor( private readonly config: ConfigService, @@ -55,12 +56,17 @@ export class VectorService implements OnModuleInit { } async onModuleInit() { + // Don't block startup — init lazily on first request + } + + private async ensureInit() { + if (this.initialized) return; try { await this.client.getCollection(COLLECTION_NAME); this.logger.log(`Connected to Qdrant collection: ${COLLECTION_NAME}`); + this.initialized = true; } catch { - this.logger.warn(`Qdrant collection ${COLLECTION_NAME} not found — creating`); - await this.ensureCollection(); + this.logger.warn(`Qdrant collection ${COLLECTION_NAME} not available, will retry later`); } } @@ -80,6 +86,7 @@ export class VectorService implements OnModuleInit { } async upsert(points: VectorPoint[]): Promise { + await this.ensureInit(); if (points.length === 0) return; await this.client.upsert(COLLECTION_NAME, { wait: true, @@ -93,6 +100,7 @@ export class VectorService implements OnModuleInit { } async deleteBySource(sourceId: string): Promise { + await this.ensureInit(); await this.client.delete(COLLECTION_NAME, { filter: { must: [{ key: 'sourceId', match: { value: sourceId } }] }, wait: true, @@ -110,6 +118,7 @@ export class VectorService implements OnModuleInit { } async search(embedding: number[], filters: SearchFilters = {}, topK = 10): Promise { + await this.ensureInit(); const must: any[] = []; if (filters.userId) must.push({ key: 'userId', match: { value: filters.userId } }); if (filters.knowledgeBaseId) must.push({ key: 'knowledgeBaseId', match: { value: filters.knowledgeBaseId } });