mq-bridge-py-basic 0.3.7__tar.gz → 0.3.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.gitignore +4 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/CLAUDE.md +1 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/Cargo.lock +30 -10
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/Cargo.toml +2 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/PKG-INFO +1 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/README.md +9 -4
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/REFERENCE.md +107 -33
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/benches/ETL_BENCHMARKS.md +5 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq-bridge.schema.json +54 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq_bridge/config.py +2 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq_bridge/config.pyi +37 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/Cargo.toml +17 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/src/lib.rs +70 -9
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/httparena/README.md +1 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/httparena/frameworks/mq-bridge-py/server.py +1 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/checkpoint.rs +24 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/clickhouse.rs +4 -3
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/file/mod.rs +222 -57
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/file/tests.rs +275 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/http/publisher.rs +23 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/http/stream.rs +9 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/framed.rs +81 -13
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mod.rs +3 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/consumer.rs +14 -9
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/readers.rs +24 -13
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/nats.rs +33 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/object_store.rs +31 -24
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/mod.rs +69 -21
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/replication.rs +83 -23
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/redis_streams.rs +130 -19
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/sqlx/dedup.rs +23 -3
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/sqlx/mod.rs +160 -40
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/sqlx/tests.rs +40 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/reader.rs +17 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/stream_buffer.rs +34 -13
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/zeromq/omq.rs +12 -3
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/zeromq/zmq.rs +25 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/errors.rs +18 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/lib.rs +4 -1
- mq_bridge_py_basic-0.3.9/src/middleware/compression.rs +314 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/deduplication.rs +187 -14
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/dlq.rs +141 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/encryption.rs +133 -24
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/mod.rs +8 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/retry.rs +90 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/schema.rs +3 -5
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/models.rs +161 -4
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/route.rs +34 -2
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/support/compression.rs +1 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/support/connection_registry.rs +3 -3
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/support/crypto.rs +3 -5
- mq_bridge_py_basic-0.3.9/src/support/crypto_envelope.rs +17 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/support/mod.rs +1 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/traits.rs +6 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mariadb.rs +16 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mod.rs +32 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mongodb.rs +40 -1
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mysql.rs +137 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/nats.rs +48 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/object_store.rs +102 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/postgres_cdc.rs +113 -0
- mq_bridge_py_basic-0.3.9/tests/integration/redis_streams.rs +434 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration_test.rs +95 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/reference_docs_test.rs +134 -175
- mq_bridge_py_basic-0.3.7/tests/integration/redis_streams.rs +0 -227
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/benchmark.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/ci.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/ibm-mq.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/node.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/publish-node.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/publish-python.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/python.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/release.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/.github/workflows/test-matrix.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/ARCHITECTURE.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/CONFIGURATION.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/CONTRIBUTING.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/LICENSE +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/benches/performance_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/benches/router_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/benches/zeromq_backends.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/bindings-common/Cargo.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/bindings-common/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/bindings-common/src/logging.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/build.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/examples/ipc_worker_queue.yaml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq_bridge/__init__.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq_bridge/__init__.pyi +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/mq_bridge/py.typed +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/package-lock.json +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/example.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/bench_memory.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/consume_pull.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/dlt_source.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/json_route.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/memory.yaml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/examples/raw_route.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/pyproject-basic.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_config_types.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_logging.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_packaging.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_public_api.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/tests/test_routes.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/python/mq-bridge-py/uv.lock +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/benches/metadata_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/http/http_flamegraph.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/analysis/http/run_http_ladder.sh +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/ci/format_bench_output.sh +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/README.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/postgres.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/seed.sql +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/techempower/verify.sh +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/the-benchmarker/README.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/canonical_message.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/command_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/amqp.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/aws.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/grpc.proto +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/grpc.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/http/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/http/tests.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/ibm_mq.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/kafka.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/endpoint.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/ipc_unix.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/ipc_windows.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/memory_transport.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/memory/transport.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/dedup.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/publisher.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mongodb/tests.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/poll.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/VENDORED.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/pgoutput/values.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/postgres/state.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/sled.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/fanout.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/null.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/request.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/response.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/static_endpoint.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/structural/switch.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/websocket.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/zeromq/codec.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/endpoints/zeromq/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/event_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/event_store.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/extensions.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/buffer.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/cookie_jar.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/delay.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/limiter.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/metrics.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/random_panic.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/coerce.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/compiled.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/error.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/path.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/transform/tests.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/middleware/weak_join.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/outcomes.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/publisher.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/response.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/support/interpolation.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/test_utils.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/src/type_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/README.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/armature_integration.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/amqp.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/aws.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/clickhouse.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/config.toml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/amqp.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/aws.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/clickhouse.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm_mq.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/kafka-tls.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/kafka.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mariadb.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mongodb.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mosquitto.conf +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mq_init.mqsc +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mqtt.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/mysql.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/nats.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/object_store.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/postgres.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/docker-compose/redis.yml +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/file.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/grpc.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/grpc_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/http.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/http_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/ibm_mq.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/ipc.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/kafka.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/kafka_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/logic_test.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/memory.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mongodb_raw.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mongodb_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/performance_static.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/postgres.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/route.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/scripts/gen_certs.sh +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/sqlite.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/tls_helpers.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/websocket.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/integration/zeromq.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/memory_leak_test.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/ref_test.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/sqlite_test.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/tls_example.rs +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/unit_tests.md +0 -0
- {mq_bridge_py_basic-0.3.7 → mq_bridge_py_basic-0.3.9}/tests/websocket_test.rs +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **Looking for what middleware or structural endpoints exist, and how to configure them?**
|
|
4
4
|
> [REFERENCE.md](REFERENCE.md) is the complete, authoritative list — every middleware
|
|
5
5
|
> (`retry`, `dlq`, `transform`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
|
|
6
|
-
> `cookie_jar`, `encryption`, `metrics`, `random_panic`, `custom`) and every structural endpoint (`ref`,
|
|
6
|
+
> `cookie_jar`, `encryption`, `compression`, `metrics`, `random_panic`, `custom`) and every structural endpoint (`ref`,
|
|
7
7
|
> `fanout`, `switch`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
|
|
8
8
|
> `custom`), each with its fields, defaults, and a working YAML example. Do not infer these
|
|
9
9
|
> from the enum definitions in `models.rs`; the reference records the behaviour and the
|
|
@@ -2976,6 +2976,15 @@ dependencies = [
|
|
|
2976
2976
|
"windows-link",
|
|
2977
2977
|
]
|
|
2978
2978
|
|
|
2979
|
+
[[package]]
|
|
2980
|
+
name = "libmimalloc-sys"
|
|
2981
|
+
version = "0.1.49"
|
|
2982
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2983
|
+
checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
|
|
2984
|
+
dependencies = [
|
|
2985
|
+
"cc",
|
|
2986
|
+
]
|
|
2987
|
+
|
|
2979
2988
|
[[package]]
|
|
2980
2989
|
name = "libmqm-constants"
|
|
2981
2990
|
version = "0.8.4"
|
|
@@ -3200,6 +3209,15 @@ dependencies = [
|
|
|
3200
3209
|
"sketches-ddsketch",
|
|
3201
3210
|
]
|
|
3202
3211
|
|
|
3212
|
+
[[package]]
|
|
3213
|
+
name = "mimalloc"
|
|
3214
|
+
version = "0.1.52"
|
|
3215
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3216
|
+
checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
|
|
3217
|
+
dependencies = [
|
|
3218
|
+
"libmimalloc-sys",
|
|
3219
|
+
]
|
|
3220
|
+
|
|
3203
3221
|
[[package]]
|
|
3204
3222
|
name = "mime"
|
|
3205
3223
|
version = "0.3.17"
|
|
@@ -3330,7 +3348,7 @@ dependencies = [
|
|
|
3330
3348
|
|
|
3331
3349
|
[[package]]
|
|
3332
3350
|
name = "mq-bridge"
|
|
3333
|
-
version = "0.3.
|
|
3351
|
+
version = "0.3.9"
|
|
3334
3352
|
dependencies = [
|
|
3335
3353
|
"aes-gcm",
|
|
3336
3354
|
"anyhow",
|
|
@@ -3411,7 +3429,7 @@ dependencies = [
|
|
|
3411
3429
|
|
|
3412
3430
|
[[package]]
|
|
3413
3431
|
name = "mq-bridge-bindings-common"
|
|
3414
|
-
version = "0.3.
|
|
3432
|
+
version = "0.3.9"
|
|
3415
3433
|
dependencies = [
|
|
3416
3434
|
"anyhow",
|
|
3417
3435
|
"fast-uuid-v7",
|
|
@@ -3425,12 +3443,13 @@ dependencies = [
|
|
|
3425
3443
|
|
|
3426
3444
|
[[package]]
|
|
3427
3445
|
name = "mq-bridge-node"
|
|
3428
|
-
version = "0.3.
|
|
3446
|
+
version = "0.3.9"
|
|
3429
3447
|
dependencies = [
|
|
3430
3448
|
"anyhow",
|
|
3431
3449
|
"async-trait",
|
|
3432
3450
|
"bytes",
|
|
3433
3451
|
"fast-uuid-v7",
|
|
3452
|
+
"mimalloc",
|
|
3434
3453
|
"mq-bridge",
|
|
3435
3454
|
"mq-bridge-bindings-common",
|
|
3436
3455
|
"napi",
|
|
@@ -3446,12 +3465,13 @@ dependencies = [
|
|
|
3446
3465
|
|
|
3447
3466
|
[[package]]
|
|
3448
3467
|
name = "mq-bridge-py"
|
|
3449
|
-
version = "0.3.
|
|
3468
|
+
version = "0.3.9"
|
|
3450
3469
|
dependencies = [
|
|
3451
3470
|
"anyhow",
|
|
3452
3471
|
"async-trait",
|
|
3453
3472
|
"bytes",
|
|
3454
3473
|
"fast-uuid-v7",
|
|
3474
|
+
"mimalloc",
|
|
3455
3475
|
"mq-bridge",
|
|
3456
3476
|
"mq-bridge-bindings-common",
|
|
3457
3477
|
"pyo3",
|
|
@@ -3725,9 +3745,9 @@ dependencies = [
|
|
|
3725
3745
|
|
|
3726
3746
|
[[package]]
|
|
3727
3747
|
name = "omq-proto"
|
|
3728
|
-
version = "0.
|
|
3748
|
+
version = "0.25.0"
|
|
3729
3749
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3730
|
-
checksum = "
|
|
3750
|
+
checksum = "856d18f6b58f39153fcf0b574efe3f04362ff44d3a46829eb984c1f9ef2d121c"
|
|
3731
3751
|
dependencies = [
|
|
3732
3752
|
"bytes",
|
|
3733
3753
|
"patricia_tree",
|
|
@@ -3739,9 +3759,9 @@ dependencies = [
|
|
|
3739
3759
|
|
|
3740
3760
|
[[package]]
|
|
3741
3761
|
name = "omq-tokio"
|
|
3742
|
-
version = "0.20.
|
|
3762
|
+
version = "0.20.3"
|
|
3743
3763
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3744
|
-
checksum = "
|
|
3764
|
+
checksum = "98aaa33702e7d723de268dd9fe725f93d469afef3f1bedb14cfa7f579f61a7b7"
|
|
3745
3765
|
dependencies = [
|
|
3746
3766
|
"arc-swap",
|
|
3747
3767
|
"bytes",
|
|
@@ -7191,9 +7211,9 @@ dependencies = [
|
|
|
7191
7211
|
|
|
7192
7212
|
[[package]]
|
|
7193
7213
|
name = "yring"
|
|
7194
|
-
version = "0.3.
|
|
7214
|
+
version = "0.3.11"
|
|
7195
7215
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
7196
|
-
checksum = "
|
|
7216
|
+
checksum = "f8545becda6379f37e13fbdf5d9de464849bdd1565a995368648f11fe9d96d13"
|
|
7197
7217
|
dependencies = [
|
|
7198
7218
|
"loom",
|
|
7199
7219
|
]
|
|
@@ -16,7 +16,7 @@ members = ["bindings-common", "python/mq-bridge-py"]
|
|
|
16
16
|
resolver = "2"
|
|
17
17
|
|
|
18
18
|
[workspace.package]
|
|
19
|
-
version = "0.3.
|
|
19
|
+
version = "0.3.9"
|
|
20
20
|
|
|
21
21
|
[workspace.dependencies]
|
|
22
22
|
anyhow = "1.0"
|
|
@@ -210,7 +210,7 @@ float-roundtrip = ["serde_json/float_roundtrip"]
|
|
|
210
210
|
# runtime the client is loaded lazily only when an ibm-mq endpoint is opened
|
|
211
211
|
# (clear error if the client isn't installed). Use `ibm-mq-static` instead for
|
|
212
212
|
# static linking.
|
|
213
|
-
full = ["middleware", "mongodb", "kafka", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "redis-streams", "sled", "grpc", "sqlx", "clickhouse", "websocket", "postgres-cdc", "object-store", "rustls-aws-lc", "ibm-mq"]
|
|
213
|
+
full = ["middleware", "mongodb", "kafka", "amqp", "nats", "mqtt", "http", "aws", "zeromq", "zeromq-omq", "redis-streams", "sled", "grpc", "sqlx", "clickhouse", "websocket", "postgres-cdc", "object-store", "rustls-aws-lc", "ibm-mq"]
|
|
214
214
|
|
|
215
215
|
# Endpoints that build across most OS targets (glibc/musl/Alpine, macOS,
|
|
216
216
|
# Windows, aarch64/armv7) without a special toolchain — no librdkafka, protoc,
|
|
@@ -33,7 +33,7 @@ If you need to move data reliably between systems and you write code (Rust, Pyth
|
|
|
33
33
|
* **TLS everywhere, one config shape**: a single `TlsConfig` block (CA bundle, client cert/key for mTLS, insecure-skip) is reused across transports.
|
|
34
34
|
* **Self-hosted, no daemon**: generate config in the optional UI, paste it into your code, run it in-process. No hosted control plane, no separate scheduler.
|
|
35
35
|
|
|
36
|
-
> **Throughput & footprint.** In our own benchmarks, the same engine — driven the zero-code way through [`mq-bridge-app`](https://github.com/marcomq/mq-bridge-app) —
|
|
36
|
+
> **Throughput & footprint.** In our own benchmarks, the same engine — driven the zero-code way through [`mq-bridge-app`](https://github.com/marcomq/mq-bridge-app) — on a CSV→JSONL file conversion (1,000,000 mixed-type rows, ~116 MiB) sustained **1,133,786 rows/s** at ~22 MiB, about **~58x faster** and **~20x leaner in memory** than Meltano (`tap-csv` → `target-jsonl`, ~19,500 rows/s / ~444 MiB). Full setup, methodology, and the exact parameters are in [`benches/ETL_BENCHMARKS.md`](benches/ETL_BENCHMARKS.md).
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
## Language Bindings
|
|
@@ -306,9 +306,14 @@ server-side (default one-hour window) — `insert_deduplication_token` lets you
|
|
|
306
306
|
mq-bridge does not set one, so rely on `ReplacingMergeTree` for logical dedup and treat block-level
|
|
307
307
|
dedup only as retry-safety.
|
|
308
308
|
|
|
309
|
-
**Postgres CDC — deterministic id + `postgres.key`.** The `postgres_cdc` source
|
|
310
|
-
durable
|
|
311
|
-
|
|
309
|
+
**Postgres CDC — deterministic id + `postgres.key`.** The `postgres_cdc` source resumes from the slot's
|
|
310
|
+
durable `confirmed_flush_lsn`. In-band standby feedback is asynchronous and is *not* flushed when the
|
|
311
|
+
stream stops, so the last acks are made durable by the consumer's `Drop`, which stops the stream and
|
|
312
|
+
advances the slot synchronously. Re-delivery is therefore avoided only on a restart that actually runs
|
|
313
|
+
that teardown — a host process that exits without dropping the route (or one on a current-thread Tokio
|
|
314
|
+
runtime, where the blocking advance is skipped) replays everything since the last asynchronous feedback
|
|
315
|
+
tick. Set `checkpoint_store` to a `file://` path for a second, per-ack durable position that survives
|
|
316
|
+
teardown regardless. Treat the source as at-least-once and make the sink idempotent. Each change event
|
|
312
317
|
carries the full row (so the primary key is in the payload), `postgres.lsn` (a monotonic version),
|
|
313
318
|
`postgres.operation`/`schema`/`table`, and — when the table has a primary key / replica identity —
|
|
314
319
|
`postgres.key` (the key value). The event's `message_id` is a stable hash of `schema.table + key +
|
|
@@ -17,7 +17,7 @@ endpoints, shape routing, or terminate a request. Data endpoints (`kafka`, `nats
|
|
|
17
17
|
Middleware attaches to an endpoint via a `middlewares:` list, on the **input**, the
|
|
18
18
|
**output**, or both:
|
|
19
19
|
|
|
20
|
-
```yaml
|
|
20
|
+
```yaml route
|
|
21
21
|
my_route:
|
|
22
22
|
input:
|
|
23
23
|
middlewares:
|
|
@@ -38,6 +38,11 @@ layer and sees the failures of the ones before it.** Put `dlq` last.
|
|
|
38
38
|
**Input (consumer) middlewares are applied in reverse, so the *first* entry is outermost**
|
|
39
39
|
and runs first on an incoming message.
|
|
40
40
|
|
|
41
|
+
**Consequence: a route that reads back what another route wrote needs the *reversed* list.**
|
|
42
|
+
Writing with `[compression, encryption]` produces `compress(encrypt(payload))`; a reader
|
|
43
|
+
given that same list would try to decrypt first and fail. The reading route must say
|
|
44
|
+
`[encryption, compression]`. The lists mirror — they are not copied.
|
|
45
|
+
|
|
41
46
|
> This is asserted by `route::tests::test_dlq_and_retry_batch_integration`,
|
|
42
47
|
> `middleware::transform::tests::test_rejected_message_reaches_the_dlq_through_the_config_wiring`,
|
|
43
48
|
> and `reference_docs_test::publisher_middleware_wraps_last_entry_outermost`, and is
|
|
@@ -58,17 +63,28 @@ middlewares:
|
|
|
58
63
|
| [`retry`](#retry) | – | ✅ | – | Exponential-backoff retry of failed sends |
|
|
59
64
|
| [`dlq`](#dlq) | – | ✅ | – | Route permanently-failed messages to another endpoint |
|
|
60
65
|
| [`transform`](#transform) | ✅ | ✅ | – | Declarative JSON mapping, coercion, validation |
|
|
61
|
-
| [`deduplication`](#deduplication) | ✅ | – | `dedup` | Drop repeated
|
|
66
|
+
| [`deduplication`](#deduplication) | ✅ | – | `dedup` | Drop repeated keys within a TTL |
|
|
62
67
|
| [`weak_join`](#weak_join) | ✅ | – | – | Correlate and join related messages |
|
|
63
68
|
| [`buffer`](#buffer) | ✅ | ✅ | – | Coalesce single sends into batches |
|
|
64
69
|
| [`limiter`](#limiter) | ✅ | ✅ | – | Cap throughput to a message rate |
|
|
65
70
|
| [`delay`](#delay) | ✅ | ✅ | – | Fixed delay per receive/send |
|
|
66
71
|
| [`cookie_jar`](#cookie_jar) | ✅ | ✅ | – | Persist HTTP cookies / session values across messages |
|
|
67
72
|
| [`encryption`](#encryption) | ✅ | ✅ | `encryption` | AEAD-encrypt payloads on send, decrypt on receive |
|
|
73
|
+
| [`compression`](#compression) | ✅ | ✅ | `compression` | Compress payloads on send, decompress on receive |
|
|
68
74
|
| [`metrics`](#metrics) | ✅ | ✅ | `metrics` | Emit throughput/latency/error metrics |
|
|
69
75
|
| [`random_panic`](#random_panic) | ✅ | ✅ | – | Fault injection for testing |
|
|
70
76
|
| [`custom`](#custom-middleware) | ✅ | ✅ | – | Your own middleware via a registered factory |
|
|
71
77
|
|
|
78
|
+
> **Two kinds of compression.** The [`compression`](#compression) *middleware* compresses
|
|
79
|
+
> each message **payload** on any transport and decompresses it on the far side. Separately,
|
|
80
|
+
> the batch `compression` *field* on the `file` and `object_store` endpoints (`none` / `gzip`
|
|
81
|
+
> / `lz4` / `zstd`, same `compression` feature) compresses whole write batches so the file
|
|
82
|
+
> stays decodable with `zcat` / `lz4 -d`. Use the field for CLI-readable data at rest, the
|
|
83
|
+
> middleware for over-the-wire payloads. Don't stack either compression with the
|
|
84
|
+
> [`encryption`](#encryption) middleware on the same route — ciphertext does not compress; for
|
|
85
|
+
> compressed-and-encrypted data at rest use the endpoints' own `compression`/`encryption`
|
|
86
|
+
> fields (compress-then-encrypt per batch).
|
|
87
|
+
|
|
72
88
|
**Putting a middleware on the wrong side behaves in two different ways**, so check the table
|
|
73
89
|
above rather than assuming:
|
|
74
90
|
|
|
@@ -92,7 +108,7 @@ Retries failed sends with exponential backoff. Output only.
|
|
|
92
108
|
| `max_interval_ms` | integer | `5000` |
|
|
93
109
|
| `multiplier` | float | `2.0` |
|
|
94
110
|
|
|
95
|
-
```yaml
|
|
111
|
+
```yaml middleware
|
|
96
112
|
- retry: { max_attempts: 5, initial_interval_ms: 200, max_interval_ms: 10000, multiplier: 2.0 }
|
|
97
113
|
```
|
|
98
114
|
|
|
@@ -108,7 +124,7 @@ Sends permanently-failed messages to a separate endpoint instead of failing the
|
|
|
108
124
|
|---|---|---|
|
|
109
125
|
| `endpoint` | Endpoint | yes |
|
|
110
126
|
|
|
111
|
-
```yaml
|
|
127
|
+
```yaml middleware
|
|
112
128
|
- dlq:
|
|
113
129
|
endpoint:
|
|
114
130
|
file: { path: "dead-letters.jsonl" }
|
|
@@ -150,7 +166,7 @@ validation — over a single parse. Input and output.
|
|
|
150
166
|
`schema` and `schema_file` are mutually exclusive. A mapping rule is either a bare path
|
|
151
167
|
string or `{ path, default, required }`.
|
|
152
168
|
|
|
153
|
-
```yaml
|
|
169
|
+
```yaml middleware
|
|
154
170
|
- transform:
|
|
155
171
|
mapping:
|
|
156
172
|
firstName: "$.first_name"
|
|
@@ -174,7 +190,7 @@ lossless ones: `string → integer`, `string → number`, `string → boolean` (
|
|
|
174
190
|
A field carrying a JSON document as a string is decoded by `contentMediaType`, following
|
|
175
191
|
JSON Schema 2020-12:
|
|
176
192
|
|
|
177
|
-
```yaml
|
|
193
|
+
```yaml middleware
|
|
178
194
|
- transform:
|
|
179
195
|
schema:
|
|
180
196
|
type: object
|
|
@@ -216,7 +232,7 @@ with neither stage configured leaves the payload untouched without parsing it.
|
|
|
216
232
|
|
|
217
233
|
### `deduplication`
|
|
218
234
|
|
|
219
|
-
Drops messages whose
|
|
235
|
+
Drops messages whose key was already seen within the TTL. Input only. Requires the `dedup`
|
|
220
236
|
feature (pulls `sled`).
|
|
221
237
|
|
|
222
238
|
| Field | Type | Required |
|
|
@@ -224,13 +240,22 @@ feature (pulls `sled`).
|
|
|
224
240
|
| `store` | string | one of `store`/`sled_path` |
|
|
225
241
|
| `sled_path` | string | one of `store`/`sled_path` |
|
|
226
242
|
| `ttl_seconds` | integer | yes |
|
|
243
|
+
| `key` | string | no (defaults to `message_id`) |
|
|
244
|
+
|
|
245
|
+
`key` is an interpolation template (see `${namespace:selector}`), typically
|
|
246
|
+
`"${payload:order_id}"`. Without it the key is the `message_id`, which most sources
|
|
247
|
+
regenerate on every read — so re-reading the same source deduplicates nothing and only
|
|
248
|
+
in-flight redeliveries are suppressed. Set `key` to a business key whenever you need
|
|
249
|
+
dedup to survive a re-read.
|
|
227
250
|
|
|
228
251
|
`store` selects the backend by URL scheme:
|
|
229
252
|
|
|
230
253
|
- `sled:///path` (or a bare path) — a local sled database; per-process, not cluster-wide.
|
|
231
254
|
- `mongodb://host/db[/collection]` — a shared collection, so multiple instances of a route
|
|
232
|
-
deduplicate against one another. Requires the `mongodb` feature.
|
|
233
|
-
|
|
255
|
+
deduplicate against one another. Requires the `mongodb` feature. Expiry is judged on read,
|
|
256
|
+
so a `ttl_seconds` boundary is honoured exactly; the TTL index only reclaims space
|
|
257
|
+
afterwards (MongoDB's sweep can lag by up to a minute). The collection defaults to
|
|
258
|
+
`mqb_dedup_<route>`. Point it at the same
|
|
234
259
|
deployment your sink already uses to avoid running extra infrastructure.
|
|
235
260
|
- `postgres|mysql|mariadb|sqlite://…[/table]` — a shared SQL table (`dedup_key` PK,
|
|
236
261
|
`expire_at`), so multiple instances deduplicate against one another. Requires the `sqlx`
|
|
@@ -239,18 +264,22 @@ feature (pulls `sled`).
|
|
|
239
264
|
|
|
240
265
|
`sled_path` is the legacy spelling of a local sled store and is equivalent to `store: "sled://<path>"`.
|
|
241
266
|
|
|
242
|
-
```yaml
|
|
267
|
+
```yaml middleware
|
|
243
268
|
- deduplication: { store: "sled:///var/lib/mq-bridge/dedup", ttl_seconds: 3600 }
|
|
244
269
|
```
|
|
245
270
|
|
|
246
|
-
```yaml
|
|
271
|
+
```yaml middleware
|
|
247
272
|
- deduplication: { store: "mongodb://localhost:27017/etl", ttl_seconds: 3600 }
|
|
248
273
|
```
|
|
249
274
|
|
|
250
|
-
```yaml
|
|
275
|
+
```yaml middleware
|
|
251
276
|
- deduplication: { store: "postgres://user:pass@localhost/etl", ttl_seconds: 3600 }
|
|
252
277
|
```
|
|
253
278
|
|
|
279
|
+
```yaml middleware
|
|
280
|
+
- deduplication: { store: "sled:///var/lib/mq-bridge/dedup", ttl_seconds: 3600, key: "${payload:order_id}" }
|
|
281
|
+
```
|
|
282
|
+
|
|
254
283
|
When MongoDB is your sink and messages carry a business key, prefer the sink's own unique
|
|
255
284
|
index (`id_field` on the mongodb output) over this middleware — the target collection then
|
|
256
285
|
*is* the deduplication authority, with no second write. See the idempotency notes in README.
|
|
@@ -268,7 +297,7 @@ Correlates messages by a metadata key and emits them as one joined message. Inpu
|
|
|
268
297
|
| `required` | list of branch names | `[]` |
|
|
269
298
|
| `on_timeout` | `fire` \| `discard` | `fire` |
|
|
270
299
|
|
|
271
|
-
```yaml
|
|
300
|
+
```yaml middleware
|
|
272
301
|
# Count mode: wait for any 3 messages sharing a correlation_id, emit a JSON array.
|
|
273
302
|
- weak_join: { group_by: "correlation_id", expected_count: 3, timeout_ms: 5000 }
|
|
274
303
|
|
|
@@ -296,7 +325,7 @@ Accumulates single sends and forwards them as one batch. Input and output.
|
|
|
296
325
|
| `max_messages` | integer | yes |
|
|
297
326
|
| `max_delay_ms` | integer | yes |
|
|
298
327
|
|
|
299
|
-
```yaml
|
|
328
|
+
```yaml middleware
|
|
300
329
|
- buffer: { max_messages: 500, max_delay_ms: 20 }
|
|
301
330
|
```
|
|
302
331
|
|
|
@@ -311,7 +340,7 @@ Paces throughput to a target rate. Input and output.
|
|
|
311
340
|
|---|---|---|
|
|
312
341
|
| `messages_per_second` | float (> 0) | yes |
|
|
313
342
|
|
|
314
|
-
```yaml
|
|
343
|
+
```yaml middleware
|
|
315
344
|
- limiter: { messages_per_second: 250 }
|
|
316
345
|
```
|
|
317
346
|
|
|
@@ -325,7 +354,7 @@ Sleeps a fixed duration before each receive or send. Input and output.
|
|
|
325
354
|
|---|---|---|
|
|
326
355
|
| `delay_ms` | integer | yes |
|
|
327
356
|
|
|
328
|
-
```yaml
|
|
357
|
+
```yaml middleware
|
|
329
358
|
- delay: { delay_ms: 100 }
|
|
330
359
|
```
|
|
331
360
|
|
|
@@ -345,7 +374,7 @@ Persists HTTP cookies and arbitrary session values across messages. Input and ou
|
|
|
345
374
|
| `export_metadata_prefix` | string | – |
|
|
346
375
|
| `inject_metadata` | map string→string | `{}` |
|
|
347
376
|
|
|
348
|
-
```yaml
|
|
377
|
+
```yaml middleware
|
|
349
378
|
- cookie_jar:
|
|
350
379
|
shared_scope: "login-session"
|
|
351
380
|
capture_metadata_keys: ["x-csrf-token"]
|
|
@@ -369,7 +398,7 @@ output. Requires the `encryption` feature.
|
|
|
369
398
|
| `key` | string — base64-encoded 32-byte key; `${env:VAR}` reads it from the environment | required |
|
|
370
399
|
| `decrypt_keys` | map key_id → key | `{}` |
|
|
371
400
|
|
|
372
|
-
```yaml
|
|
401
|
+
```yaml middleware
|
|
373
402
|
- encryption: { key: "${env:MQB_ENC_KEY}" }
|
|
374
403
|
```
|
|
375
404
|
|
|
@@ -391,7 +420,7 @@ Do **not** combine this middleware with a sink's batch `compression` on the same
|
|
|
391
420
|
ciphertext does not compress. For compressed *and* encrypted data at rest, use the `file` /
|
|
392
421
|
`object_store` endpoints' own fields instead, which apply compress-then-encrypt per batch:
|
|
393
422
|
|
|
394
|
-
```yaml
|
|
423
|
+
```yaml endpoint
|
|
395
424
|
output:
|
|
396
425
|
file:
|
|
397
426
|
path: "data.enc"
|
|
@@ -421,12 +450,39 @@ sniffing the leading magic bytes, so raw compressed bytes are never emitted as m
|
|
|
421
450
|
> `double precision` column can change the last bit. Build with the `float-roundtrip` feature
|
|
422
451
|
> for bit-exact float parsing across every endpoint (it trades a little parse speed for it).
|
|
423
452
|
|
|
453
|
+
### `compression`
|
|
454
|
+
|
|
455
|
+
Compresses each message **payload** on the output side and decompresses it on the input
|
|
456
|
+
side. Metadata and routing keys are untouched. Input and output. Requires the `compression`
|
|
457
|
+
feature.
|
|
458
|
+
|
|
459
|
+
| Field | Type | Default |
|
|
460
|
+
|---|---|---|
|
|
461
|
+
| `algorithm` | `none` \| `gzip` \| `lz4` \| `zstd` | `zstd` |
|
|
462
|
+
| `max_decompressed_bytes` | integer — reject a payload that decompresses larger than this (bomb guard); consumer side only | unset (no limit) |
|
|
463
|
+
|
|
464
|
+
```yaml middleware
|
|
465
|
+
- compression: { algorithm: zstd }
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Each payload is compressed independently into a single self-contained member, so this works
|
|
469
|
+
over any transport, not just files. `algorithm: none` is a passthrough. A truncated or
|
|
470
|
+
corrupt frame is a **permanent** consumer error (the poison message is not re-read
|
|
471
|
+
indefinitely), as is a payload that exceeds `max_decompressed_bytes`. Put the same
|
|
472
|
+
`algorithm` on both the input and output side of a route.
|
|
473
|
+
|
|
474
|
+
Unlike the `file` / `object_store` batch `compression` field — which keeps whole write
|
|
475
|
+
batches decodable with `zcat` / `lz4 -d` — this middleware frames per message and is only
|
|
476
|
+
readable through a matching consumer. Do not combine it with the [`encryption`](#encryption)
|
|
477
|
+
middleware (ciphertext does not compress); for compressed-and-encrypted data at rest, use the
|
|
478
|
+
endpoints' own `compression`/`encryption` fields instead.
|
|
479
|
+
|
|
424
480
|
### `metrics`
|
|
425
481
|
|
|
426
482
|
Emits throughput, latency and error metrics for the endpoint. Input and output. Requires the
|
|
427
483
|
`metrics` feature. Takes no options; its presence enables collection.
|
|
428
484
|
|
|
429
|
-
```yaml
|
|
485
|
+
```yaml middleware
|
|
430
486
|
- metrics: {}
|
|
431
487
|
```
|
|
432
488
|
|
|
@@ -442,7 +498,7 @@ Deliberate fault injection for testing recovery paths. Input and output.
|
|
|
442
498
|
| `trigger_on_message` | integer (1-indexed) | – (every message) |
|
|
443
499
|
| `enabled` | bool | `true` |
|
|
444
500
|
|
|
445
|
-
```yaml
|
|
501
|
+
```yaml middleware
|
|
446
502
|
- random_panic: { mode: disconnect, trigger_on_message: 500 }
|
|
447
503
|
```
|
|
448
504
|
|
|
@@ -450,6 +506,24 @@ Deliberate fault injection for testing recovery paths. Input and output.
|
|
|
450
506
|
non-retryable one — useful for exercising a `dlq`. Keep `enabled: false` in committed configs
|
|
451
507
|
rather than deleting the block.
|
|
452
508
|
|
|
509
|
+
The middleware block alone is **not** enough: fault injection is gated per route by
|
|
510
|
+
`allow_fault_injection`, which defaults to `false`. Copying only the snippet above leaves the
|
|
511
|
+
middleware inert (the route logs that it is disabled). A complete, working configuration:
|
|
512
|
+
|
|
513
|
+
```yaml route
|
|
514
|
+
flaky_test_route:
|
|
515
|
+
allow_fault_injection: true
|
|
516
|
+
input:
|
|
517
|
+
memory: { topic: "in" }
|
|
518
|
+
middlewares:
|
|
519
|
+
- random_panic: { mode: disconnect, trigger_on_message: 500 }
|
|
520
|
+
output:
|
|
521
|
+
memory: { topic: "out" }
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
`allow_fault_injection: true` is intended for test configurations only. Do not enable it — or
|
|
525
|
+
the `random_panic` middleware — in production configs.
|
|
526
|
+
|
|
453
527
|
### `custom` (middleware)
|
|
454
528
|
|
|
455
529
|
Delegates to a factory you registered programmatically.
|
|
@@ -459,7 +533,7 @@ Delegates to a factory you registered programmatically.
|
|
|
459
533
|
| `name` | string | yes |
|
|
460
534
|
| `config` | any JSON | yes |
|
|
461
535
|
|
|
462
|
-
```yaml
|
|
536
|
+
```yaml middleware
|
|
463
537
|
- custom:
|
|
464
538
|
name: "my_enricher"
|
|
465
539
|
config: { lookup_url: "http://enrich.internal" }
|
|
@@ -507,7 +581,7 @@ use mq_bridge::route::register_endpoint;
|
|
|
507
581
|
register_endpoint("common_queue", Endpoint::new_memory("shared_memory_topic", 100));
|
|
508
582
|
```
|
|
509
583
|
|
|
510
|
-
```yaml
|
|
584
|
+
```yaml route
|
|
511
585
|
enrich:
|
|
512
586
|
input: { ref: "common_queue" }
|
|
513
587
|
output: { nats: { subject: "enriched", url: "nats://localhost:4222" } }
|
|
@@ -526,7 +600,7 @@ nesting depth is bounded.
|
|
|
526
600
|
|
|
527
601
|
Publishes each message to every listed endpoint. Output only.
|
|
528
602
|
|
|
529
|
-
```yaml
|
|
603
|
+
```yaml endpoint
|
|
530
604
|
output:
|
|
531
605
|
fanout:
|
|
532
606
|
- kafka: { topic: "audit", url: "localhost:9092" }
|
|
@@ -547,7 +621,7 @@ Content-based routing: picks a destination by the value of a **metadata key**.
|
|
|
547
621
|
| `cases` | map value → Endpoint | yes |
|
|
548
622
|
| `default` | Endpoint | no |
|
|
549
623
|
|
|
550
|
-
```yaml
|
|
624
|
+
```yaml endpoint
|
|
551
625
|
output:
|
|
552
626
|
switch:
|
|
553
627
|
metadata_key: "http_status_code"
|
|
@@ -573,7 +647,7 @@ turning a request/reply exchange into a one-way flow.
|
|
|
573
647
|
| `to` | Endpoint (request-capable) | yes |
|
|
574
648
|
| `forward_to` | Endpoint | yes |
|
|
575
649
|
|
|
576
|
-
```yaml
|
|
650
|
+
```yaml endpoint
|
|
577
651
|
output:
|
|
578
652
|
request:
|
|
579
653
|
to: { http: { url: "https://api.internal/score" } }
|
|
@@ -590,7 +664,7 @@ status key such as `http_status_code`.
|
|
|
590
664
|
Replies to the origin of the current request. Output only, and the recommended way to build
|
|
591
665
|
request/reply routes.
|
|
592
666
|
|
|
593
|
-
```yaml
|
|
667
|
+
```yaml route
|
|
594
668
|
http_echo:
|
|
595
669
|
input: { http: { url: "0.0.0.0:8080" } }
|
|
596
670
|
output: { response: {} }
|
|
@@ -606,7 +680,7 @@ pipeline. See [README.md](README.md#patterns-request-response).
|
|
|
606
680
|
An output endpoint that **ignores the incoming payload** and instead reads one message from
|
|
607
681
|
the wrapped consumer, returning it as the response. The inbound message is purely a trigger.
|
|
608
682
|
|
|
609
|
-
```yaml
|
|
683
|
+
```yaml route
|
|
610
684
|
# HTTP GET pulls the next message off a Kafka topic.
|
|
611
685
|
poll_api:
|
|
612
686
|
input: { http: { url: "0.0.0.0:8080", method: "GET" } }
|
|
@@ -632,7 +706,7 @@ source).
|
|
|
632
706
|
|
|
633
707
|
Accepts either a bare string or the full map form:
|
|
634
708
|
|
|
635
|
-
```yaml
|
|
709
|
+
```yaml endpoint
|
|
636
710
|
output: { static: "OK" } # shorthand, body JSON-encoded
|
|
637
711
|
|
|
638
712
|
output:
|
|
@@ -669,7 +743,7 @@ structure — append `| raw` to a token to splice it verbatim. To emit a literal
|
|
|
669
743
|
`${…}`, write `$${…}` (a bare `$$` is left as-is); any `${…}` with an unknown namespace is also
|
|
670
744
|
left untouched.
|
|
671
745
|
|
|
672
|
-
```yaml
|
|
746
|
+
```yaml endpoint
|
|
673
747
|
output:
|
|
674
748
|
static:
|
|
675
749
|
body: '{"error":"not found","id":"${message:id}","at":"${gen:now}"}'
|
|
@@ -688,7 +762,7 @@ bodies between routes.
|
|
|
688
762
|
| `correlation_id` | string | **required on consumers, must be unset on publishers** |
|
|
689
763
|
| `capacity` | integer | default `100`, per partition |
|
|
690
764
|
|
|
691
|
-
```yaml
|
|
765
|
+
```yaml endpoint
|
|
692
766
|
output:
|
|
693
767
|
stream_buffer: { topic: "responses" } # publisher: no correlation_id
|
|
694
768
|
|
|
@@ -703,7 +777,7 @@ and ignores it. Primarily wired up via `HttpConfig::stream_response_to`.
|
|
|
703
777
|
|
|
704
778
|
Discards every message. Output only. This is the **default output** when a route omits one.
|
|
705
779
|
|
|
706
|
-
```yaml
|
|
780
|
+
```yaml route
|
|
707
781
|
drain:
|
|
708
782
|
input: { kafka: { topic: "noisy", url: "localhost:9092" } }
|
|
709
783
|
output: null # a bare YAML null
|
|
@@ -724,7 +798,7 @@ Delegates to a factory you registered programmatically.
|
|
|
724
798
|
| `name` | string | yes |
|
|
725
799
|
| `config` | any JSON | yes |
|
|
726
800
|
|
|
727
|
-
```yaml
|
|
801
|
+
```yaml endpoint
|
|
728
802
|
output:
|
|
729
803
|
custom:
|
|
730
804
|
name: "my_sink"
|
|
@@ -72,7 +72,7 @@ theirs. The run brief lives in [`mq-bridge-app-benchmark-prompt.md`](mq-bridge-a
|
|
|
72
72
|
|
|
73
73
|
| Scenario | Payload | Batch | Concurrency | Source → Sink | Result |
|
|
74
74
|
| --- | --- | --- | --- | --- | --- |
|
|
75
|
-
| Bulk-copy throughput | 7-col mixed-type rows, 1,000,000 rows | 1024 | 4 | postgres (keyset cursor) → file (JSONL) | **
|
|
75
|
+
| Bulk-copy throughput | 7-col mixed-type rows, 1,000,000 rows | 1024 | 4 | postgres (keyset cursor) → file (JSONL) | **384,615 rows/s** (2.600 s) |
|
|
76
76
|
|
|
77
77
|
Command: `mq-bridge-app copy --from postgres://…?table=…&cursor_column=id --to file://…?format=raw --drain --batch-size 1024 --concurrency 4`, wall-clocked. Requires an index on the cursor column (`CREATE INDEX ON <table>(id)`) — without it the keyset-pagination reader (`WHERE id > $cursor ORDER BY id LIMIT batch`) does a full scan per batch (near-quadratic).
|
|
78
78
|
|
|
@@ -82,10 +82,10 @@ Same source table (`bench`: 1,000,000 rows, 7 mixed-type columns), same Postgres
|
|
|
82
82
|
|
|
83
83
|
| Scenario | Payload | Batch | Concurrency | Source → Sink | Throughput | Peak RSS |
|
|
84
84
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
85
|
-
| mq-bridge-app `copy` | 7-col, 1,000,000 rows | 1024 | 1 | postgres (keyset cursor) → file (JSONL) | **
|
|
85
|
+
| mq-bridge-app `copy` | 7-col, 1,000,000 rows | 1024 | 1 | postgres (keyset cursor) → file (JSONL) | **338,066 rows/s** | 39.8 MiB |
|
|
86
86
|
| Meltano (`tap-postgres` → `target-jsonl`) | 7-col, 1,000,000 rows | default Singer config | — | postgres → JSONL | 15,356 rows/s | 599.7 MiB |
|
|
87
87
|
|
|
88
|
-
**~
|
|
88
|
+
**~22x faster and ~15x leaner in peak memory** than Meltano in this scenario. Full setup (including the Meltano project config) is in [mq-bridge-app's `benches/etl/README.md`](https://github.com/marcomq/mq-bridge-app/blob/dev/benches/etl/README.md#5--postgres--jsonl-vs-meltano-tap-postgres--target-jsonl).
|
|
89
89
|
|
|
90
90
|
### Preliminary run — CSV → JSONL vs. Meltano
|
|
91
91
|
|
|
@@ -93,10 +93,10 @@ Same seeded dataset both sides, same machine, one-shot full-file CSV → local J
|
|
|
93
93
|
|
|
94
94
|
| Scenario | Payload | Batch | Concurrency | Source → Sink | Throughput | Peak RSS |
|
|
95
95
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
96
|
-
| mq-bridge-app `copy` | 7-col mixed-type, 1,000,000 rows (~116 MiB) | 1024 | 1 | file (CSV) → file (JSONL) | **
|
|
96
|
+
| mq-bridge-app `copy` | 7-col mixed-type, 1,000,000 rows (~116 MiB) | 1024 | 1 | file (CSV) → file (JSONL) | **1,133,786 rows/s** | 21.9 MiB |
|
|
97
97
|
| Meltano (`tap-csv` → `target-jsonl`) | 7-col mixed-type, 1,000,000 rows | default Singer config | — | file (CSV) → JSONL | ~19,500 rows/s | 443.8 MiB |
|
|
98
98
|
|
|
99
|
-
**~
|
|
99
|
+
**~58x faster and ~20x leaner in peak memory** than Meltano in this scenario. Full setup is in [mq-bridge-app's `benches/etl/README.md`](https://github.com/marcomq/mq-bridge-app/blob/dev/benches/etl/README.md#6--csv--jsonl-vs-meltano).
|
|
100
100
|
|
|
101
101
|
## Status
|
|
102
102
|
|