mq-bridge-py-basic 0.4.6__tar.gz → 0.4.8__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.
Files changed (301) hide show
  1. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/ci.yml +14 -0
  2. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/CHANGELOG.md +187 -0
  3. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/Cargo.lock +76 -179
  4. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/Cargo.toml +15 -8
  5. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/PKG-INFO +1 -1
  6. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/build.rs +15 -2
  7. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/CONFIGURATION.md +16 -4
  8. mq_bridge_py_basic-0.4.8/docs/GRPC.md +263 -0
  9. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/REFERENCE.md +15 -0
  10. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/config.pyi +11 -0
  11. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/consumer.rs +322 -0
  12. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/dynamic.rs +841 -0
  13. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/mod.rs +249 -0
  14. mq_bridge_py_basic-0.4.6/src/endpoints/grpc.proto → mq_bridge_py_basic-0.4.8/src/endpoints/grpc/proto/mqbridge/bridge.proto +11 -8
  15. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/publisher.rs +254 -0
  16. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/server.rs +1000 -0
  17. mq_bridge_py_basic-0.4.8/src/endpoints/grpc/tests.rs +1520 -0
  18. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/http/mod.rs +4 -26
  19. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/http/tests.rs +37 -0
  20. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mod.rs +1 -3
  21. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/request.rs +292 -1
  22. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/filter.rs +115 -12
  23. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models/builders.rs +3 -3
  24. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models/secrets.rs +52 -0
  25. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models/tests.rs +39 -0
  26. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models.rs +44 -4
  27. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/endpoint.rs +46 -5
  28. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/route.rs +236 -24
  29. mq_bridge_py_basic-0.4.8/src/support/compression.rs +309 -0
  30. mq_bridge_py_basic-0.4.8/src/support/compression_pool.rs +236 -0
  31. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/crypto.rs +115 -43
  32. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/mod.rs +2 -0
  33. mq_bridge_py_basic-0.4.8/tests/compat/python/bridge_client.py +68 -0
  34. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/grpc_tls.rs +0 -2
  35. mq_bridge_py_basic-0.4.6/src/endpoints/grpc.rs +0 -2347
  36. mq_bridge_py_basic-0.4.6/src/support/compression.rs +0 -179
  37. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  38. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  39. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  40. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/dependabot.yml +0 -0
  41. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/benchmark.yml +0 -0
  42. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/ibm-mq.yml +0 -0
  43. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/node.yml +0 -0
  44. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/publish-node.yml +0 -0
  45. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/publish-python.yml +0 -0
  46. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/python.yml +0 -0
  47. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/release.yml +0 -0
  48. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.github/workflows/test-matrix.yml +0 -0
  49. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/.gitignore +0 -0
  50. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/CLAUDE.md +0 -0
  51. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/CONTRIBUTING.md +0 -0
  52. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/LICENSE +0 -0
  53. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/LICENSE.python +0 -0
  54. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/README.md +0 -0
  55. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/SECURITY.md +0 -0
  56. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/benches/ETL_BENCHMARKS.md +0 -0
  57. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/benches/performance_bench.rs +0 -0
  58. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/benches/router_bench.rs +0 -0
  59. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/benches/zeromq_backends.rs +0 -0
  60. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/bindings-common/Cargo.toml +0 -0
  61. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/bindings-common/src/lib.rs +0 -0
  62. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/bindings-common/src/logging.rs +0 -0
  63. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/deny.toml +0 -0
  64. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/ARCHITECTURE.md +0 -0
  65. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/DELIVERY.md +0 -0
  66. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/EXTENDING.md +0 -0
  67. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/docs/PLUGINS.md +0 -0
  68. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/examples/ipc_worker_queue.yaml +0 -0
  69. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq-bridge.schema.json +0 -0
  70. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/__init__.py +0 -0
  71. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/__init__.pyi +0 -0
  72. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/config.py +0 -0
  73. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/plugin_packaging.py +0 -0
  74. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/mq_bridge/py.typed +0 -0
  75. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/package-lock.json +0 -0
  76. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/pyproject.toml +0 -0
  77. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/Cargo.toml +0 -0
  78. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/LICENSE.python +0 -0
  79. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/README.md +0 -0
  80. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  81. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/example.py +0 -0
  82. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  83. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  84. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/consume_pull.py +0 -0
  85. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/dlt_source.py +0 -0
  86. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/json_route.py +0 -0
  87. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/memory.yaml +0 -0
  88. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/examples/raw_route.py +0 -0
  89. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/pyproject-basic.toml +0 -0
  90. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
  91. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
  92. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/src/lib.rs +0 -0
  93. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_config_types.py +0 -0
  94. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
  95. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_logging.py +0 -0
  96. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_packaging.py +0 -0
  97. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  98. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
  99. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_public_api.py +0 -0
  100. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/tests/test_routes.py +0 -0
  101. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/python/mq-bridge-py/uv.lock +0 -0
  102. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/benches/metadata_bench.rs +0 -0
  103. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  104. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  105. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/http/http_flamegraph.py +0 -0
  106. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  107. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/analysis/http/run_http_ladder.sh +0 -0
  108. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/ci/format_bench_output.sh +0 -0
  109. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/httparena/README.md +0 -0
  110. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
  111. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  112. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  113. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  114. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  115. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  116. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  117. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/README.md +0 -0
  118. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/postgres.yml +0 -0
  119. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/seed.sql +0 -0
  120. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/techempower/verify.sh +0 -0
  121. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/the-benchmarker/README.md +0 -0
  122. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  123. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  124. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  125. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/canonical_message.rs +0 -0
  126. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/checkpoint.rs +0 -0
  127. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/command_handler.rs +0 -0
  128. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/amqp.rs +0 -0
  129. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/aws.rs +0 -0
  130. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/clickhouse.rs +0 -0
  131. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/file/mod.rs +0 -0
  132. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/file/tests.rs +0 -0
  133. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/http/publisher.rs +0 -0
  134. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/http/stream.rs +0 -0
  135. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/ibm_mq.rs +0 -0
  136. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/kafka.rs +0 -0
  137. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/endpoint.rs +0 -0
  138. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/framed.rs +0 -0
  139. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/ipc_unix.rs +0 -0
  140. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/ipc_windows.rs +0 -0
  141. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/memory_transport.rs +0 -0
  142. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/mod.rs +0 -0
  143. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/memory/transport.rs +0 -0
  144. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/consumer.rs +0 -0
  145. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/dedup.rs +0 -0
  146. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/mod.rs +0 -0
  147. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/publisher.rs +0 -0
  148. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/readers.rs +0 -0
  149. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mongodb/tests.rs +0 -0
  150. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/mqtt.rs +0 -0
  151. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/nats.rs +0 -0
  152. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/object_store.rs +0 -0
  153. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/poll.rs +0 -0
  154. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/VENDORED.md +0 -0
  155. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/mod.rs +0 -0
  156. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
  157. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
  158. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
  159. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
  160. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/pgoutput/values.rs +0 -0
  161. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/replication.rs +0 -0
  162. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/postgres/state.rs +0 -0
  163. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/redis_streams.rs +0 -0
  164. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/sled.rs +0 -0
  165. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/sqlx/dedup.rs +0 -0
  166. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/sqlx/mod.rs +0 -0
  167. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/sqlx/tests.rs +0 -0
  168. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/fanout.rs +0 -0
  169. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/mod.rs +0 -0
  170. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/null.rs +0 -0
  171. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/reader.rs +0 -0
  172. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/response.rs +0 -0
  173. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/static_endpoint.rs +0 -0
  174. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/stream_buffer.rs +0 -0
  175. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/structural/switch.rs +0 -0
  176. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/websocket.rs +0 -0
  177. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/zeromq/codec.rs +0 -0
  178. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/zeromq/mod.rs +0 -0
  179. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/zeromq/omq.rs +0 -0
  180. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/endpoints/zeromq/zmq.rs +0 -0
  181. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/errors.rs +0 -0
  182. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/event_handler.rs +0 -0
  183. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/event_store.rs +0 -0
  184. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/extensions.rs +0 -0
  185. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/lib.rs +0 -0
  186. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/buffer.rs +0 -0
  187. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/compression.rs +0 -0
  188. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/cookie_jar.rs +0 -0
  189. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/deduplication.rs +0 -0
  190. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/deferred_commit.rs +0 -0
  191. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/delay.rs +0 -0
  192. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/dlq.rs +0 -0
  193. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/encryption.rs +0 -0
  194. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/id.rs +0 -0
  195. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/limiter.rs +0 -0
  196. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/metrics.rs +0 -0
  197. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/mod.rs +0 -0
  198. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/random_panic.rs +0 -0
  199. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/raw_json.rs +0 -0
  200. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/retry.rs +0 -0
  201. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/coerce.rs +0 -0
  202. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/compiled.rs +0 -0
  203. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/error.rs +0 -0
  204. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/mod.rs +0 -0
  205. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/path.rs +0 -0
  206. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/schema.rs +0 -0
  207. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/transform/tests.rs +0 -0
  208. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/middleware/weak_join.rs +0 -0
  209. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models/defaults.rs +0 -0
  210. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/models/serde_support.rs +0 -0
  211. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/outcomes.rs +0 -0
  212. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/conformance.rs +0 -0
  213. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/message.rs +0 -0
  214. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/middleware.rs +0 -0
  215. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/mod.rs +0 -0
  216. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/sdk.rs +0 -0
  217. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/plugin/test_support.rs +0 -0
  218. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/publisher.rs +0 -0
  219. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/response.rs +0 -0
  220. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/base64_engine.rs +0 -0
  221. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/connection_registry.rs +0 -0
  222. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/crypto_envelope.rs +0 -0
  223. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/interpolation.rs +0 -0
  224. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/plugin_abi.rs +0 -0
  225. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/support/source_ranges.rs +0 -0
  226. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/test_utils.rs +0 -0
  227. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/traits.rs +0 -0
  228. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/src/type_handler.rs +0 -0
  229. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/README.md +0 -0
  230. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/armature_integration.rs +0 -0
  231. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/amqp.rs +0 -0
  232. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/aws.rs +0 -0
  233. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/clickhouse.rs +0 -0
  234. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/config.toml +0 -0
  235. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/amqp.yml +0 -0
  236. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/aws.yml +0 -0
  237. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/clickhouse.yml +0 -0
  238. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  239. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  240. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  241. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  242. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  243. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  244. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  245. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  246. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/kafka.yml +0 -0
  247. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mariadb.yml +0 -0
  248. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  249. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  250. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mongodb.yml +0 -0
  251. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mosquitto.conf +0 -0
  252. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  253. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  254. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  255. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  256. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mqtt.yml +0 -0
  257. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  258. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/mysql.yml +0 -0
  259. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/nats.yml +0 -0
  260. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/object_store.yml +0 -0
  261. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/postgres.yml +0 -0
  262. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
  263. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/docker-compose/redis.yml +0 -0
  264. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/file.rs +0 -0
  265. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/grpc.rs +0 -0
  266. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/http.rs +0 -0
  267. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/http_tls.rs +0 -0
  268. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/ibm_mq.rs +0 -0
  269. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/ibm_mq_tls.rs +0 -0
  270. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/ipc.rs +0 -0
  271. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/kafka.rs +0 -0
  272. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/kafka_tls.rs +0 -0
  273. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/logic_test.rs +0 -0
  274. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mariadb.rs +0 -0
  275. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/memory.rs +0 -0
  276. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mod.rs +0 -0
  277. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mongodb.rs +0 -0
  278. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mongodb_raw.rs +0 -0
  279. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mongodb_tls.rs +0 -0
  280. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mqtt.rs +0 -0
  281. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/mysql.rs +0 -0
  282. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/nats.rs +0 -0
  283. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/object_store.rs +0 -0
  284. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/performance_static.rs +0 -0
  285. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/postgres.rs +0 -0
  286. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/postgres_cdc.rs +0 -0
  287. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/redis_streams.rs +0 -0
  288. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/route.rs +0 -0
  289. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/scripts/gen_certs.sh +0 -0
  290. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/sqlite.rs +0 -0
  291. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/tls_helpers.rs +0 -0
  292. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/websocket.rs +0 -0
  293. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration/zeromq.rs +0 -0
  294. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/integration_test.rs +0 -0
  295. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/memory_leak_test.rs +0 -0
  296. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/ref_test.rs +0 -0
  297. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/reference_docs_test.rs +0 -0
  298. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/sqlite_test.rs +0 -0
  299. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/tls_example.rs +0 -0
  300. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/unit_tests.md +0 -0
  301. {mq_bridge_py_basic-0.4.6 → mq_bridge_py_basic-0.4.8}/tests/websocket_test.rs +0 -0
@@ -42,6 +42,11 @@ jobs:
42
42
  - name: Run clippy
43
43
  run: cargo clippy --all-targets --all-features -- -D warnings
44
44
 
45
+ # Not a workspace default member, so nothing else builds it. It pins the
46
+ # exhaustive `GrpcConfig` literal a downstream crate would write.
47
+ - name: Check downstream config-compat fixture
48
+ run: cargo check -p grpc-config-compat
49
+
45
50
  # Every feature subset still gets its own `cargo check`, but sequentially in one
46
51
  # job: the matrix cost 8 runner slots at the moment integration-build's dependents
47
52
  # were starving, and none of this is on the critical path.
@@ -87,6 +92,15 @@ jobs:
87
92
 
88
93
  - name: Cache cargo build
89
94
  uses: Swatinem/rust-cache@v2
95
+
96
+ # setup-python provides a non-PEP-668 interpreter; the system python3 on
97
+ # ubuntu-latest is externally managed and rejects a plain pip install.
98
+ - uses: actions/setup-python@v5
99
+ with:
100
+ python-version: '3.12'
101
+
102
+ - name: Install Python gRPC compatibility tools
103
+ run: python3 -m pip install grpcio-tools
90
104
 
91
105
  - name: Run unit tests
92
106
  run: cargo test --lib --features=full
@@ -2,6 +2,193 @@
2
2
 
3
3
  All notable changes to `mq-bridge`. Newest first.
4
4
 
5
+ ## 0.4.8
6
+
7
+ ### Added
8
+
9
+ - **Dynamic gRPC sinks.** The descriptor keys now work on a route's `output` too: a unary method
10
+ makes one call per message and returns the reply as its response, a client-streaming method
11
+ streams a batch into one call. Server-streaming and bidirectional methods, and `request`, are
12
+ rejected there. Status codes that mean "never going to succeed" are non-retryable, so such a
13
+ message is dead-lettered instead of replayed.
14
+
15
+ - **gRPC server reflection, on both sides.** `reflection: true` discovers descriptors from the
16
+ remote server instead of a descriptor file, and server mode hosts reflection v1 and v1alpha,
17
+ so `grpcurl` can introspect an embedded server.
18
+
19
+ - **Metadata and credentials for dynamic gRPC calls.** `metadata`, `binary_metadata`,
20
+ `bearer_token`, and `api_key`/`api_key_name`, sent on the reflection call as well. They never
21
+ appear in errors or logs, and are startup errors on Bridge and server mode rather than a silent
22
+ unauthenticated connection — authenticate that with TLS client certificates.
23
+
24
+ - **Separate gRPC deadlines.** `connect_timeout_ms`, `request_timeout_ms`,
25
+ `idle_stream_timeout_ms` (retryable: the route reconnects), and `overall_timeout_ms` (terminal:
26
+ reconnecting would reset the cap). All default to disabled.
27
+
28
+ - **`descriptor_set_bytes`** passes a compiled gRPC `FileDescriptorSet` straight from embedded
29
+ Rust callers, with no temporary file.
30
+
31
+ - **Provenance on dynamic gRPC responses.** A deterministic id per response, plus `grpc.service`,
32
+ `grpc.method`, `grpc.response_index`, and `grpc.ack_guarantee=none` metadata.
33
+
34
+ - **[docs/GRPC.md](docs/GRPC.md).** The full gRPC guide, including why a generic
35
+ descriptor-driven server is intentionally not implemented. The Bridge contract moved to
36
+ `src/endpoints/grpc/proto/mqbridge/bridge.proto`, unchanged on the wire, and CI now checks a
37
+ generated Python client against server mode.
38
+
39
+ ### Changed
40
+
41
+ - **Adding the dedicated gRPC deadline fields is a breaking Rust API change for exhaustive
42
+ `GrpcConfig` struct literals.** Downstream Rust callers must specify the new fields or use
43
+ `..Default::default()` / `GrpcConfig::new`. A downstream compile fixture now locks the complete
44
+ literal shape so future additions cannot make this break silently.
45
+
46
+ - **gRPC `bearer_token` and `api_key` now require an `https://` endpoint.** A credential sent over
47
+ plaintext h2c is rejected rather than put on the wire in the clear. Deployments that terminated
48
+ TLS at a sidecar and spoke plaintext gRPC to it must point the endpoint at `https://`.
49
+
50
+ - **The gRPC endpoint's `timeout_ms` and `server_streaming` are deprecated but still accepted.**
51
+ `timeout_ms` stays the fallback for connection and request setup; it no longer bounds a dynamic
52
+ stream, which needs the dedicated keys. RPC shape comes from the descriptor, so a disagreeing
53
+ `server_streaming` warns instead of failing startup.
54
+
55
+ - **gRPC descriptor keys on an `output` select the dynamic publisher.** They were previously
56
+ ignored there and the Bridge publisher was used.
57
+
58
+ - **gRPC failures preserve code, message, and trailing metadata** in a `GrpcStatusError`. Its
59
+ `Display`/`Debug` omit trailer values so a peer's credentials cannot leak into logs.
60
+
61
+ - **Filtering and structural forwarding retain bulk writes where possible.** An input `filter`
62
+ now reads additional full source batches after dropping rows until it refills the requested
63
+ batch size; a naturally short source batch remains a flush boundary so live routes do not
64
+ wait indefinitely. A `request` still performs its request/reply calls individually and
65
+ concurrently, unless its `to` endpoint requires ordered publishing; ordered requests run one
66
+ at a time. Results are restored to input order and responses plus error fallbacks are sent to
67
+ `forward_to` in one `send_batch` call. Batch-capable destinations such as MongoDB can
68
+ therefore continue using `insert_many` through both paths.
69
+
70
+ - **Buffered concurrent routes warn that destination order is not guaranteed.** Buffering
71
+ preserves order within each batch, but with route `concurrency > 1` separate destination
72
+ writes may complete out of source order. Route validation now recommends `concurrency: 1`
73
+ when destination order matters.
74
+
75
+ ## 0.4.7
76
+
77
+ ### Changed
78
+
79
+ - **The startup failure message distinguishes its two causes.** A route that never became ready
80
+ reports `failed to start: did not become ready within {n}ms`; a route whose task ended before
81
+ signalling ready reports `failed to start: ended before it signalled ready (outcome: ...)`.
82
+ The second case returns immediately and never involved the timeout, so reporting it as one
83
+ sent the reader looking for a stall that never happened. Both now carry the cause the
84
+ reconnect loop recorded, which the old message dropped. Code matching on the old
85
+ `failed to start within {n}ms or encountered an error` text needs updating; the substring
86
+ `failed to start` is unchanged.
87
+
88
+ ### Fixed
89
+
90
+ - **A route that ran to completion is no longer reported as one that failed to start.** The run
91
+ task signals ready before its consume loop, so a drain over a small source can reach its
92
+ terminal while that signal is still buffered — leaving the reconnect loop's `select!` with two
93
+ ready branches and free to take the terminal one, dropping the startup channel unread.
94
+ `Route::run()` then returned an error for a drain that had already written its output, and
95
+ `mqb copy --drain` exited non-zero on a successful copy. Both terminal arms now forward a
96
+ ready signal that was already emitted.
97
+
98
+ - **A completed route reports the messages it dropped even after an earlier reconnect failure.**
99
+ The drop report was suppressed whenever `EndpointStatus::error` was already set, including by a
100
+ transient failure the route recovered from. Only a `Failed` route's cause now outranks it.
101
+
102
+ - **A plugin endpoint that rejects its config no longer reconnects forever.** `create_consumer`
103
+ and `create_publisher` flattened the plugin's status into a bare message, and the reconnect
104
+ loop decides by downcasting to `ConsumerError`/`PublisherError` — so every failure to open
105
+ looked like a connection fault worth retrying. A plugin answering `MQB_ERR_INVALID_CONFIG`,
106
+ `MQB_ERR_UNSUPPORTED`, `MQB_ERR_PERMANENT` or `MQB_ERR_PANIC` now stops the route with that
107
+ cause; `MQB_ERR_CONNECTION` and `MQB_ERR_RETRYABLE` still get the reconnect loop.
108
+
109
+ ## 0.4.6
110
+
111
+ ### Added
112
+
113
+ - **`filter` middleware.** Keeps only the messages matching an expression and drops the rest,
114
+ on the input or the output: `- filter: "amount > 100"`. Payload fields are read by bare name
115
+ (`amount`, `order.status`), metadata under `meta.` and always as text, so a numeric comparison
116
+ needs a cast (`number(meta.http_status_code) >= 400`); `&&`/`||` and `and`/`or` both work. A
117
+ metadata-only expression never parses the payload. **Prefer the input** — a filter there drops
118
+ the message before the rest of the route touches it and acks it at the source. Requires the
119
+ new `filter` feature (it pulls the `zen-expression` engine), which is part of `middleware` and
120
+ `full` but **not** of `portable`.
121
+
122
+ - **Predicate mode for `switch`.** `when: [{ if, to }, ...]` routes on the same expression
123
+ language, first match wins, so overlapping thresholds are safe to write and a payload-derived
124
+ key no longer has to be promoted into metadata first. A `switch` uses exactly one of `when` or
125
+ `metadata_key`/`cases`; naming both or neither is a startup error, as is a `when` list in a
126
+ build without the `filter` feature. Value lookup stays the cheaper mode when the key is
127
+ already in metadata.
128
+
129
+ - **`expression` on `transform`.** A Zen expression producing the output document, applied after
130
+ `mapping` and before `schema` — for values that have to be calculated rather than copied.
131
+ Needs the `zen` feature.
132
+
133
+ - **A `fanout` can reply.** If one branch produces a response — a `response` or `static` leg, or
134
+ a `request` whose `forward_to` replies — that response goes back to the caller, so a
135
+ request/reply input can fan a message out and still answer. Only one branch may answer: if
136
+ several do, the first in list order wins, and the route warns once rather than on every
137
+ message. A branch that *fails* nacks the whole fan-out, so the caller gets a `500` rather than
138
+ an answer that hides a lost message; opt out per branch with a `request` whose `forward_to`
139
+ does not reply, or a `dlq` on a plain branch.
140
+
141
+ - **`pass_through_status` on the `http` endpoint.** On a **publisher**, a non-2xx response
142
+ becomes response data instead of a publisher error, so a route can branch on
143
+ `http_status_code` with a `switch` rather than treating every 404 as a failed send. Transport
144
+ failures and unreadable responses are still errors. On a **consumer**, once every output sink
145
+ opts in, a transient sink failure answers the request with `502` instead of stopping and
146
+ reconnecting a non-streaming request/reply route. Composite outputs such as `fanout` need the
147
+ flag on every leaf sink — a mixed output keeps the normal stop-and-reconnect policy — and
148
+ streamable HTTP inputs keep their protocol-specific error frames.
149
+
150
+ ### Changed
151
+
152
+ - **A middleware that empties a batch no longer acknowledges ahead of the route.** `filter` and
153
+ `deduplication` can filter a batch down to nothing, and acking that straight away jumps ahead
154
+ of batches the route is still writing on a source with cumulative acks — the ordered sequencer
155
+ only sees the commits `receive_batch` returns, so a crash in that window lost them. On those
156
+ sources the emptied batch's commit is now held and runs from inside the next retained batch's
157
+ commit, which the sequencer does order.
158
+
159
+ - **An `object_store` sink on `name_by: auto` switches to `write_time` names when a row-dropping
160
+ middleware is on the route.** A source-range name covers one *contiguous* run of positions, so
161
+ a batch with holes punched in it would be written as one object per surviving run — a filter
162
+ keeping 80% of rows turns one upload into roughly a hundred. The route logs one line at
163
+ startup saying it made the switch. This covers `filter`, `deduplication`, `weak_join`,
164
+ `transform` with `on_error: reject`, and a `switch` in `when` mode with no `default`. Set
165
+ `name_by: source_position` explicitly to keep replay-safe names and accept the fragmentation.
166
+
167
+ - **`filter` expressions and a `switch`'s `when` cases are compiled when the config is loaded.**
168
+ An invalid expression is now a startup error naming the expression, instead of a per-message
169
+ failure that only surfaces once traffic arrives.
170
+
171
+ ### Fixed
172
+
173
+ - **`switch` forwards connect and disconnect hooks to its destinations**, `cases` and `default`
174
+ alike, and one failing teardown no longer skips the rest.
175
+
176
+ - **A failed `request` whose `forward_to` answers the caller surfaces the error** instead of
177
+ echoing the original message back as a success. The route then nacks (HTTP `500`) and a
178
+ `retry` or `dlq` on the endpoint sees the failure as usual. Forwarding to a plain sink still
179
+ acks, so routing a status with a `switch` is unchanged.
180
+
181
+ - **Concurrent MongoDB consumers no longer claim documents out from under each other.** Two
182
+ consumers polling within the same second write the same `locked_until`, which is all the claim
183
+ query had to work with, so one poll could read back documents another had just taken. Each
184
+ claim now carries a unique `claim_token`, and the read-back, unlock, ack and delete are all
185
+ scoped to it — an expired lease that was re-claimed elsewhere is no longer deleted from under
186
+ its new owner.
187
+
188
+ ## 0.4.5
189
+
190
+ No library changes: CI workflow timeouts and a version bump.
191
+
5
192
  ## 0.4.4
6
193
 
7
194
  ### Breaking