Skip to content

feat: opt-in commit=wait_for for completion-tracked batches#25

Merged
acoshift merged 1 commit into
mainfrom
feat/ingest-commit-mode
Jun 13, 2026
Merged

feat: opt-in commit=wait_for for completion-tracked batches#25
acoshift merged 1 commit into
mainfrom
feat/ingest-commit-mode

Conversation

@acoshift

Copy link
Copy Markdown
Member

"With care" item #6 from the review: make the durability boundary of a tracked Ack configurable.

Problem

A 200 from the ingest endpoint means the documents reached the server's write-ahead log, not that they're committed/searchable. For tracked callers (IngestSync/IngestBatch), settle(nil) is a durability claim, so the WAL-vs-searchable distinction matters.

Change

Add SetIngestCommit(CommitAuto | CommitWaitFor | CommitForce), applied per batch:

  • A batch is sent with the stronger commit (?commit=wait_for / force) only if it carries a tracked item.
  • Pure fire-and-forget batches keep commit=auto and pay no extra latency.
  • A mixed batch (coalesced tracked + fire-and-forget) uses the stronger mode if any tracked item is present.

Two endpoint URLs are precomputed per worker (endpointDefault, endpointTracked); they're equal when the mode is CommitAuto, so the default path is byte-for-byte unchanged. Combines cleanly with ?detailed_response=true (#23).

Also tightened the IngestSync doc: nil means WAL-persisted (crash-safe) by default, committed/searchable under wait_for.

The sharp edge (documented)

wait_for/force block the request until commit, which can exceed the default ResponseHeaderTimeout (= ingestTimeout/3, from #22). If it does, the request is aborted → retried → re-ingested. The SetIngestCommit doc spells out the required headroom: set SetIngestTimeout to >3× the index commit interval (or supply your own http.Client), and rely on a dedup id. /scrutinize flagged that an earlier draft of the doc only said "raise the timeout" without the 3× factor — fixed.

Tests

4 (commit_mode_test.go): default → no commit param; tracked → commit=wait_for; fire-and-forget with wait_for set → still auto (no tracked item); force + detailed_response combine into one well-formed query (asserted via url.ParseQuery). Full suite green, go vet clean, race-clean ×2.

🤖 Generated with Claude Code

A 200 from the ingest endpoint means the documents reached the server's WAL,
not that they are committed/searchable. For tracked callers (IngestSync /
IngestBatch) settle(nil) is a durability claim, so make the commit boundary
configurable.

Add SetIngestCommit(CommitAuto|CommitWaitFor|CommitForce). The mode is applied
per batch: only when a batch carries a tracked item does it use the stronger
commit (?commit=wait_for / force); pure fire-and-forget batches keep commit=auto
and pay no extra latency. Two endpoint URLs are precomputed per worker, so the
default (CommitAuto) path is unchanged. Combines cleanly with
?detailed_response=true.

wait_for/force block the request until commit, which can exceed the default
ResponseHeaderTimeout (ingestTimeout/3); the IngestSync and SetIngestCommit docs
spell out the >3x-commit-interval timeout headroom needed to avoid
timeout-driven retries/duplicates. Also tightened the IngestSync doc: nil means
WAL-persisted (crash-safe) by default, committed/searchable under wait_for.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@acoshift acoshift merged commit 7996615 into main Jun 13, 2026
1 check passed
@acoshift acoshift deleted the feat/ingest-commit-mode branch June 13, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant