fix: lazy-init Qdrant connection to prevent app startup hang
Some checks failed
Deploy API Server / build-and-deploy (push) Failing after 34s
Some checks failed
Deploy API Server / build-and-deploy (push) Failing after 34s
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 <noreply@anthropic.com>
This commit is contained in:
parent
dbfb1d2fd6
commit
b71371cd1c
@ -45,6 +45,7 @@ const VECTOR_SIZE = 1024;
|
|||||||
export class VectorService implements OnModuleInit {
|
export class VectorService implements OnModuleInit {
|
||||||
private readonly logger = new Logger(VectorService.name);
|
private readonly logger = new Logger(VectorService.name);
|
||||||
private client: QdrantClient;
|
private client: QdrantClient;
|
||||||
|
private initialized = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly config: ConfigService,
|
private readonly config: ConfigService,
|
||||||
@ -55,12 +56,17 @@ export class VectorService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
|
// Don't block startup — init lazily on first request
|
||||||
|
}
|
||||||
|
|
||||||
|
private async ensureInit() {
|
||||||
|
if (this.initialized) return;
|
||||||
try {
|
try {
|
||||||
await this.client.getCollection(COLLECTION_NAME);
|
await this.client.getCollection(COLLECTION_NAME);
|
||||||
this.logger.log(`Connected to Qdrant collection: ${COLLECTION_NAME}`);
|
this.logger.log(`Connected to Qdrant collection: ${COLLECTION_NAME}`);
|
||||||
|
this.initialized = true;
|
||||||
} catch {
|
} catch {
|
||||||
this.logger.warn(`Qdrant collection ${COLLECTION_NAME} not found — creating`);
|
this.logger.warn(`Qdrant collection ${COLLECTION_NAME} not available, will retry later`);
|
||||||
await this.ensureCollection();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +86,7 @@ export class VectorService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async upsert(points: VectorPoint[]): Promise<void> {
|
async upsert(points: VectorPoint[]): Promise<void> {
|
||||||
|
await this.ensureInit();
|
||||||
if (points.length === 0) return;
|
if (points.length === 0) return;
|
||||||
await this.client.upsert(COLLECTION_NAME, {
|
await this.client.upsert(COLLECTION_NAME, {
|
||||||
wait: true,
|
wait: true,
|
||||||
@ -93,6 +100,7 @@ export class VectorService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteBySource(sourceId: string): Promise<void> {
|
async deleteBySource(sourceId: string): Promise<void> {
|
||||||
|
await this.ensureInit();
|
||||||
await this.client.delete(COLLECTION_NAME, {
|
await this.client.delete(COLLECTION_NAME, {
|
||||||
filter: { must: [{ key: 'sourceId', match: { value: sourceId } }] },
|
filter: { must: [{ key: 'sourceId', match: { value: sourceId } }] },
|
||||||
wait: true,
|
wait: true,
|
||||||
@ -110,6 +118,7 @@ export class VectorService implements OnModuleInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async search(embedding: number[], filters: SearchFilters = {}, topK = 10): Promise<SearchResult[]> {
|
async search(embedding: number[], filters: SearchFilters = {}, topK = 10): Promise<SearchResult[]> {
|
||||||
|
await this.ensureInit();
|
||||||
const must: any[] = [];
|
const must: any[] = [];
|
||||||
if (filters.userId) must.push({ key: 'userId', match: { value: filters.userId } });
|
if (filters.userId) must.push({ key: 'userId', match: { value: filters.userId } });
|
||||||
if (filters.knowledgeBaseId) must.push({ key: 'knowledgeBaseId', match: { value: filters.knowledgeBaseId } });
|
if (filters.knowledgeBaseId) must.push({ key: 'knowledgeBaseId', match: { value: filters.knowledgeBaseId } });
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user