feat: Apache Fluss data connector with CDC refresh (connector-fluss) - #2
Draft
J0hnG4lt wants to merge 7 commits into
Draft
feat: Apache Fluss data connector with CDC refresh (connector-fluss)#2J0hnG4lt wants to merge 7 commits into
J0hnG4lt wants to merge 7 commits into
Conversation
Port of the v1-era Fluss connector (feat/fluss-connector-v1) onto the 2.x connector architecture: standalone crate under crates/data-connectors, linkme registration, generic spice_sys blob checkpoint sidecar, framework ready-signal envelopes. - Log tables -> refresh_mode: append (RecordBatchLogScanner) - PK tables -> refresh_mode: changes (LogScanner changelog, upstream spiceai#639) - Per-bucket offset checkpoints committed per envelope (at-least-once); CDC path now checkpoints for real via upstream ScanRecord::offset() - Readiness via high-watermark accounting seeded from the checkpoint - fluss-rs git-pinned to J0hnG4lt/fluss-rust arrow-58 (= apache main + Arrow 57->58 bump) until upstream ships an Arrow 58-compatible release Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All-podman harness for the Fluss connector: Fluss 0.9.x cluster (zk + coordinator + 2 tablets, host networking), deterministic Rust producer (setup/append/cdc/mixed with retry), spiced built from source with the connector, and a scenario runner asserting through POST /v1/sql: s1 bootstrap replay (append + CDC upserts/deletes before spiced starts) s2 realtime append latency s3 live CDC insert/update/delete exact state s4 graceful restart -> exact checkpoint resume s5 SIGKILL crash -> at-least-once appends, exact PK state s6 tablet-server fault under load -> convergence s7 chaos (coordinator pause + tablet restart) -> convergence Cargo.lock: add fluss-rs (git, arrow-58) + connector-fluss resolution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uilder - spiced on 18090/15051 so the suite coexists with another spiced on the machine's shared host-network port namespace - hand podman-compose a Windows-style path under Git Bash (cygpath -m) - clang + libclang-dev in the builder image (custom-labels bindgen) - run-e2e.sh executable bit Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… deps TableProvider no longer declares as_any (the trait inherits Any); drop the impl and downcast Arc<dyn TableProvider> directly, matching connector-kafka. Builder image gains libprotobuf-dev (substrait well-known types) — spiced now compiles and links with the connector. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cycle from compose deps - /v1/sql JSON requires 'parameters' — without it every assert read as empty - drop spiced depends_on: podman-compose 'up -d spiced' recreates dependency containers, wiping ZooKeeper (and all Fluss tables) mid-suite - restart scenarios use plain podman stop/start/kill - clean force-removes containers by name (compose down ordering fails) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
✅ Pull with Spice PassedPassing checks:
|
…runcation Two defects found by the E2E suite: - A stream that starts already caught up (empty table, or a resume whose checkpoint covers the watermarks) emitted no envelope until new data arrived, leaving the dataset NotReady and unqueryable indefinitely. Announce readiness up front with a zero-row ready-signal envelope. - A checkpoint pointing past the server's surviving log segments (tablet loses its unflushed tail) hot-looped LogOffsetOutOfRangeException. Poll errors now back off 1s, and out-of-range recovers: the CDC path replays the changelog from EARLIEST (idempotent PK ops converge), the append path rejoins at the live tail with a loud data-loss warning. E2E: tablet restarts get a 30s graceful stop so Fluss flushes acked rows. Suite: 20/20 scenarios pass (bootstrap, realtime, CDC, graceful+crash resume, tablet fault, chaos). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ests, docs Per CONTRIBUTING.md and the Alpha connector criteria: - 'fluss' feature flag in spiced (optional dep, in defaults), matching the connector feature convention; cfg-gated force-link - unit tests: CDC batch construction over real ScanRecords (op mapping, UpdateBefore filtering, per-row primary keys), watermark readiness accounting, checkpoint serde roundtrip (9 tests) - docs/features/fluss-connector.md: setup, both modes, delivery semantics, known limitations, troubleshooting - clippy strict pass (-D warnings, --no-deps): doc backticks, if-let over single-pattern match, struct-update init, expect(implicit_hasher) - Containerfile BUILD_CMD arg so the cached builder runs the signoff-equivalent checks (fmt/clippy/test) Checks (in-container, rust 1.96.1): cargo fmt --check clean; cargo clippy --all-targets --no-deps -D warnings clean; cargo test 9 passed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Summary
Adds an Apache Fluss data connector (
connector-fluss) with efficient CDC-based refresh, modeled on the DynamoDB Streams connector pattern.refresh_mode: append: continuous ingestion viaRecordBatchLogScanner.refresh_mode: changes: the table's changelog streams in as Debezium-style CDC ops (c/u/d,-Uskipped), applied by primary key.spice_sys::checkpoint_storesidecar (spice_sys_fluss_log); offsets ride eachChangeEnvelope's committer so they commit only after durable apply — exact resume on graceful restart, at-least-once on crash. Zero changes to theruntimecrate.LogOffsetOutOfRangeException) recovers — CDC replays fromEARLIEST_OFFSET(idempotent ops converge), append rejoins the live tail with a loud data-loss warning.fluss(inspiceddefaults), per the CONTRIBUTING feature-flag convention; linkme registration;MetricsProviderwith consume/error counters.Verification: E2E suite fully green — 20/20 assertions across 7 scenarios against a live Fluss 0.9.1 cluster (all podman; see
e2e/fluss/): bootstrap replay (both modes), realtime append (1s visibility), live CDC ins/upd/del, graceful restart (exact, no re-ingest), SIGKILL crash (zero loss), tablet-server fault and coordinator-pause chaos under continuous load (exact convergence: 478/478, 871/871). The suite caught two real defects fixed in this PR: a NotReady deadlock on caught-up stream start, and a hot error loop on source log truncation.Unit tests cover CDC batch construction (op mapping,
-Ufiltering, per-row primary keys), readiness accounting, and checkpoint serialization.🔗 Related
feat/fluss-connector-v1), rebuilt for the 2.x connector-crate architecture.mainpins Arrow 57 vs workspace Arrow 58 — this PR git-pinsJ0hnG4lt/fluss-rustbrancharrow-58(= apache maina10c37e+ a two-line version bump; compiles clean). Re-pin to an official release once fluss-rs ships Arrow ≥58 (chore: bump arrow-schema from 57.3.0 to 59.0.0 apache/fluss-rust#651).🚨 Breaking Changes
None. New connector behind a new
flussfeature (added tospiceddefaults, matching other connectors).📚 Docs
docs/features/fluss-connector.md(setup, both modes, delivery semantics, known limitations, troubleshooting).Request in the official repo
spiceai#9423
👀 Notes for Reviewers
Alpha criteria checklist (
docs/criteria/connectors/alpha.md):table.log.ttl; KV-snapshot read not yet in fluss-rs), partition set fixed at stream start, no auth params, git-pinned fluss-rs until an Arrow ≥58 releasedocs/features/fluss-connector.md)Process notes for the eventual upstream submission (per CONTRIBUTING.md):
make signoffon a Linux dev machine to attest the pushed commit (fmt/clippy/test for the changed crates were run in-container for this draft:cargo fmt --check,cargo clippy --all-targets -D warnings,cargo test -p connector-fluss).Review focus:
stream.rsoffset/readiness accounting (watermark-exclusive vs last-offset-inclusive), the truncation-recovery semantics per mode, and the committer ordering contract inlib.rs.🤖 Generated with Claude Code