Skip to content

fix: consolidate streaming, Arrow, and event contracts#633

Merged
cofin merged 10 commits into
mainfrom
feat/c4-consolidation
Jul 10, 2026
Merged

fix: consolidate streaming, Arrow, and event contracts#633
cofin merged 10 commits into
mainfrom
feat/c4-consolidation

Conversation

@cofin

@cofin cofin commented Jul 9, 2026

Copy link
Copy Markdown
Member

Summary

  • align bounded row-stream cleanup and transaction behavior across adapters
  • consolidate Arrow fallback behavior and adapter contract cleanup
  • define canonical event transports: notify, notify_queue, poll_queue, aq, and txeventq
  • add typed adapter event configuration and accurate durable-delivery documentation

Review fixes

  • context-manager failures roll back and cleanup TypeError is not retried
  • legacy duck-typed stream sources with close() still clean up correctly
  • mysql-connector early close consumes unread rows without replacing an active transaction session
  • retired event names fail explicitly with canonical migration guidance rather than silently selecting polling
  • adapter events_backend features are honored when extension configuration does not override them
  • native event fixtures remain collected and Python 3.14 type introspection remains supported

Stack

This is the base PR for #635, which contains listener lifecycle, batching, polling/recovery, and final transport documentation.

Validation

  • focused stream, Arrow, event, mysql-connector, and configuration tests
  • Ruff, mypy, and pyright
  • full GitHub unit/integration matrix on Python 3.10-3.14
  • docs, source distribution, pure wheel, MyPyC wheel, and package integrity checks

All GitHub checks are green.

@codecov-commenter

codecov-commenter commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.41916% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.77%. Comparing base (27863f0) to head (1895c42).

Files with missing lines Patch % Lines
sqlspec/extensions/events/_channel.py 83.33% 3 Missing and 2 partials ⚠️
sqlspec/adapters/psycopg/core.py 50.00% 2 Missing and 2 partials ⚠️
sqlspec/adapters/asyncpg/core.py 50.00% 1 Missing and 1 partial ⚠️
sqlspec/adapters/mysqlconnector/core.py 90.00% 0 Missing and 2 partials ⚠️
sqlspec/adapters/psqlpy/core.py 50.00% 1 Missing and 1 partial ⚠️
sqlspec/adapters/bigquery/driver.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #633      +/-   ##
==========================================
- Coverage   75.79%   75.77%   -0.03%     
==========================================
  Files         473      473              
  Lines       65121    65170      +49     
  Branches     9713     9723      +10     
==========================================
+ Hits        49361    49383      +22     
- Misses      12518    12530      +12     
- Partials     3242     3257      +15     
Flag Coverage Δ
integration 59.64% <78.44%> (-0.04%) ⬇️
py3.10 74.03% <90.41%> (-0.01%) ⬇️
py3.11 74.05% <90.41%> (-0.01%) ⬇️
py3.12 74.04% <90.41%> (-0.01%) ⬇️
py3.13 74.04% <90.41%> (-0.01%) ⬇️
py3.14 74.97% <89.33%> (-0.01%) ⬇️
unit 62.51% <84.43%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sqlspec/adapters/adbc/config.py 92.72% <100.00%> (ø)
sqlspec/adapters/adbc/driver.py 80.74% <100.00%> (ø)
sqlspec/adapters/aiomysql/config.py 93.54% <100.00%> (ø)
sqlspec/adapters/aiomysql/core.py 73.85% <100.00%> (-0.33%) ⬇️
sqlspec/adapters/aiosqlite/config.py 94.09% <100.00%> (ø)
sqlspec/adapters/aiosqlite/core.py 89.44% <100.00%> (-0.51%) ⬇️
sqlspec/adapters/arrow_odbc/driver.py 76.82% <100.00%> (ø)
sqlspec/adapters/asyncmy/config.py 90.59% <100.00%> (ø)
sqlspec/adapters/asyncmy/core.py 71.87% <100.00%> (-0.35%) ⬇️
sqlspec/adapters/asyncpg/config.py 92.43% <100.00%> (ø)
... and 31 more

... and 2 files with indirect coverage changes

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

@cofin
cofin marked this pull request as draft July 10, 2026 00:24
@cofin cofin changed the title fix: align streaming and Arrow contracts fix: consolidate streaming, Arrow, and event contracts Jul 10, 2026
@cofin
cofin marked this pull request as ready for review July 10, 2026 04:58
@cofin
cofin merged commit 7855fd0 into main Jul 10, 2026
24 checks passed
@cofin
cofin deleted the feat/c4-consolidation branch July 10, 2026 05:27
cofin added a commit that referenced this pull request Jul 10, 2026
## Summary

- dedicate one long-lived listener resource per native backend instance
while publishers use short pooled sessions
- add typed sync/async `publish_many()` with ordered IDs, explicit
grouped transactions, and an ordered fallback
- bulk-insert durable rows and emit one compact `{marker_id,
batch_size}` wakeup marker per channel atomically
- recover missing markers through independent `event_poll_interval`
reconciliation and immediately drain every recovered row
- cancel async listener waits concurrently, bound sync joins, and
prevent table polling faster than the configured interval
- preserve durable batch delivery order and add
`SQLSpecChannelsBackend.publish_many(data, channels)` for consumer
integration
- document canonical transport semantics, adapter support, connection
ownership, and recovery behavior

## Integration

This PR now targets `main` directly after #633 and #634 merged. Its
event-only commits are rebased onto merge commit `ff0b8cb51`, so the
final branch validates the consolidated C4 contracts and lazy-typing
implementation together.

## Correctness notes

Durable rows are the source of truth. Native markers are wakeup hints,
not batch envelopes. Row insertion and marker publication share one
explicit transaction, marker publication failure rolls back the rows,
duplicate markers are suppressed, and one reconciliation timeout enters
drain mode until the queue is empty. Durable transports remain
competing-consumer queues rather than browser fan-out.

JSON payloads and metadata remain native values through batch parameter
preparation so adapter-specific encoders receive the same input shape as
single-event publication.

## Validation

- listener lifecycle and native backend factory tests
- 1,000-event batch, ordering, transaction rollback, autocommit
restoration, session/statement count, empty/fallback, marker
loss/duplication, polling, and metadata tests
- real asyncpg, psqlpy, and psycopg PostgreSQL integration coverage for
single-plus-batch IDs, delivery order, payloads, and metadata
- SQLite durable order and Litestar channel integrations
- focused event suite, Ruff, mypy, pyright, docs, and docs linkcheck
- full GitHub CI is running for the final post-merge rebased commit
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.

2 participants