On-write reindex (#17, merged d15afda) runs inline: the api::reindex helper .awaits SearchClient::sync_object, which itself .awaits Meilisearch's wait_for_completion. So every admin catalogue write (create/update/delete/fields/visibility) blocks on Meilisearch finishing the index task before the handler returns. A slow or stalled Meili adds latency to writes (worst case, blocks until the SDK's completion poll resolves/times out). Failures are already logged-not-propagated, so correctness is fine — this is purely about write latency coupling to search health.
What to do
Decouple indexing from the request path, e.g. one of:
tokio::spawn the sync_object call (fire-and-forget) after commit — AppState/SearchClient/the db pool are all cheap to clone; keep the tracing::error! on failure.
or a small bounded queue / channel drained by a background task, so bursts don't spawn unbounded tasks.
Either way: keep the best-effort semantics (a committed write must never fail or block on Meili), and keep reindex_all as the recovery path. Note that backgrounding makes the api/tests/reindex.rs assertions racy — they currently rely on the inline wait_for_completion; they'd need a poll/retry helper or to test sync_object at the unit level instead.
## Context
On-write reindex (#17, merged `d15afda`) runs **inline**: the `api::reindex` helper `.await`s `SearchClient::sync_object`, which itself `.await`s Meilisearch's `wait_for_completion`. So every admin catalogue write (create/update/delete/fields/visibility) blocks on Meilisearch finishing the index task before the handler returns. A slow or stalled Meili adds latency to writes (worst case, blocks until the SDK's completion poll resolves/times out). Failures are already logged-not-propagated, so correctness is fine — this is purely about write latency coupling to search health.
## What to do
Decouple indexing from the request path, e.g. one of:
- `tokio::spawn` the `sync_object` call (fire-and-forget) after commit — `AppState`/`SearchClient`/the db pool are all cheap to clone; keep the `tracing::error!` on failure.
- or a small bounded queue / channel drained by a background task, so bursts don't spawn unbounded tasks.
Either way: keep the best-effort semantics (a committed write must never fail or block on Meili), and keep `reindex_all` as the recovery path. Note that backgrounding makes the `api/tests/reindex.rs` assertions racy — they currently rely on the inline `wait_for_completion`; they'd need a poll/retry helper or to test `sync_object` at the unit level instead.
## References
- `crates/api/src/lib.rs` — `reindex` helper (inline `.await`)
- `crates/search/src/lib.rs` — `sync_object` / `index_object` (`wait_for_completion`)
- Surfaced in the #17 code review.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
On-write reindex (#17, merged
d15afda) runs inline: theapi::reindexhelper.awaitsSearchClient::sync_object, which itself.awaits Meilisearch'swait_for_completion. So every admin catalogue write (create/update/delete/fields/visibility) blocks on Meilisearch finishing the index task before the handler returns. A slow or stalled Meili adds latency to writes (worst case, blocks until the SDK's completion poll resolves/times out). Failures are already logged-not-propagated, so correctness is fine — this is purely about write latency coupling to search health.What to do
Decouple indexing from the request path, e.g. one of:
tokio::spawnthesync_objectcall (fire-and-forget) after commit —AppState/SearchClient/the db pool are all cheap to clone; keep thetracing::error!on failure.Either way: keep the best-effort semantics (a committed write must never fail or block on Meili), and keep
reindex_allas the recovery path. Note that backgrounding makes theapi/tests/reindex.rsassertions racy — they currently rely on the inlinewait_for_completion; they'd need a poll/retry helper or to testsync_objectat the unit level instead.References
crates/api/src/lib.rs—reindexhelper (inline.await)crates/search/src/lib.rs—sync_object/index_object(wait_for_completion)