Skip to content

Integrate protobuf ingestion with the indexer - #1388

Draft
jwils wants to merge 3 commits into
joshuaw/proto-decoding-validationfrom
joshuaw/proto-integration
Draft

jwils wants to merge 3 commits into
joshuaw/proto-decoding-validationfrom
joshuaw/proto-integration

Conversation

@jwils

@jwils jwils commented Sep 13, 2026 •

Copy link
Copy Markdown
Collaborator

Why

The protobuf decoder and adapter need a public entry point that sends binary payloads through the shared indexer.

What

Expose a protobuf indexer wrapper and exercise the full ingestion path under proto2 and proto3.

How

The wrapper decodes batches or raw messages, returns individual failures, and indexes valid events through the shared processor. Integration tests check indexed values, source-only updates, out-of-order replay, warehouse output, and boot from dumped artifacts.

Risk

The wrapper is new and adds no transport-specific consumers. It uses the versionless validation and schema-evolution rules from #1406.

Testing

No manual testing.

Bigger picture

Final PR in the protobuf ingestion stack. This layer contains the wrapper and end-to-end tests; #1406 owns decoding, validation, and schema evolution.

@jwils
jwils force-pushed the joshuaw/proto-integration branch 4 times, most recently from 49058c8 to 0ad7f71 Compare September 15, 2026 14:20
@jwils
jwils force-pushed the joshuaw/proto-integration branch 4 times, most recently from 73e7853 to 628c847 Compare September 24, 2026 04:02
@jwils jwils changed the title Support protobuf ingestion end to end Integrate protobuf ingestion with the indexer Sep 24, 2026
@jwils
jwils changed the base branch from main to joshuaw/proto-decoding-validation September 24, 2026 04:02
@jwils
jwils added this pull request to stack #1407 September 24, 2026 04:03
@jwils
jwils force-pushed the joshuaw/proto-integration branch from 628c847 to 4f6417c Compare September 24, 2026 04:13
@jwils
jwils removed this pull request from stack #1407 September 24, 2026 04:14
@jwils
jwils added this pull request to stack #1409 September 24, 2026 04:14
@jwils
jwils force-pushed the joshuaw/proto-integration branch 2 times, most recently from 8fc3d16 to 86f7895 Compare September 24, 2026 13:55
@jwils
jwils force-pushed the joshuaw/proto-integration branch from 86f7895 to e6831fe Compare September 28, 2026 14:34
@jwils
jwils force-pushed the joshuaw/proto-integration branch from e6831fe to f07ca01 Compare September 28, 2026 15:00
@jwils
jwils force-pushed the joshuaw/proto-integration branch from f07ca01 to 8b1b253 Compare September 28, 2026 15:22
@jwils
jwils force-pushed the joshuaw/proto-integration branch 2 times, most recently from 56764a8 to d088ad5 Compare September 29, 2026 20:22
@jwils
jwils force-pushed the joshuaw/proto-integration branch from d088ad5 to e725d0e Compare September 29, 2026 21:55
@jwils
jwils force-pushed the joshuaw/proto-integration branch 2 times, most recently from d621534 to 595ec8c Compare September 30, 2026 01:23
jwils added a commit that referenced this pull request Oct 1, 2026
…ormat (#1412)

## Why

Protobuf ingestion should support everything JSON ingestion does. The
indexer acceptance and integration specs are the best record of what
JSON ingestion supports, but they only run against JSON. Running them
against protobuf too would show each gap as the protobuf stack closes
it.

## What

Run all indexer acceptance and integration specs once per ingestion
format, in `with json ingestion` and `with proto ingestion` contexts.
The protobuf examples are `pending` because the indexer cannot ingest
protobuf events yet.

RSpec still runs pending examples and fails any that pass. As protobuf
ingestion lands, the blanket `pending` gives way to `pending` metadata
on the examples that still fail. RSpec then flags each of those examples
as its gap closes.

## How

A new `spec_support/.../ingestion_formats.rb` provides
`for_each_ingestion_format`, which defines a context per format.
Examples keep building events with the JSON factories. They process them
through `process_indexing_events`, which calls
`round_trip_indexing_events` (and `index_records` for the derived-type
spec). For JSON, the round trip returns the events unchanged. For
protobuf, it raises `NotImplementedError` for now; the protobuf stack
will replace that with publishing to and decoding from protobuf. The
names match the harness in #1388 so the stack can rebase onto this.

The protobuf contexts build indexers from the stock schema defined with
the protobuf extension, cached once per process. `schema_evolution_spec`
dumps protobuf-only artifacts and leaves out `json_schema_version`.

The malformed-event examples in `processor_spec` run only for JSON.
Their events have wrong primitive types (e.g. `name: 17`), which a
protobuf publisher can't encode.

This also fixes the VCR hook. It skipped recording a cassette only when
`ex.exception` was set. RSpec stores the expected failure of a pending
example in `execution_result.pending_exception` instead, so failing
pending examples got recorded. After a gap closed, replaying that
cassette would fail the example with a VCR error, so it stayed pending
and RSpec never reported it fixed. I checked this locally by making the
protobuf round trip return events unchanged: before the fix, examples
stayed pending; after it, RSpec reports them `FIXED`.

## Risk

Low. Only specs and spec support change. The JSON examples are the same
52 as before.

## Testing

No manual testing. On main, the proto variants already show real gaps
beyond the stubbed round trip. Protobuf-only artifacts give "No
ingestion adapters are available". Removing a field or type doesn't
abort the dump the way the JSON schema version check does.

## Bigger picture

This follows up on Myron's suggestion to run the indexer specs against
both formats and use `pending` for the gaps. The protobuf ingestion
stack (#1405 → #1408 → #1406 → #1388) can rebase onto this, implement
`round_trip_indexing_events` for protobuf, and replace the blanket
`pending` with per-example metadata. Schema evolution for protobuf will
also need to encode old events with the old compiled descriptors.

---------

Co-authored-by: myronmarston-toast <myron.marston@toasttab.com>
jwils added 3 commits October 1, 2026 11:41
Define the unversioned wire contract and its tradeoffs. Correct the
historical index destination and enum behavior assumptions, and explain
safe renames, deletions, integer changes, and explicit field rotation.
Retain wire identities and retired contracts in the field-number sidecar.
Map old publisher bytes to current public names and index destinations,
and keep range checks active when record validation is sampled out.

Decode and validate protobuf events through the shared indexer. Exercise
historical publishers with separate descriptors under proto2 and proto3.
Expose a protobuf indexer wrapper that decodes a batch, converts valid
events through the registered adapter, and sends them to the shared
processor. Exercise protobuf and JSON ingestion through the shared
indexing path.

This branch has not been deployed

No deployments
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