Skip to content

feat(cluster): wire IngestHandler on readers for query freshness#385

Merged
xe-nvdk merged 2 commits intomainfrom
feat/reader-ingest-handler
Apr 10, 2026
Merged

feat(cluster): wire IngestHandler on readers for query freshness#385
xe-nvdk merged 2 commits intomainfrom
feat/reader-ingest-handler

Conversation

@xe-nvdk
Copy link
Copy Markdown
Member

@xe-nvdk xe-nvdk commented Apr 10, 2026

Summary

  • Reader nodes now apply replicated WAL entries to their local ArrowBuffer, enabling near-real-time query freshness across the cluster
  • buildReplicationIngestHandler() parses WAL envelope, decodes both columnar and row msgpack formats, writes via WriteColumnarDirectNoWAL (avoids WAL double-write since receiver's LocalWAL already handles persistence)
  • Added IngestHandlerFunc adapter type (follows http.HandlerFunc pattern)
  • Extracted wal.ParseEnvelope() as shared utility — replaces inline envelope parsing in both wal/reader.go and coordinator.go
  • Foundation for feat: query in-flight buffer data (zero-latency reads) #249 (query in-flight buffer data)

Data flow (after this change)

Writer: Ingest → ArrowBuffer → WAL → replication hook → Sender → TCP → Reader
Reader: Receiver → LocalWAL (persistence) + IngestHandler → ArrowBuffer (query freshness)

Test plan

  • go build ./cmd/... ./internal/... passes
  • go test ./internal/cluster/... passes
  • go test ./internal/wal/... passes
  • Post-implementation review: nil safety, envelope parsing, format detection

Reader nodes now apply replicated WAL entries to their local ArrowBuffer,
enabling near-real-time query freshness across the cluster.

Changes:
- Added ingestBuffer field + SetIngestBuffer() to Coordinator
- buildReplicationIngestHandler() parses WAL envelope, decodes both
  columnar and row msgpack formats, writes to ArrowBuffer via
  WriteColumnarDirectNoWAL (avoids WAL double-write)
- Added IngestHandlerFunc adapter (follows http.HandlerFunc pattern)
- Extracted ParseEnvelope() to wal package as shared utility, replacing
  inline parsing in both reader.go and coordinator.go
- main.go calls SetIngestBuffer(arrowBuffer) alongside SetWAL()
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements reader query freshness by enabling reader nodes to apply replicated WAL entries directly to their local in-memory ArrowBuffer. It introduces an IngestHandler within the cluster coordinator to decode both columnar and row-formatted WAL payloads and write them to the buffer. The review feedback highlights several improvement opportunities: ensuring the row-format decoder correctly identifies measurement metadata keys, protecting access to the ingest buffer with read locks to prevent data races, and optimizing the rowsToColumns conversion to filter out metadata and improve efficiency.

Comment thread internal/cluster/coordinator.go
Comment thread internal/cluster/coordinator.go
Comment thread internal/cluster/coordinator.go
- Read-lock c.mu when accessing ingestBuffer in handler closure to
  prevent data race with SetIngestBuffer
- Added _measurement key check for row format records (writer's
  columnarToWALRecords uses _measurement prefix)
- Optimized rowsToColumns to single-pass and filter all metadata keys
  (_measurement, measurement, m, _database, database)
@xe-nvdk xe-nvdk merged commit 17ad976 into main Apr 10, 2026
5 checks passed
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