mq-bridge-py-basic 0.4.6__tar.gz → 0.4.7__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.4.6 → mq_bridge_py_basic-0.4.7}/CHANGELOG.md +117 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/Cargo.lock +4 -4
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/Cargo.toml +1 -1
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/PKG-INFO +1 -1
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/endpoint.rs +46 -5
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/route.rs +147 -24
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/dependabot.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/benchmark.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/ci.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/ibm-mq.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/node.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/publish-node.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/publish-python.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/python.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/release.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/workflows/test-matrix.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.gitignore +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/CLAUDE.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/CONTRIBUTING.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/LICENSE +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/SECURITY.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/benches/ETL_BENCHMARKS.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/benches/performance_bench.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/benches/router_bench.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/benches/zeromq_backends.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/bindings-common/Cargo.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/bindings-common/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/bindings-common/src/logging.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/build.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/deny.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/ARCHITECTURE.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/CONFIGURATION.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/DELIVERY.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/EXTENDING.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/PLUGINS.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/docs/REFERENCE.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/examples/ipc_worker_queue.yaml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq-bridge.schema.json +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/__init__.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/__init__.pyi +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/config.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/config.pyi +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/plugin_packaging.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/mq_bridge/py.typed +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/package-lock.json +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/Cargo.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/LICENSE.python +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/example.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/bench_memory.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/consume_pull.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/dlt_source.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/json_route.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/memory.yaml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/raw_route.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/pyproject-basic.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_config_types.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_logging.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_packaging.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_public_api.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/tests/test_routes.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/uv.lock +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/benches/metadata_bench.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/http/http_flamegraph.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/analysis/http/run_http_ladder.sh +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/ci/format_bench_output.sh +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/httparena/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/postgres.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/seed.sql +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/techempower/verify.sh +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/the-benchmarker/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/canonical_message.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/checkpoint.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/command_handler.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/amqp.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/aws.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/clickhouse.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/file/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/file/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/grpc.proto +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/grpc.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/http/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/http/publisher.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/http/stream.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/http/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/ibm_mq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/kafka.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/endpoint.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/framed.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/ipc_unix.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/ipc_windows.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/memory_transport.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/memory/transport.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/consumer.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/dedup.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/publisher.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/readers.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mongodb/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/nats.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/object_store.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/poll.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/VENDORED.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/pgoutput/values.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/replication.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/postgres/state.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/redis_streams.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/sled.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/sqlx/dedup.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/sqlx/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/sqlx/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/fanout.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/null.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/reader.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/request.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/response.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/static_endpoint.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/stream_buffer.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/structural/switch.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/websocket.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/zeromq/codec.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/zeromq/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/zeromq/omq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/endpoints/zeromq/zmq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/errors.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/event_handler.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/event_store.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/extensions.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/lib.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/buffer.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/compression.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/cookie_jar.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/deduplication.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/deferred_commit.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/delay.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/dlq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/encryption.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/filter.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/id.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/limiter.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/metrics.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/random_panic.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/raw_json.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/retry.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/coerce.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/compiled.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/error.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/path.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/schema.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/transform/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/middleware/weak_join.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models/builders.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models/defaults.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models/secrets.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models/serde_support.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models/tests.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/models.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/outcomes.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/conformance.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/message.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/middleware.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/sdk.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/plugin/test_support.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/publisher.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/response.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/base64_engine.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/compression.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/connection_registry.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/crypto.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/crypto_envelope.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/interpolation.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/plugin_abi.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/support/source_ranges.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/test_utils.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/traits.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/src/type_handler.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/README.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/armature_integration.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/amqp.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/aws.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/clickhouse.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/config.toml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/amqp.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/aws.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/clickhouse.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm_mq.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/kafka-tls.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/kafka.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mariadb.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mongodb.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mosquitto.conf +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mq_init.mqsc +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mqtt.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/mysql.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/nats.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/object_store.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/postgres.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/docker-compose/redis.yml +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/file.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/grpc.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/grpc_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/http.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/http_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/ibm_mq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/ibm_mq_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/ipc.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/kafka.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/kafka_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/logic_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mariadb.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/memory.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mod.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mongodb.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mongodb_raw.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mongodb_tls.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mqtt.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/mysql.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/nats.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/object_store.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/performance_static.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/postgres.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/postgres_cdc.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/redis_streams.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/route.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/scripts/gen_certs.sh +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/sqlite.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/tls_helpers.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/websocket.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration/zeromq.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/integration_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/memory_leak_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/ref_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/reference_docs_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/sqlite_test.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/tls_example.rs +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/unit_tests.md +0 -0
- {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/tests/websocket_test.rs +0 -0
|
@@ -2,6 +2,123 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `mq-bridge`. Newest first.
|
|
4
4
|
|
|
5
|
+
## 0.4.7
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **The startup failure message distinguishes its two causes.** A route that never became ready
|
|
10
|
+
reports `failed to start: did not become ready within {n}ms`; a route whose task ended before
|
|
11
|
+
signalling ready reports `failed to start: ended before it signalled ready (outcome: ...)`.
|
|
12
|
+
The second case returns immediately and never involved the timeout, so reporting it as one
|
|
13
|
+
sent the reader looking for a stall that never happened. Both now carry the cause the
|
|
14
|
+
reconnect loop recorded, which the old message dropped. Code matching on the old
|
|
15
|
+
`failed to start within {n}ms or encountered an error` text needs updating; the substring
|
|
16
|
+
`failed to start` is unchanged.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **A route that ran to completion is no longer reported as one that failed to start.** The run
|
|
21
|
+
task signals ready before its consume loop, so a drain over a small source can reach its
|
|
22
|
+
terminal while that signal is still buffered — leaving the reconnect loop's `select!` with two
|
|
23
|
+
ready branches and free to take the terminal one, dropping the startup channel unread.
|
|
24
|
+
`Route::run()` then returned an error for a drain that had already written its output, and
|
|
25
|
+
`mqb copy --drain` exited non-zero on a successful copy. Both terminal arms now forward a
|
|
26
|
+
ready signal that was already emitted.
|
|
27
|
+
|
|
28
|
+
- **A completed route reports the messages it dropped even after an earlier reconnect failure.**
|
|
29
|
+
The drop report was suppressed whenever `EndpointStatus::error` was already set, including by a
|
|
30
|
+
transient failure the route recovered from. Only a `Failed` route's cause now outranks it.
|
|
31
|
+
|
|
32
|
+
- **A plugin endpoint that rejects its config no longer reconnects forever.** `create_consumer`
|
|
33
|
+
and `create_publisher` flattened the plugin's status into a bare message, and the reconnect
|
|
34
|
+
loop decides by downcasting to `ConsumerError`/`PublisherError` — so every failure to open
|
|
35
|
+
looked like a connection fault worth retrying. A plugin answering `MQB_ERR_INVALID_CONFIG`,
|
|
36
|
+
`MQB_ERR_UNSUPPORTED`, `MQB_ERR_PERMANENT` or `MQB_ERR_PANIC` now stops the route with that
|
|
37
|
+
cause; `MQB_ERR_CONNECTION` and `MQB_ERR_RETRYABLE` still get the reconnect loop.
|
|
38
|
+
|
|
39
|
+
## 0.4.6
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **`filter` middleware.** Keeps only the messages matching an expression and drops the rest,
|
|
44
|
+
on the input or the output: `- filter: "amount > 100"`. Payload fields are read by bare name
|
|
45
|
+
(`amount`, `order.status`), metadata under `meta.` and always as text, so a numeric comparison
|
|
46
|
+
needs a cast (`number(meta.http_status_code) >= 400`); `&&`/`||` and `and`/`or` both work. A
|
|
47
|
+
metadata-only expression never parses the payload. **Prefer the input** — a filter there drops
|
|
48
|
+
the message before the rest of the route touches it and acks it at the source. Requires the
|
|
49
|
+
new `filter` feature (it pulls the `zen-expression` engine), which is part of `middleware` and
|
|
50
|
+
`full` but **not** of `portable`.
|
|
51
|
+
|
|
52
|
+
- **Predicate mode for `switch`.** `when: [{ if, to }, ...]` routes on the same expression
|
|
53
|
+
language, first match wins, so overlapping thresholds are safe to write and a payload-derived
|
|
54
|
+
key no longer has to be promoted into metadata first. A `switch` uses exactly one of `when` or
|
|
55
|
+
`metadata_key`/`cases`; naming both or neither is a startup error, as is a `when` list in a
|
|
56
|
+
build without the `filter` feature. Value lookup stays the cheaper mode when the key is
|
|
57
|
+
already in metadata.
|
|
58
|
+
|
|
59
|
+
- **`expression` on `transform`.** A Zen expression producing the output document, applied after
|
|
60
|
+
`mapping` and before `schema` — for values that have to be calculated rather than copied.
|
|
61
|
+
Needs the `zen` feature.
|
|
62
|
+
|
|
63
|
+
- **A `fanout` can reply.** If one branch produces a response — a `response` or `static` leg, or
|
|
64
|
+
a `request` whose `forward_to` replies — that response goes back to the caller, so a
|
|
65
|
+
request/reply input can fan a message out and still answer. Only one branch may answer: if
|
|
66
|
+
several do, the first in list order wins, and the route warns once rather than on every
|
|
67
|
+
message. A branch that *fails* nacks the whole fan-out, so the caller gets a `500` rather than
|
|
68
|
+
an answer that hides a lost message; opt out per branch with a `request` whose `forward_to`
|
|
69
|
+
does not reply, or a `dlq` on a plain branch.
|
|
70
|
+
|
|
71
|
+
- **`pass_through_status` on the `http` endpoint.** On a **publisher**, a non-2xx response
|
|
72
|
+
becomes response data instead of a publisher error, so a route can branch on
|
|
73
|
+
`http_status_code` with a `switch` rather than treating every 404 as a failed send. Transport
|
|
74
|
+
failures and unreadable responses are still errors. On a **consumer**, once every output sink
|
|
75
|
+
opts in, a transient sink failure answers the request with `502` instead of stopping and
|
|
76
|
+
reconnecting a non-streaming request/reply route. Composite outputs such as `fanout` need the
|
|
77
|
+
flag on every leaf sink — a mixed output keeps the normal stop-and-reconnect policy — and
|
|
78
|
+
streamable HTTP inputs keep their protocol-specific error frames.
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **A middleware that empties a batch no longer acknowledges ahead of the route.** `filter` and
|
|
83
|
+
`deduplication` can filter a batch down to nothing, and acking that straight away jumps ahead
|
|
84
|
+
of batches the route is still writing on a source with cumulative acks — the ordered sequencer
|
|
85
|
+
only sees the commits `receive_batch` returns, so a crash in that window lost them. On those
|
|
86
|
+
sources the emptied batch's commit is now held and runs from inside the next retained batch's
|
|
87
|
+
commit, which the sequencer does order.
|
|
88
|
+
|
|
89
|
+
- **An `object_store` sink on `name_by: auto` switches to `write_time` names when a row-dropping
|
|
90
|
+
middleware is on the route.** A source-range name covers one *contiguous* run of positions, so
|
|
91
|
+
a batch with holes punched in it would be written as one object per surviving run — a filter
|
|
92
|
+
keeping 80% of rows turns one upload into roughly a hundred. The route logs one line at
|
|
93
|
+
startup saying it made the switch. This covers `filter`, `deduplication`, `weak_join`,
|
|
94
|
+
`transform` with `on_error: reject`, and a `switch` in `when` mode with no `default`. Set
|
|
95
|
+
`name_by: source_position` explicitly to keep replay-safe names and accept the fragmentation.
|
|
96
|
+
|
|
97
|
+
- **`filter` expressions and a `switch`'s `when` cases are compiled when the config is loaded.**
|
|
98
|
+
An invalid expression is now a startup error naming the expression, instead of a per-message
|
|
99
|
+
failure that only surfaces once traffic arrives.
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- **`switch` forwards connect and disconnect hooks to its destinations**, `cases` and `default`
|
|
104
|
+
alike, and one failing teardown no longer skips the rest.
|
|
105
|
+
|
|
106
|
+
- **A failed `request` whose `forward_to` answers the caller surfaces the error** instead of
|
|
107
|
+
echoing the original message back as a success. The route then nacks (HTTP `500`) and a
|
|
108
|
+
`retry` or `dlq` on the endpoint sees the failure as usual. Forwarding to a plain sink still
|
|
109
|
+
acks, so routing a status with a `switch` is unchanged.
|
|
110
|
+
|
|
111
|
+
- **Concurrent MongoDB consumers no longer claim documents out from under each other.** Two
|
|
112
|
+
consumers polling within the same second write the same `locked_until`, which is all the claim
|
|
113
|
+
query had to work with, so one poll could read back documents another had just taken. Each
|
|
114
|
+
claim now carries a unique `claim_token`, and the read-back, unlock, ack and delete are all
|
|
115
|
+
scoped to it — an expired lease that was re-claimed elsewhere is no longer deleted from under
|
|
116
|
+
its new owner.
|
|
117
|
+
|
|
118
|
+
## 0.4.5
|
|
119
|
+
|
|
120
|
+
No library changes: CI workflow timeouts and a version bump.
|
|
121
|
+
|
|
5
122
|
## 0.4.4
|
|
6
123
|
|
|
7
124
|
### Breaking
|
|
@@ -3439,7 +3439,7 @@ dependencies = [
|
|
|
3439
3439
|
|
|
3440
3440
|
[[package]]
|
|
3441
3441
|
name = "mq-bridge"
|
|
3442
|
-
version = "0.4.
|
|
3442
|
+
version = "0.4.7"
|
|
3443
3443
|
dependencies = [
|
|
3444
3444
|
"aes-gcm",
|
|
3445
3445
|
"anyhow",
|
|
@@ -3524,7 +3524,7 @@ dependencies = [
|
|
|
3524
3524
|
|
|
3525
3525
|
[[package]]
|
|
3526
3526
|
name = "mq-bridge-bindings-common"
|
|
3527
|
-
version = "0.4.
|
|
3527
|
+
version = "0.4.7"
|
|
3528
3528
|
dependencies = [
|
|
3529
3529
|
"anyhow",
|
|
3530
3530
|
"fast-uuid-v7",
|
|
@@ -3538,7 +3538,7 @@ dependencies = [
|
|
|
3538
3538
|
|
|
3539
3539
|
[[package]]
|
|
3540
3540
|
name = "mq-bridge-node"
|
|
3541
|
-
version = "0.4.
|
|
3541
|
+
version = "0.4.7"
|
|
3542
3542
|
dependencies = [
|
|
3543
3543
|
"anyhow",
|
|
3544
3544
|
"async-trait",
|
|
@@ -3580,7 +3580,7 @@ dependencies = [
|
|
|
3580
3580
|
|
|
3581
3581
|
[[package]]
|
|
3582
3582
|
name = "mq-bridge-py"
|
|
3583
|
-
version = "0.4.
|
|
3583
|
+
version = "0.4.7"
|
|
3584
3584
|
dependencies = [
|
|
3585
3585
|
"anyhow",
|
|
3586
3586
|
"async-trait",
|
|
@@ -99,11 +99,16 @@ impl CustomEndpointFactory for PluginEndpointFactory {
|
|
|
99
99
|
if status == MQB_OK {
|
|
100
100
|
Ok(AssertSend(out))
|
|
101
101
|
} else {
|
|
102
|
-
|
|
102
|
+
// Classify rather than flattening to a string: a plugin that
|
|
103
|
+
// rejected its config reports MQB_ERR_INVALID_CONFIG, and the
|
|
104
|
+
// route only breaks out of its reconnect loop for the error
|
|
105
|
+
// classes it can downcast back out of this `anyhow`.
|
|
106
|
+
let cause = anyhow!(
|
|
103
107
|
"endpoint plugin `{}` could not open an input for route `{route}`: {}",
|
|
104
108
|
plugin.name(),
|
|
105
109
|
plugin.take_error(err)
|
|
106
|
-
)
|
|
110
|
+
);
|
|
111
|
+
Err(anyhow::Error::new(consumer_error_from(status, cause)))
|
|
107
112
|
}
|
|
108
113
|
})
|
|
109
114
|
.await
|
|
@@ -146,11 +151,13 @@ impl CustomEndpointFactory for PluginEndpointFactory {
|
|
|
146
151
|
if status == MQB_OK {
|
|
147
152
|
Ok(AssertSend(out))
|
|
148
153
|
} else {
|
|
149
|
-
|
|
154
|
+
// Classified for the same reason as the consumer side above.
|
|
155
|
+
let cause = anyhow!(
|
|
150
156
|
"endpoint plugin `{}` could not open an output for route `{route}`: {}",
|
|
151
157
|
plugin.name(),
|
|
152
158
|
plugin.take_error(err)
|
|
153
|
-
)
|
|
159
|
+
);
|
|
160
|
+
Err(anyhow::Error::new(publisher_error_from(status, cause)))
|
|
154
161
|
}
|
|
155
162
|
})
|
|
156
163
|
.await
|
|
@@ -513,7 +520,12 @@ fn publisher_error(
|
|
|
513
520
|
err: MqbBuffer,
|
|
514
521
|
action: &str,
|
|
515
522
|
) -> PublisherError {
|
|
516
|
-
|
|
523
|
+
publisher_error_from(status, plugin_cause(plugin, err, action))
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/// The status-to-class half of [`publisher_error`], for callers that already
|
|
527
|
+
/// turned the plugin's error buffer into a message.
|
|
528
|
+
pub(super) fn publisher_error_from(status: MqbStatus, cause: anyhow::Error) -> PublisherError {
|
|
517
529
|
match status {
|
|
518
530
|
MQB_ERR_RETRYABLE => PublisherError::Retryable(cause),
|
|
519
531
|
MQB_ERR_CONNECTION => PublisherError::Connection(cause),
|
|
@@ -545,4 +557,33 @@ mod tests {
|
|
|
545
557
|
MQB_DISPOSITION_ACK
|
|
546
558
|
);
|
|
547
559
|
}
|
|
560
|
+
|
|
561
|
+
// A plugin that rejected its config must not look like a transient fault:
|
|
562
|
+
// `create_consumer`/`create_publisher` classify with these, and the route
|
|
563
|
+
// only stops reconnecting for the permanent classes.
|
|
564
|
+
#[test]
|
|
565
|
+
fn a_rejected_plugin_config_is_permanent_not_retryable() {
|
|
566
|
+
assert!(matches!(
|
|
567
|
+
consumer_error_from(MQB_ERR_INVALID_CONFIG, anyhow!("bad field")),
|
|
568
|
+
ConsumerError::Permanent(_)
|
|
569
|
+
));
|
|
570
|
+
assert!(matches!(
|
|
571
|
+
publisher_error_from(MQB_ERR_INVALID_CONFIG, anyhow!("bad field")),
|
|
572
|
+
PublisherError::NonRetryable(_)
|
|
573
|
+
));
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// The other half of the contract: a connection failure stays retryable, so
|
|
577
|
+
// a broker that is merely down still gets the reconnect loop.
|
|
578
|
+
#[test]
|
|
579
|
+
fn a_plugin_connection_failure_stays_retryable() {
|
|
580
|
+
assert!(matches!(
|
|
581
|
+
consumer_error_from(MQB_ERR_CONNECTION, anyhow!("broker down")),
|
|
582
|
+
ConsumerError::Connection(_)
|
|
583
|
+
));
|
|
584
|
+
assert!(matches!(
|
|
585
|
+
publisher_error_from(MQB_ERR_CONNECTION, anyhow!("broker down")),
|
|
586
|
+
PublisherError::Connection(_)
|
|
587
|
+
));
|
|
588
|
+
}
|
|
548
589
|
}
|
|
@@ -101,13 +101,14 @@ impl Drop for OutcomeGuard {
|
|
|
101
101
|
RouteOutcome::Failed
|
|
102
102
|
});
|
|
103
103
|
// A route that discarded data did not run clean, whatever its outcome.
|
|
104
|
-
//
|
|
105
|
-
// route stopped
|
|
104
|
+
// Only a `Failed` route's cause is kept over the drop report: it explains
|
|
105
|
+
// why the route stopped. On any other outcome a lingering `error` is a
|
|
106
|
+
// stale reconnect failure the route recovered from, so the drops win.
|
|
106
107
|
{
|
|
107
108
|
let drops = recover_read_lock(&self.drops, "route_drop_report");
|
|
108
109
|
if drops.count > 0 {
|
|
109
110
|
let mut s = recover_write_lock(&self.status, "route_handle_status");
|
|
110
|
-
if s.error.is_none() {
|
|
111
|
+
if s.error.is_none() || !matches!(outcome, RouteOutcome::Failed) {
|
|
111
112
|
s.error = Some(format!(
|
|
112
113
|
"dropped {} message(s): sink rejected them permanently and no dlq middleware is configured: {}",
|
|
113
114
|
drops.count,
|
|
@@ -370,6 +371,25 @@ const DRAIN_MAX_RECONNECT_ATTEMPTS: usize = 10;
|
|
|
370
371
|
/// never reported healthy on the strength of the connect alone.
|
|
371
372
|
const STABLE_RUN: std::time::Duration = std::time::Duration::from_secs(30);
|
|
372
373
|
|
|
374
|
+
/// Forward a ready signal the run task already emitted but the reconnect loop
|
|
375
|
+
/// never observed.
|
|
376
|
+
///
|
|
377
|
+
/// The inner task signals ready onto a `bounded(1)` channel *before* its consume
|
|
378
|
+
/// loop, so the signal sits buffered. A drain over a small source can then reach
|
|
379
|
+
/// its terminal within the same scheduling window, leaving `select!` with two
|
|
380
|
+
/// ready branches and free to pick the terminal one at random. Without this, a
|
|
381
|
+
/// route that ran to completion is reported to `run()` as one that never started.
|
|
382
|
+
async fn forward_buffered_ready(
|
|
383
|
+
startup_notified: &mut bool,
|
|
384
|
+
iter_ready_rx: &async_channel::Receiver<()>,
|
|
385
|
+
ready_tx: &Sender<()>,
|
|
386
|
+
) {
|
|
387
|
+
if !*startup_notified && iter_ready_rx.try_recv().is_ok() {
|
|
388
|
+
let _ = ready_tx.send(()).await;
|
|
389
|
+
*startup_notified = true;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
373
393
|
async fn pause_after_empty_batch(delay_ms: u64) {
|
|
374
394
|
if delay_ms > 0 {
|
|
375
395
|
tokio::time::sleep(std::time::Duration::from_millis(delay_ms)).await;
|
|
@@ -1094,6 +1114,7 @@ impl Route {
|
|
|
1094
1114
|
let _ = internal_shutdown_tx.send(()).await;
|
|
1095
1115
|
// Wait for the inner task to finish gracefully.
|
|
1096
1116
|
let _ = run_task.await;
|
|
1117
|
+
forward_buffered_ready(&mut startup_notified, &iter_ready_rx, &ready_tx).await;
|
|
1097
1118
|
outcome_guard.set(RouteOutcome::Stopped);
|
|
1098
1119
|
break 'reconnect;
|
|
1099
1120
|
}
|
|
@@ -1126,6 +1147,7 @@ impl Route {
|
|
|
1126
1147
|
// Keep waiting for the run result / shutdown.
|
|
1127
1148
|
}
|
|
1128
1149
|
res = &mut run_task => {
|
|
1150
|
+
forward_buffered_ready(&mut startup_notified, &iter_ready_rx, &ready_tx).await;
|
|
1129
1151
|
match res {
|
|
1130
1152
|
Ok(Ok(should_continue)) if !should_continue => {
|
|
1131
1153
|
info!("Route '{}' completed gracefully. Shutting down.", name);
|
|
@@ -1226,32 +1248,49 @@ impl Route {
|
|
|
1226
1248
|
}
|
|
1227
1249
|
});
|
|
1228
1250
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1251
|
+
let started = tokio::time::timeout(startup_timeout, ready_rx.recv()).await;
|
|
1252
|
+
if let Ok(Ok(_)) = started {
|
|
1253
|
+
return Ok(RouteHandle {
|
|
1231
1254
|
handle,
|
|
1232
1255
|
shutdown_tx,
|
|
1233
1256
|
status,
|
|
1234
1257
|
outcome,
|
|
1235
|
-
})
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
handle.abort();
|
|
1261
|
+
// The startup failure itself stays inside the reconnect loop, so
|
|
1262
|
+
// surface the cause it recorded rather than a bare timeout.
|
|
1263
|
+
// "connecting" is the initial marker, not a recorded failure.
|
|
1264
|
+
let cause = recover_read_lock(&status, "route_handle_status")
|
|
1265
|
+
.error
|
|
1266
|
+
.clone()
|
|
1267
|
+
.filter(|e| e != "connecting")
|
|
1268
|
+
.map(|e| format!(": {e}"))
|
|
1269
|
+
.unwrap_or_default();
|
|
1270
|
+
Err(match started {
|
|
1271
|
+
// Every `ready_tx` was dropped: the route task ended without ever
|
|
1272
|
+
// signalling ready. That returns immediately, so calling it a timeout
|
|
1273
|
+
// sends the reader after a stall that never happened.
|
|
1274
|
+
Ok(Err(_)) => {
|
|
1275
|
+
let terminal = *recover_read_lock(&outcome, "route_handle_outcome");
|
|
1276
|
+
anyhow::anyhow!(
|
|
1277
|
+
"Route '{}' failed to start: ended before it signalled ready (outcome: {}){}",
|
|
1249
1278
|
name_str,
|
|
1250
|
-
|
|
1279
|
+
terminal.map_or("unknown", |o| match o {
|
|
1280
|
+
RouteOutcome::Completed => "completed",
|
|
1281
|
+
RouteOutcome::Stopped => "stopped",
|
|
1282
|
+
RouteOutcome::Failed => "failed",
|
|
1283
|
+
}),
|
|
1251
1284
|
cause
|
|
1252
|
-
)
|
|
1285
|
+
)
|
|
1253
1286
|
}
|
|
1254
|
-
|
|
1287
|
+
_ => anyhow::anyhow!(
|
|
1288
|
+
"Route '{}' failed to start: did not become ready within {}ms{}",
|
|
1289
|
+
name_str,
|
|
1290
|
+
startup_timeout.as_millis(),
|
|
1291
|
+
cause
|
|
1292
|
+
),
|
|
1293
|
+
})
|
|
1255
1294
|
}
|
|
1256
1295
|
|
|
1257
1296
|
/// The core logic of running the route, designed to be called within a reconnect loop.
|
|
@@ -3556,6 +3595,44 @@ mod tests {
|
|
|
3556
3595
|
assert_eq!(state.publisher_disconnects.load(Ordering::SeqCst), 1);
|
|
3557
3596
|
}
|
|
3558
3597
|
|
|
3598
|
+
#[tokio::test]
|
|
3599
|
+
async fn test_forward_buffered_ready_delivers_a_signal_the_loop_never_observed() {
|
|
3600
|
+
// The terminal arms of the reconnect loop can win the `select!` race against a
|
|
3601
|
+
// ready signal the run task already buffered. Forwarding it from there is what
|
|
3602
|
+
// keeps a route that ran to completion from being reported as one that never
|
|
3603
|
+
// started.
|
|
3604
|
+
let (iter_ready_tx, iter_ready_rx) = bounded::<()>(1);
|
|
3605
|
+
let (ready_tx, ready_rx) = bounded::<()>(1);
|
|
3606
|
+
iter_ready_tx.send(()).await.unwrap();
|
|
3607
|
+
|
|
3608
|
+
let mut startup_notified = false;
|
|
3609
|
+
forward_buffered_ready(&mut startup_notified, &iter_ready_rx, &ready_tx).await;
|
|
3610
|
+
assert!(startup_notified);
|
|
3611
|
+
assert!(
|
|
3612
|
+
ready_rx.try_recv().is_ok(),
|
|
3613
|
+
"buffered ready must reach `run()`"
|
|
3614
|
+
);
|
|
3615
|
+
|
|
3616
|
+
// `run()` consumes the startup channel once, so a second send would sit unread.
|
|
3617
|
+
iter_ready_tx.send(()).await.unwrap();
|
|
3618
|
+
forward_buffered_ready(&mut startup_notified, &iter_ready_rx, &ready_tx).await;
|
|
3619
|
+
assert!(
|
|
3620
|
+
ready_rx.try_recv().is_err(),
|
|
3621
|
+
"startup must not be notified twice"
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
#[tokio::test]
|
|
3626
|
+
async fn test_forward_buffered_ready_keeps_a_never_ready_route_a_failure() {
|
|
3627
|
+
let (_iter_ready_tx, iter_ready_rx) = bounded::<()>(1);
|
|
3628
|
+
let (ready_tx, ready_rx) = bounded::<()>(1);
|
|
3629
|
+
|
|
3630
|
+
let mut startup_notified = false;
|
|
3631
|
+
forward_buffered_ready(&mut startup_notified, &iter_ready_rx, &ready_tx).await;
|
|
3632
|
+
assert!(!startup_notified);
|
|
3633
|
+
assert!(ready_rx.try_recv().is_err());
|
|
3634
|
+
}
|
|
3635
|
+
|
|
3559
3636
|
#[tokio::test]
|
|
3560
3637
|
async fn test_start_fails_on_unavailable_endpoint() {
|
|
3561
3638
|
// tokio::time::pause();
|
|
@@ -3582,8 +3659,54 @@ mod tests {
|
|
|
3582
3659
|
// The route should fail to start because the input endpoint fails to create.
|
|
3583
3660
|
// The run() method waits for a ready signal which never comes.
|
|
3584
3661
|
let result = route.run("test_start_fail").await;
|
|
3585
|
-
|
|
3586
|
-
|
|
3662
|
+
let err = result.expect_err("must fail").to_string();
|
|
3663
|
+
// A stalled connect is a timeout, not a route that ended: the two now read
|
|
3664
|
+
// differently, and the recorded cause rides along.
|
|
3665
|
+
assert!(
|
|
3666
|
+
err.contains("failed to start: did not become ready within 5000ms")
|
|
3667
|
+
&& err.contains("Endpoint unavailable"),
|
|
3668
|
+
"got: {err}"
|
|
3669
|
+
);
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3672
|
+
#[tokio::test]
|
|
3673
|
+
async fn test_start_failure_distinguishes_an_ended_route_from_a_timeout() {
|
|
3674
|
+
// A drain gives up after DRAIN_MAX_RECONNECT_ATTEMPTS, so the route task ends
|
|
3675
|
+
// long before the startup timeout. `ready_rx` then fails immediately, and
|
|
3676
|
+
// calling that a 5000ms timeout sends the reader after a stall that never
|
|
3677
|
+
// happened.
|
|
3678
|
+
let factory_name = format!("ended_before_ready_{}", fast_uuid_v7::gen_id());
|
|
3679
|
+
register_endpoint_factory(
|
|
3680
|
+
&factory_name,
|
|
3681
|
+
Arc::new(MockEndpointFactory {
|
|
3682
|
+
create_consumer_fail: true,
|
|
3683
|
+
..MockEndpointFactory::new()
|
|
3684
|
+
}),
|
|
3685
|
+
)
|
|
3686
|
+
.unwrap();
|
|
3687
|
+
|
|
3688
|
+
let input = Endpoint {
|
|
3689
|
+
endpoint_type: EndpointType::Custom {
|
|
3690
|
+
name: factory_name,
|
|
3691
|
+
config: serde_json::Value::Null,
|
|
3692
|
+
},
|
|
3693
|
+
middlewares: vec![],
|
|
3694
|
+
handler: None,
|
|
3695
|
+
};
|
|
3696
|
+
let route = Route::new(input, Endpoint::new_memory("out", 10))
|
|
3697
|
+
.with_exit_on_empty(true)
|
|
3698
|
+
.with_reconnect_interval_ms(1);
|
|
3699
|
+
|
|
3700
|
+
let err = route
|
|
3701
|
+
.run("test_ended_before_ready")
|
|
3702
|
+
.await
|
|
3703
|
+
.expect_err("must fail")
|
|
3704
|
+
.to_string();
|
|
3705
|
+
assert!(
|
|
3706
|
+
err.contains("failed to start: ended before it signalled ready")
|
|
3707
|
+
&& err.contains("outcome: failed"),
|
|
3708
|
+
"got: {err}"
|
|
3709
|
+
);
|
|
3587
3710
|
}
|
|
3588
3711
|
|
|
3589
3712
|
#[tokio::test]
|
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/.github/ISSUE_TEMPLATE/feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/bench_memory.py
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/bench_memory.yaml
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/consume_pull.py
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/dlt_source.py
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/json_route.py
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/memory.yaml
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/examples/raw_route.py
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/pyproject-basic.toml
RENAMED
|
File without changes
|
{mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.7}/python/mq-bridge-py/pyproject-reduced.toml
RENAMED
|
File without changes
|