feat(connectors): Add Iggy source connector - #3886
Open
jiengup wants to merge 1 commit into
Open
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3886 +/- ##
============================================
- Coverage 82.96% 82.92% -0.05%
Complexity 1339 1339
============================================
Files 1218 1219 +1
Lines 165595 165925 +330
Branches 133910 134365 +455
============================================
+ Hits 137394 137592 +198
+ Misses 24540 24529 -11
- Partials 3661 3804 +143
🚀 New features to boost your workflow:
|
jiengup
force-pushed
the
iggy-source-connector
branch
from
August 15, 2026 12:58
33b84a5 to
68ed073
Compare
jiengup
marked this pull request as ready for review
August 15, 2026 13:08
Contributor
Author
Replicates a topic from an upstream Iggy cluster with per-partition offset tracking.
jiengup
force-pushed
the
iggy-source-connector
branch
from
August 15, 2026 13:21
68ed073 to
37116c6
Compare
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.
Which issue does this PR address?
Closes #3869
Relates to #3764
Rationale
Cross-cluster topic replication had no first-class path: the connectors subsystem's sinks and sources target external systems (Postgres, Elasticsearch, HTTP, etc.), and the runtime itself connects to a single Iggy cluster. Cross-cluster sync (disaster recovery, data migration, federated setups) therefore required external tooling. This PR adds
iggy_source: a source connector that replicates a topic from an upstream Iggy cluster into the cluster the connectors runtime is connected to.What changed?
Previously there was no way to sync two Iggy clusters through connectors. Now
core/connectors/sources/iggy_sourceconnects to the upstream cluster and discovers all partitions inopen(), polls each partition with an explicitpoll_messages(offset)call per cycle, and passes payloads and user headers through asSchema::Rawwhile preserving upstream message IDs for downstream deduplication. Sync progress (per-partition confirmed offsets, total synced, error count) is persisted in connector state, and restarts resume fromsaved_offset + 1without replaying history.Design tradeoffs
poll_messagesAPI instead of the high-levelIggyConsumer: crash recovery requires per-partition starting offsets, butIggyConsumeraccepts only one globalpolling_strategyat construction time, which cannot express per-partition offsets. The low-level API allows passingPollingStrategy::offset(saved + 1)per partition explicitly.JoinConsumerGroupResponseis empty (no member id returned), so assignment-driven multi-instance scaling is not expressible through the low-level API. Revisit once the server exposes member ids.offset(saved + 1)directly rather thanfirst()plus in-memory filtering, keeping restart cost O(batch) instead of O(topic history).Schema::Rawbyte passthrough: no decode/encode; payloads, user headers, and message IDs are preserved verbatim, avoiding re-serialization cost and format corruption.InvalidOffsetreset: when upstream retention expires a saved offset, the partition is warned and reset toinitial_offset(earliest/latest/ numeric) without blocking other partitions.exponential_backoff+jitter(starting atretry_interval, capped atmax_retry_interval); the failure counter is anAtomicU64and resets on any successful cycle.Persisted state design
rmp_serde) viaConnectorState::serialize/deserialize; the runtime persists it with the existingFileStateProviderto{state_path}/source_{key}.state, inheriting its atomic-rename + fsync protocol and0o600permissions. The state save path is untouched.u64per partition plus two counters, O(partition count), so rewriting the whole file every batch is cheap.initial_offsetapplies only to partitions with no saved entry (first run or newly added partitions); existing entries always win.errors_countincrements and offset resets ride the same state channel, and state is returned even on empty-message cycles (e.g., connection-failure cycles), so error accounting and offset resets survive restarts.Crash recovery analysis
errors_countincremented, offsets not advanced, exponential backoff with jitter; the SDK client reconnects automaticallyproducer.sendfails → state not saved; the connector's in-memory offsets have advanced, so that batch is dropped for the lifetime of the process, this can be fixed when #3855 is merged; a connector restart replays from the stale state file → at-least-onceInvalidOffset→ partition reset toinitial_offset; expired messages are unrecoverable (inherent to offset-based replication)Sync semantics
Local Execution
cargo fmt --all,cargo sort --no-format --workspace,cargo clippy -p iggy_connector_iggy_source --all-targets --all-features -- -D warnings,cargo test -p iggy_connector_iggy_source(11 unit tests: state restore, serialization round-trip, config defaults, initial_offset parsing, next_strategy jump, connection-string redaction), taplo, markdownlint, license-headers, cargo machetecargo test -p integration -- connectors::iggy_sourceEnd-to-end verification (two real server-ng instances + runtime)
iggy-server(TCP 8090/8091) +iggy-connectors; a CLI producer continuously emitted messages with headersproducer:string,seq:uint64), and message IDs are byte-identicalRestored state ... Offsets: {0: 4}, messages synced: 5→ only the 3 missing messages were synced, the first 5 with zero duplicatesAI Usage