From cec787554f9b7b8a435b1371cbca025b4b016b8c Mon Sep 17 00:00:00 2001 From: Bogdan Szabo Date: Tue, 27 Oct 2026 12:23:52 +0100 Subject: [PATCH] A write does not queue a vector index build while one for the same table and dims is running Signed-off-by: Bogdan Szabo --- crates/utopia-store/src/vector_index.rs | 5 +++-- .../tests/a_vector_index_is_built_by_a_job.rs | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/utopia-store/src/vector_index.rs b/crates/utopia-store/src/vector_index.rs index e91159733..0ed91d3f9 100644 --- a/crates/utopia-store/src/vector_index.rs +++ b/crates/utopia-store/src/vector_index.rs @@ -200,7 +200,7 @@ fn is_known(name: &str) -> bool { /// 返回 `Some(job id)` = 这一次排上了。 /// /// 索引在的话记在进程里,往后只是一次 HashSet 查找;不在的时候每次写入一次目录 -/// 查询加一次「没排着才排」的插入——建索引那一两分钟里写入照常,代价可忽略。 +/// 查询加一次「没排着、也没在建才排」的插入——建索引的那段时间里写入照常,代价可忽略。 /// 超过 [`MAX_DIMS`] 的维度什么都不排:建不了,查询走精确路径 pub async fn request(pool: &PgPool, target: Target, dims: usize) -> AppResult> { if dims == 0 || dims > MAX_DIMS { @@ -214,10 +214,11 @@ pub async fn request(pool: &PgPool, target: Target, dims: usize) -> AppResult anyhow::Result<()> let second = vector_index::request(&pool, Target::Chunks, DIMS).await?; assert_eq!(second, None, "队列里已经有一条,不再排"); assert_eq!(queued(&pool, DIMS).await?, 1); + // worker 认领了它、正在建:再写也不排。排上的每一条都会占一个 worker 名额, + // 在建索引的咨询锁上空等到前一条建完(3072 维的库上一建一个多小时) + sqlx::query("UPDATE jobs SET status = 'running' WHERE kind = $1 AND payload->>'dims' = $2") + .bind(JOB_KIND) + .bind(DIMS.to_string()) + .execute(&pool) + .await?; + let while_building = vector_index::request(&pool, Target::Chunks, DIMS).await?; + assert_eq!(while_building, None, "正在建的时候不再排"); + assert_eq!(queued(&pool, DIMS).await?, 0); let built = vector_index::build(&pool, Target::Chunks, DIMS).await?; assert!(built.created);