mq-bridge-py-basic 0.3.5__tar.gz → 0.3.6__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.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/ibm-mq.yml +0 -1
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/ARCHITECTURE.md +108 -6
- mq_bridge_py_basic-0.3.5/claude.md → mq_bridge_py_basic-0.3.6/CLAUDE.md +60 -16
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/CONFIGURATION.md +35 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/Cargo.lock +321 -60
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/Cargo.toml +33 -6
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/PKG-INFO +1 -1
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/README.md +84 -4
- mq_bridge_py_basic-0.3.6/REFERENCE.md +688 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/examples/ipc_worker_queue.yaml +0 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq-bridge.schema.json +278 -8
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq_bridge/config.py +16 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq_bridge/config.pyi +45 -1
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/Cargo.toml +4 -3
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/httparena/README.md +1 -1
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/httparena/frameworks/mq-bridge-py/server.py +2 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/clickhouse.rs +101 -13
- mq_bridge_py_basic-0.3.5/src/endpoints/file.rs → mq_bridge_py_basic-0.3.6/src/endpoints/file/mod.rs +1088 -1089
- mq_bridge_py_basic-0.3.6/src/endpoints/file/tests.rs +1622 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/grpc.rs +2 -2
- mq_bridge_py_basic-0.3.6/src/endpoints/http/mod.rs +2220 -0
- mq_bridge_py_basic-0.3.6/src/endpoints/http/publisher.rs +542 -0
- mq_bridge_py_basic-0.3.6/src/endpoints/http/tests.rs +1637 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/ibm_mq.rs +7 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/kafka.rs +2 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/memory/endpoint.rs +134 -7
- mq_bridge_py_basic-0.3.6/src/endpoints/memory/framed.rs +287 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/memory/ipc_unix.rs +155 -60
- mq_bridge_py_basic-0.3.6/src/endpoints/memory/ipc_windows.rs +351 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/memory/memory_transport.rs +0 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/memory/mod.rs +2 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/memory/transport.rs +0 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/mod.rs +40 -9
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/mongodb.rs +192 -81
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/nats.rs +2 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/object_store.rs +304 -8
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/redis_streams.rs +3 -0
- mq_bridge_py_basic-0.3.5/src/endpoints/sqlx.rs → mq_bridge_py_basic-0.3.6/src/endpoints/sqlx/mod.rs +96 -712
- mq_bridge_py_basic-0.3.6/src/endpoints/sqlx/tests.rs +737 -0
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/fanout.rs +73 -5
- mq_bridge_py_basic-0.3.6/src/endpoints/structural/mod.rs +21 -0
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/reader.rs +39 -13
- mq_bridge_py_basic-0.3.6/src/endpoints/structural/request.rs +280 -0
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/static_endpoint.rs +80 -17
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/stream_buffer.rs +19 -3
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/switch.rs +61 -12
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/errors.rs +5 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/lib.rs +1 -1
- mq_bridge_py_basic-0.3.6/src/middleware/encryption.rs +279 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/mod.rs +28 -2
- mq_bridge_py_basic-0.3.6/src/middleware/transform/coerce.rs +147 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/compiled.rs +345 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/error.rs +68 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/mod.rs +259 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/path.rs +127 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/schema.rs +363 -0
- mq_bridge_py_basic-0.3.6/src/middleware/transform/tests.rs +1278 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/models.rs +279 -9
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/route.rs +136 -7
- mq_bridge_py_basic-0.3.6/src/support/compression.rs +179 -0
- mq_bridge_py_basic-0.3.6/src/support/crypto.rs +245 -0
- mq_bridge_py_basic-0.3.6/src/support/interpolation.rs +590 -0
- mq_bridge_py_basic-0.3.6/src/support/mod.rs +15 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/test_utils.rs +3 -4
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/ipc.rs +0 -2
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/route.rs +110 -4
- mq_bridge_py_basic-0.3.6/tests/reference_docs_test.rs +361 -0
- mq_bridge_py_basic-0.3.5/scripts/analysis/HTTP_STREAM_ENDPOINT_PLAN.md +0 -81
- mq_bridge_py_basic-0.3.5/src/endpoints/http.rs +0 -4196
- mq_bridge_py_basic-0.3.5/src/endpoints/memory/ipc_windows.rs +0 -260
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/benchmark.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/ci.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/node.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/publish-node.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/publish-python.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/python.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/release.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.github/workflows/test-matrix.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/.gitignore +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/CONTRIBUTING.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/LICENSE +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/benches/ETL_BENCHMARKS.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/benches/performance_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/benches/router_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/bindings-common/Cargo.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/bindings-common/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/bindings-common/src/logging.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/build.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq_bridge/__init__.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq_bridge/__init__.pyi +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/mq_bridge/py.typed +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/package-lock.json +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/example.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/bench_memory.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/consume_pull.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/dlt_source.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/json_route.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/memory.yaml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/examples/raw_route.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/pyproject-basic.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_config_types.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_logging.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_packaging.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_public_api.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/tests/test_routes.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/python/mq-bridge-py/uv.lock +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/benches/metadata_bench.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/http/http_flamegraph.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/analysis/http/run_http_ladder.sh +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/ci/format_bench_output.sh +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/README.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/postgres.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/seed.sql +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/techempower/verify.sh +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/the-benchmarker/README.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/canonical_message.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/checkpoint.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/command_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/amqp.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/aws.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/grpc.proto +0 -0
- /mq_bridge_py_basic-0.3.5/src/endpoints/http_stream.rs → /mq_bridge_py_basic-0.3.6/src/endpoints/http/stream.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/poll.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/VENDORED.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/pgoutput/values.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/replication.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/postgres/state.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/sled.rs +0 -0
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/null.rs +0 -0
- {mq_bridge_py_basic-0.3.5/src/endpoints → mq_bridge_py_basic-0.3.6/src/endpoints/structural}/response.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/websocket.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/endpoints/zeromq.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/event_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/event_store.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/extensions.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/buffer.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/cookie_jar.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/deduplication.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/delay.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/dlq.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/limiter.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/metrics.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/random_panic.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/retry.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/middleware/weak_join.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/outcomes.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/publisher.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/response.rs +0 -0
- {mq_bridge_py_basic-0.3.5/src → mq_bridge_py_basic-0.3.6/src/support}/connection_registry.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/traits.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/src/type_handler.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/README.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/armature_integration.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/amqp.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/aws.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/clickhouse.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/config.toml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/amqp.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/aws.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/clickhouse.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm_mq.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/kafka-tls.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/kafka.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mariadb.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mongodb.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mosquitto.conf +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mq_init.mqsc +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mqtt.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/mysql.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/nats.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/object_store.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/postgres.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/docker-compose/redis.yml +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/file.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/grpc.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/grpc_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/http.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/http_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/ibm_mq.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/kafka.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/kafka_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/logic_test.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mariadb.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/memory.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mod.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mongodb.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mongodb_raw.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mongodb_tls.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/mysql.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/nats.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/object_store.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/performance_static.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/postgres.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/postgres_cdc.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/redis_streams.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/scripts/gen_certs.sh +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/sqlite.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/tls_helpers.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/websocket.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration/zeromq.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/integration_test.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/memory_leak_test.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/ref_test.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/sqlite_test.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/tls_example.rs +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/unit_tests.md +0 -0
- {mq_bridge_py_basic-0.3.5 → mq_bridge_py_basic-0.3.6}/tests/websocket_test.rs +0 -0
|
@@ -17,23 +17,125 @@ A `Route` defines a data pipeline from one input endpoint to one output endpoint
|
|
|
17
17
|
- Attach a handler for business logic (transform, filter, respond)
|
|
18
18
|
|
|
19
19
|
### 2. Endpoint
|
|
20
|
-
Endpoints are protocol adapters for sources (consumers) and sinks (publishers). Supported types include Kafka, NATS, AMQP, MQTT, MongoDB, HTTP, SQLx, ZeroMQ, Files, AWS, IBM MQ, and in-
|
|
20
|
+
Endpoints are protocol adapters for sources (consumers) and sinks (publishers). Supported types include Kafka, NATS, AMQP, MQTT, MongoDB, HTTP, SQLx, ZeroMQ, Files, AWS, IBM MQ, and the `memory` endpoint (in-process channels and cross-process IPC). Endpoints are created via factory functions and configured via serde (json/yml).
|
|
21
|
+
|
|
22
|
+
Beyond these protocol adapters there are **structural endpoints** that compose other endpoints
|
|
23
|
+
or shape routing rather than talking to a broker: `ref`, `fanout`, `switch`, `request`,
|
|
24
|
+
`response`, `reader`, `static`, `stream_buffer`, `null` and `custom`. All of them are
|
|
25
|
+
documented in [REFERENCE.md](REFERENCE.md#structural-endpoints).
|
|
21
26
|
|
|
22
27
|
### 3. Middleware
|
|
23
|
-
Middleware wraps consumers and publishers to add cross-cutting features
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
+
Middleware wraps consumers and publishers to add cross-cutting features. There is no
|
|
29
|
+
`Middleware` trait: a middleware *is* a decorator implementing `MessageConsumer` and/or
|
|
30
|
+
`MessagePublisher`, which is why `CustomMiddlewareFactory` is defined as `apply_consumer` /
|
|
31
|
+
`apply_publisher`. Available middleware includes:
|
|
32
|
+
- Retries (exponential backoff) and dead-letter queues (DLQ)
|
|
33
|
+
- JSON transformation (`transform`): mapping, type coercion, schema validation
|
|
34
|
+
- Deduplication (sled-based), weak joins, buffering, rate limiting
|
|
35
|
+
- Metrics, delays, fault injection
|
|
28
36
|
- Custom user middleware
|
|
29
37
|
|
|
38
|
+
The complete list, with fields, defaults and the layer-ordering rules, is in
|
|
39
|
+
[REFERENCE.md](REFERENCE.md#middleware).
|
|
40
|
+
|
|
30
41
|
### 4. Handler
|
|
31
42
|
Handlers are user-defined async functions that process messages. There are two main handler types:
|
|
32
43
|
- **CommandHandler:** 1-to-1 or 1-to-0 transformation, can return a new message for publishing or as response.
|
|
33
44
|
- **EventHandler:** 1-to-N handler for event consumption. Compatible to CommandHandler, but should not return a response.
|
|
34
45
|
- **TypeHandler:** Strongly-typed handler, dispatches based on the `kind` metadata field and deserializes payloads.
|
|
35
46
|
|
|
47
|
+
## Memory Endpoint and IPC Transport
|
|
48
|
+
|
|
49
|
+
The `memory` endpoint is not only an in-process channel. Its `topic` field (serde alias: `url`) doubles as a **transport URL**, so the same endpoint type covers both in-process queues and cross-process IPC over Unix domain sockets / Windows named pipes.
|
|
50
|
+
|
|
51
|
+
### Transport URL schemes
|
|
52
|
+
|
|
53
|
+
| URL | Resolves to | Platform |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `my-topic` | `memory://my-topic` (no scheme = in-process, for backward compatibility) | all |
|
|
56
|
+
| `memory://my-topic` | In-process channel, shared by namespace within the same process | all |
|
|
57
|
+
| `ipc://my-queue` | Unix: `/run/mq-bridge/my-queue.sock`<br>Windows: `\\.\pipe\mq-bridge-my-queue` | Unix + Windows |
|
|
58
|
+
| `ipc:///var/run/my.sock` | That exact socket path (leading `/` = absolute path, note the three slashes) | Unix |
|
|
59
|
+
| `unix:///var/run/my.sock` | That exact socket path; the path **must** be absolute | Unix only |
|
|
60
|
+
| `pipe://my-pipe` | `\\.\pipe\my-pipe` — used verbatim, **no** `mq-bridge-` prefix | Windows only |
|
|
61
|
+
|
|
62
|
+
Anything else (`http://…`, an empty URL, a relative `unix://path`) is rejected at parse time.
|
|
63
|
+
|
|
64
|
+
**Named `ipc://` resolution on Unix** falls back in order, using the first writable location:
|
|
65
|
+
1. `/run/mq-bridge/<name>.sock` (systemd standard)
|
|
66
|
+
2. `$XDG_RUNTIME_DIR/mq-bridge/<name>.sock`
|
|
67
|
+
3. `/tmp/mq-bridge/<name>.sock` (less secure)
|
|
68
|
+
|
|
69
|
+
Because of this fallback, `ipc://name` can land in different places for different users or services. When both sides must agree deterministically, use an explicit path (`ipc:///run/myapp/queue.sock`) instead of a bare name.
|
|
70
|
+
|
|
71
|
+
### Roles: consumer is the server, publisher is the client
|
|
72
|
+
|
|
73
|
+
IPC is **unidirectional, publisher → consumer**, and the roles are fixed:
|
|
74
|
+
|
|
75
|
+
- The **consumer** binds and listens on the socket/pipe (server). It removes a stale socket file before binding, creates the parent directory with mode `0700`, and sets the socket to `0600`. It unlinks the socket on drop.
|
|
76
|
+
- The **publisher** connects to it (client).
|
|
77
|
+
|
|
78
|
+
So **the consumer process must be running before the publisher connects** — otherwise the publisher fails with a connection error. The consumer serves one connection at a time; if the peer disconnects, it logs a warning and waits for a new connection rather than erroring out.
|
|
79
|
+
|
|
80
|
+
### IPC requires async construction
|
|
81
|
+
|
|
82
|
+
`MemoryConsumer::new`, `MemoryPublisher::new`, and `new_local` are synchronous and only support `memory://`. Given an IPC URL they return an error ("requires async endpoint construction"). Use the async constructors:
|
|
83
|
+
|
|
84
|
+
```rust
|
|
85
|
+
use mq_bridge::endpoints::memory::{MemoryConsumer, MemoryPublisher};
|
|
86
|
+
use mq_bridge::models::MemoryConfig;
|
|
87
|
+
|
|
88
|
+
let config = MemoryConfig::new_with_url("ipc:///run/mq-bridge/orders.sock", Some(100));
|
|
89
|
+
|
|
90
|
+
// Server side (start first)
|
|
91
|
+
let mut consumer = MemoryConsumer::new_async(&config).await?;
|
|
92
|
+
// Client side, in another process
|
|
93
|
+
let publisher = MemoryPublisher::new_async(&config).await?;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Routes always build endpoints through the async factories, so an `ipc://` URL works in YAML/JSON config with no extra code:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
ipc_ingest:
|
|
100
|
+
input:
|
|
101
|
+
memory:
|
|
102
|
+
url: "ipc:///run/mq-bridge/orders.sock"
|
|
103
|
+
capacity: 256
|
|
104
|
+
output:
|
|
105
|
+
kafka:
|
|
106
|
+
topic: "orders"
|
|
107
|
+
url: "localhost:9092"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Wire format
|
|
111
|
+
|
|
112
|
+
Batches are serialized with **MessagePack** (`Vec<CanonicalMessage>`) and written as length-prefixed frames: a 4-byte big-endian length followed by the payload. Frames larger than 100 MB are rejected.
|
|
113
|
+
|
|
114
|
+
Framing is handled by `tokio_util::codec::LengthDelimitedCodec` in `endpoints/memory/framed.rs`, shared by both platforms. This matters for more than deduplication: the codec owns the partial-frame buffer, which makes reads **cancel safe**. Routes cancel `receive_batch` on shutdown via `select!`, and a hand-rolled `read_exact` pair would consume part of a frame on cancellation and desync the connection permanently.
|
|
115
|
+
|
|
116
|
+
### Backpressure
|
|
117
|
+
|
|
118
|
+
A batch is written as one frame. Socket buffers are small — **8 KiB by default on macOS** (`net.local.stream.sendspace`) — so a batch that outgrows the buffer only completes once the consumer drains it. `send_batch` blocking is therefore normal backpressure, not a fault.
|
|
119
|
+
|
|
120
|
+
Two consequences worth knowing:
|
|
121
|
+
|
|
122
|
+
- The consumer must actually be reading, not merely connected. A consumer that has accepted but stopped draining will stall the publisher indefinitely. After 5 seconds blocked, the publisher logs a warning naming the socket; it keeps waiting rather than dropping data.
|
|
123
|
+
- `capacity` does not create a queue here. There is no buffering between the two processes beyond the kernel socket buffer.
|
|
124
|
+
|
|
125
|
+
### Acknowledgements and redelivery over IPC
|
|
126
|
+
|
|
127
|
+
`enable_nack` defaults to **`true`** for IPC transports (`ipc://`, `unix://`, `pipe://`) and `false` for `memory://`; an explicit `enable_nack` in config always wins.
|
|
128
|
+
|
|
129
|
+
Redelivery over IPC is **consumer-local**. The socket carries publisher → consumer traffic only, so a nack cannot travel back to the producer — the publisher never reads, and writing to it would strand the messages and eventually block the commit on a full socket buffer. A nacked message is therefore requeued inside the consumer and redelivered ahead of new traffic. It does **not** survive a consumer crash, and the publisher is never told.
|
|
130
|
+
|
|
131
|
+
If you need redelivery that survives the consumer process, use a real broker endpoint. mq-bridge deliberately does not implement a bidirectional ack protocol over IPC.
|
|
132
|
+
|
|
133
|
+
### Behavioural differences vs `memory://`
|
|
36
134
|
|
|
135
|
+
- **`subscribe_mode` is not supported** over IPC, on either side — the EventStore/broadcast backend is in-process only.
|
|
136
|
+
- **`request_reply` is not supported** for IPC publishers.
|
|
137
|
+
- **Only the publisher side may send.** Calling `send_batch` on a consumer-side IPC transport returns an error rather than writing into a peer that never reads.
|
|
138
|
+
- **`capacity` bounds the consumer-side buffer**, not an internal queue — a socket has no backlog of its own. `len()` reports whole frames already buffered by the codec (readable without touching the socket), and endpoint `status().pending` adds the consumer's own buffered and awaiting-redelivery messages.
|
|
37
139
|
|
|
38
140
|
## Batching and Concurrency
|
|
39
141
|
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# mq-bridge Project Context
|
|
2
2
|
|
|
3
|
+
> **Looking for what middleware or structural endpoints exist, and how to configure them?**
|
|
4
|
+
> [REFERENCE.md](REFERENCE.md) is the complete, authoritative list — every middleware
|
|
5
|
+
> (`retry`, `dlq`, `transform`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
|
|
6
|
+
> `cookie_jar`, `encryption`, `metrics`, `random_panic`, `custom`) and every structural endpoint (`ref`,
|
|
7
|
+
> `fanout`, `switch`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
|
|
8
|
+
> `custom`), each with its fields, defaults, and a working YAML example. Do not infer these
|
|
9
|
+
> from the enum definitions in `models.rs`; the reference records the behaviour and the
|
|
10
|
+
> spelling traps too. Every snippet in it is parsed by `tests/reference_docs_test.rs`.
|
|
11
|
+
|
|
3
12
|
## Project Overview
|
|
4
13
|
|
|
5
14
|
`mq-bridge` is an asynchronous message bridging library for Rust that connects different messaging systems, data stores, and protocols. It acts as a **programmable integration layer**, allowing for transformation, filtering, handling, events, and complex routing.
|
|
@@ -32,31 +41,66 @@ src/
|
|
|
32
41
|
├── traits.rs # Core traits (MessageConsumer, MessagePublisher, Handler)
|
|
33
42
|
├── models.rs # Configuration models (Route, Endpoint, Middleware)
|
|
34
43
|
├── route.rs # Route execution logic (sequential/concurrent)
|
|
35
|
-
├── endpoints/
|
|
44
|
+
├── endpoints/ # Endpoint implementations
|
|
36
45
|
│ ├── mod.rs # Factory functions for creating consumers/publishers
|
|
37
|
-
│ ├── kafka.rs # Kafka consumer/publisher
|
|
38
|
-
│ ├── nats.rs # NATS consumer/publisher
|
|
39
46
|
│ ├── amqp.rs # AMQP (RabbitMQ) consumer/publisher
|
|
47
|
+
│ ├── aws.rs # AWS SQS/SNS
|
|
48
|
+
│ ├── clickhouse.rs # ClickHouse sink + cursor source
|
|
49
|
+
│ ├── file/ # File-based endpoints
|
|
50
|
+
│ ├── grpc.rs # gRPC consumer/publisher
|
|
51
|
+
│ ├── http/ # HTTP consumer/publisher (+ streaming)
|
|
52
|
+
│ ├── ibm_mq.rs # IBM MQ (client loaded at runtime via dlopen)
|
|
53
|
+
│ ├── kafka.rs # Kafka consumer/publisher
|
|
54
|
+
│ ├── memory/ # In-memory channels + IPC transports
|
|
55
|
+
│ ├── mongodb.rs # MongoDB consumer/publisher/change streams
|
|
40
56
|
│ ├── mqtt.rs # MQTT consumer/publisher
|
|
41
|
-
│ ├──
|
|
42
|
-
│ ├──
|
|
43
|
-
│ ├──
|
|
44
|
-
│ ├──
|
|
45
|
-
│ ├──
|
|
46
|
-
│ ├──
|
|
47
|
-
│
|
|
57
|
+
│ ├── nats.rs # NATS consumer/publisher
|
|
58
|
+
│ ├── object_store.rs # Cloud object storage (S3 / GCS / Azure)
|
|
59
|
+
│ ├── poll.rs # Shared cursor-polling helper (sqlx, clickhouse)
|
|
60
|
+
│ ├── postgres/ # Postgres CDC (logical replication + pgoutput)
|
|
61
|
+
│ ├── redis_streams.rs # Redis Streams
|
|
62
|
+
│ ├── sled.rs # Embedded sled queue
|
|
63
|
+
│ ├── sqlx/ # PostgreSQL / MySQL / SQLite
|
|
64
|
+
│ ├── websocket.rs # WebSocket consumer/publisher
|
|
65
|
+
│ ├── zeromq.rs # ZeroMQ consumer/publisher
|
|
66
|
+
│ └── structural/ # Structural endpoints (no external system)
|
|
67
|
+
│ ├── fanout.rs # Broadcast to every listed endpoint
|
|
68
|
+
│ ├── switch.rs # Content-based routing
|
|
69
|
+
│ ├── request.rs # Request/reply call, forward the response
|
|
70
|
+
│ ├── response.rs # Reply to the origin of the current request
|
|
71
|
+
│ ├── reader.rs # Trigger a pull from a consumer
|
|
72
|
+
│ ├── static_endpoint.rs # Fixed, pre-rendered message
|
|
73
|
+
│ ├── stream_buffer.rs # Correlation-partitioned in-memory stream
|
|
74
|
+
│ └── null.rs # Null endpoint (sink)
|
|
48
75
|
├── middleware/ # Middleware implementations
|
|
49
|
-
│ ├──
|
|
50
|
-
│ ├──
|
|
76
|
+
│ ├── buffer.rs # Batch accumulation
|
|
77
|
+
│ ├── cookie_jar.rs # Cookie / metadata persistence across requests
|
|
51
78
|
│ ├── deduplication.rs # Message deduplication (sled)
|
|
79
|
+
│ ├── delay.rs # Artificial delay
|
|
80
|
+
│ ├── dlq.rs # Dead-letter queue
|
|
81
|
+
│ ├── encryption.rs # AEAD payload encryption
|
|
82
|
+
│ ├── limiter.rs # Throughput limiting (msg/s)
|
|
52
83
|
│ ├── metrics.rs # Metrics collection
|
|
53
|
-
│
|
|
84
|
+
│ ├── random_panic.rs # Testing middleware
|
|
85
|
+
│ ├── retry.rs # Exponential backoff retry
|
|
86
|
+
│ ├── transform/ # Declarative JSON mapping + schema coercion
|
|
87
|
+
│ └── weak_join.rs # Correlation-keyed join
|
|
88
|
+
├── support/ # Cross-cutting helpers
|
|
89
|
+
│ ├── compression.rs # gzip / lz4 / zstd
|
|
90
|
+
│ ├── connection_registry.rs # Shared connection reuse
|
|
91
|
+
│ ├── crypto.rs # AEAD core (used by encryption middleware + at-rest)
|
|
92
|
+
│ └── interpolation.rs # `${namespace:selector}` templating
|
|
54
93
|
├── command_handler.rs # Command handler wrapper
|
|
55
94
|
├── event_handler.rs # Event handler wrapper
|
|
56
95
|
├── event_store.rs # In-memory event store
|
|
57
|
-
├── type_handler.rs
|
|
58
|
-
├──
|
|
59
|
-
|
|
96
|
+
├── type_handler.rs # Typed message handlers
|
|
97
|
+
├── publisher.rs # Standalone publisher API
|
|
98
|
+
├── checkpoint.rs # Durable cursor stores (file/s3/postgres/mongodb)
|
|
99
|
+
├── extensions.rs # Custom endpoint/middleware factory registration
|
|
100
|
+
├── response.rs # Ergonomic response helpers
|
|
101
|
+
├── test_utils.rs # Shared test helpers
|
|
102
|
+
├── errors.rs # Error types
|
|
103
|
+
└── outcomes.rs # Result types (Handled, Sent, Received)
|
|
60
104
|
```
|
|
61
105
|
|
|
62
106
|
### Consumer vs Subscriber
|
|
@@ -129,6 +129,30 @@ sqlx_postgres_route:
|
|
|
129
129
|
output:
|
|
130
130
|
memory:
|
|
131
131
|
topic: "processed_jobs"
|
|
132
|
+
|
|
133
|
+
# Route 9: Cross-process IPC via the memory endpoint
|
|
134
|
+
# The `topic` field (alias `url`) is a transport URL:
|
|
135
|
+
# "name" -> memory://name (in-process, same process only)
|
|
136
|
+
# "memory://name" -> in-process channel
|
|
137
|
+
# "ipc://name" -> Unix: /run/mq-bridge/name.sock (falls back to
|
|
138
|
+
# $XDG_RUNTIME_DIR/mq-bridge, then /tmp/mq-bridge)
|
|
139
|
+
# Windows: \\.\pipe\mq-bridge-name
|
|
140
|
+
# "ipc:///abs/path.sock" -> that exact socket path (Unix)
|
|
141
|
+
# "unix:///abs/path.sock" -> Unix only, path must be absolute
|
|
142
|
+
# "pipe://name" -> Windows only, \\.\pipe\name
|
|
143
|
+
# The consumer side binds/listens and must be started before the publisher connects.
|
|
144
|
+
# IPC does not support `subscribe_mode` or `request_reply`.
|
|
145
|
+
# `enable_nack` defaults to true, but redelivery is consumer-local: a nacked message
|
|
146
|
+
# is retried inside the consumer and is lost if the consumer process dies.
|
|
147
|
+
ipc_ingest:
|
|
148
|
+
input:
|
|
149
|
+
memory:
|
|
150
|
+
url: "ipc:///run/mq-bridge/orders.sock"
|
|
151
|
+
capacity: 256
|
|
152
|
+
output:
|
|
153
|
+
kafka:
|
|
154
|
+
topic: "orders"
|
|
155
|
+
url: "localhost:9092"
|
|
132
156
|
```
|
|
133
157
|
|
|
134
158
|
## Configuration Details
|
|
@@ -175,6 +199,13 @@ Two gotchas worth knowing before wiring up a `nats` endpoint:
|
|
|
175
199
|
placeholder string.
|
|
176
200
|
|
|
177
201
|
### Middleware Configuration
|
|
202
|
+
|
|
203
|
+
> Every available middleware, with its fields, defaults, supported side (input/output) and a
|
|
204
|
+
> working example, is listed in **[REFERENCE.md](REFERENCE.md#middleware)**. Note in
|
|
205
|
+
> particular the [ordering rule](REFERENCE.md#ordering--read-this-before-combining-middleware):
|
|
206
|
+
> on an **output**, the *last* middleware in the list is the outermost layer, so `dlq` goes
|
|
207
|
+
> last.
|
|
208
|
+
|
|
178
209
|
Middleware is defined as a list under an endpoint.
|
|
179
210
|
|
|
180
211
|
```yaml
|
|
@@ -301,6 +332,10 @@ orders_out:
|
|
|
301
332
|
|
|
302
333
|
### Specialized Endpoints
|
|
303
334
|
|
|
335
|
+
> This section covers `switch` in depth. The other structural endpoints — `ref`, `fanout`,
|
|
336
|
+
> `request`, `response`, `reader`, `static`, `stream_buffer`, `null` and `custom` — are
|
|
337
|
+
> documented in **[REFERENCE.md](REFERENCE.md#structural-endpoints)**.
|
|
338
|
+
|
|
304
339
|
#### Switch
|
|
305
340
|
|
|
306
341
|
The `switch` endpoint is a conditional publisher that routes messages to different outputs based on a metadata key.
|