Skip to content

Readd Confluent Kafka transport driver (rebased on master, working on released confluent-kafka)#679

Merged
wbarnha merged 29 commits into
masterfrom
claude/faust-prs-sync-fixes-63nsnu
Jul 17, 2026
Merged

Readd Confluent Kafka transport driver (rebased on master, working on released confluent-kafka)#679
wbarnha merged 29 commits into
masterfrom
claude/faust-prs-sync-fixes-63nsnu

Conversation

@wbarnha

@wbarnha wbarnha commented Jul 16, 2026

Copy link
Copy Markdown
Member

Description

Reintroduces the confluent transport driver (faust.transport.drivers.confluent), superseding the stale 2022 draft #418. That PR had drifted years behind master and depended on an unreleased fork of confluent-kafka; this branch brings the work up to current master and makes the driver run on the official package.

What's here

  • Registry (faust/transport/drivers/__init__.py): restores the FactoryMapping-based transport registry with aiokafka, kafka and confluent registered. This matches every other faust registry (stores, web/cache/backends, fixups) and keeps driver loading lazy, so the optional confluent_kafka dependency is only imported when the confluent:// transport is actually selected.
  • Driver works on released confluent-kafka: the previous driver called Consumer.io_event_enable(), an eventfd-based notification API that exists only in the unmerged fork stephan-hof/confluent-kafka-python@features/io_event_enable and is absent from every published confluent-kafka. That machinery is removed from AsyncConsumer. It was already unused by the real fetch path — ConfluentConsumerThread.getmany() drives the blocking Consumer.consume() on the dedicated consumer thread via call_thread() — so there is no functional behavior change. poll() is now a thin wrapper over the blocking Consumer.poll().
  • requirements/extras/ckafka.txt now points at the official confluent-kafka>=2.0.0 release instead of the git fork.
  • create_topic retention fix: Consumer.create_topic() computed retention as int(want_seconds(retention) * 1000.0) unconditionally, which crashed on the default retention=None. Now guarded to pass None through, matching the aiokafka driver (its own commit in this branch).
  • Tests rewritten: the old tests/unit/transport/drivers/test_confluent.py was copied wholesale from the aiokafka suite and asserted against methods the confluent driver never had (_fetch_records, transactional producer methods, …), so most of it failed. Replaced with a focused, broker-free suite (57 tests, all passing, <1s) covering server_list, Consumer, AsyncConsumer, ConfluentConsumerThread, Producer, ProducerThread, ProducerProduceFuture and Transport, with the underlying confluent_kafka objects mocked. Includes a regression guard that AsyncConsumer construction never calls the removed io_event_enable.

Status / notes

  • Opened as a draft. Local unit tests and linters (flake8 / isort / black) pass; the driver imports and resolves against confluent-kafka 2.15.0. It has not been exercised against a live broker end-to-end, and the producer's transactional/create_topic paths remain XXX no-ops carried over from the original driver — worth a follow-up before this leaves draft.
  • The branch retains the original Readd Confluent Kafka drivers #418 commit history plus the rebase/merge and the fixes above; recommend squash-merging.

Supersedes #418.


Generated by Claude Code

wbarnha and others added 25 commits December 2, 2022 16:59
Resolve conflict in faust/transport/drivers/__init__.py by keeping the
FactoryMapping-based transport registry (with the confluent driver
registered), consistent with every other faust registry (stores, web
cache backends, fixups) and preserving lazy driver loading so the
optional confluent_kafka dependency is only imported when the confluent
transport is actually selected.
The driver depended on Consumer.io_event_enable(), an eventfd-based
notification API that only exists in the unmerged 2022 fork
stephan-hof/confluent-kafka-python@features/io_event_enable and is
absent from every released confluent-kafka. This made faust[ckafka]
install an abandoned personal fork and the driver unusable on the
official package.

Remove the eventfd notification machinery from AsyncConsumer (eventfd,
io_event_enable, add_reader/__eventfd_ready, the waiters set and the
weakref finalizer) and reduce poll() to a thin wrapper over the blocking
confluent_kafka.Consumer.poll(). This mechanism was already unused by
the real fetch path -- ConfluentConsumerThread.getmany() drives the
blocking Consumer.consume() inside the dedicated consumer thread via
call_thread() -- so no functional behavior changes.

Point requirements/extras/ckafka.txt at the official
confluent-kafka>=2.0.0 release, and drop the now-unused os, struct and
weakref imports plus a dead cast in Consumer.on_stop().
The previous tests/unit/transport/drivers/test_confluent.py (~1375 lines)
was copied wholesale from the aiokafka test suite and asserted against
methods the confluent driver never had (_fetch_records, _max_poll_records,
transactional producer methods that raise NotImplementedError, ...), so
60 of 85 tests failed and several blocked in librdkafka.

Replace it with a focused suite that exercises the driver's actual
surface -- server_list, Consumer, AsyncConsumer, ConfluentConsumerThread,
Producer, ProducerThread, ProducerProduceFuture and Transport -- with the
underlying confluent_kafka Consumer/Producer mocked so no broker is
needed. 56 tests, all passing, runs in <1s. Includes a regression guard
that AsyncConsumer construction never calls the removed io_event_enable.
Consumer.create_topic() computed retention as
int(want_seconds(retention) * 1000.0) unconditionally, so the default
retention=None raised TypeError (None * 1000.0) whenever a topic was
declared without an explicit retention. Guard the conversion the same way
the aiokafka driver does (pass None through), and add a regression test.
confluent-kafka is an optional extra (faust[ckafka]) and is not part of
requirements/test.txt, so it is absent in the CI test matrix. The test
module imports the driver (which imports confluent_kafka) at import time,
which turned every matrix job into a collection error. Guard the module
with pytest.importorskip('confluent_kafka') so it skips cleanly when the
optional dependency is unavailable, and runs in full where it is.
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.10%. Comparing base (c3c4244) to head (e5f5b43).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #679   +/-   ##
=======================================
  Coverage   94.09%   94.10%           
=======================================
  Files         102      102           
  Lines       11108    11107    -1     
  Branches     1198     1198           
=======================================
  Hits        10452    10452           
+ Misses        557      556    -1     
  Partials       99       99           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

wbarnha added 2 commits July 16, 2026 14:23
confluent.py is only importable when the ckafka extra (faust[ckafka]) is
installed, which the CI test environment does not do -- so its tests are
skipped there and the file shows as 0% covered, dragging project/patch
coverage down. Omit it from coverage like the memory driver already is;
the driver's own tests still run wherever confluent-kafka is available.
The confluent readd had switched examples/word_count.py to
'confluent://localhost:9092'. Confluent is an optional, experimental
transport (installed via faust[ckafka]); mainstream examples should use
the default aiokafka transport. Revert the example broker to
'kafka://localhost:9092'.
@wbarnha
wbarnha marked this pull request as ready for review July 17, 2026 02:43
@wbarnha
wbarnha merged commit a413a74 into master Jul 17, 2026
22 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