mq-bridge-py-basic 0.4.4__tar.gz → 0.4.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/ci.yml +70 -126
  2. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/ibm-mq.yml +12 -2
  3. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/node.yml +6 -0
  4. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/python.yml +6 -0
  5. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/test-matrix.yml +6 -0
  6. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/CHANGELOG.md +87 -0
  7. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/CLAUDE.md +3 -1
  8. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/Cargo.lock +360 -8
  9. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/Cargo.toml +12 -2
  10. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/PKG-INFO +1 -1
  11. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/README.md +2 -2
  12. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/CONFIGURATION.md +7 -0
  13. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/DELIVERY.md +58 -26
  14. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/REFERENCE.md +169 -14
  15. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq-bridge.schema.json +107 -20
  16. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/config.py +4 -0
  17. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/config.pyi +23 -5
  18. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/scripts/gen_config_types.py +22 -3
  19. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/file/mod.rs +35 -22
  20. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/file/tests.rs +7 -7
  21. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/http/publisher.rs +3 -1
  22. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/http/tests.rs +71 -0
  23. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mod.rs +684 -49
  24. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/consumer.rs +84 -29
  25. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/object_store.rs +554 -84
  26. mq_bridge_py_basic-0.4.6/src/endpoints/structural/fanout.rs +615 -0
  27. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/request.rs +73 -7
  28. mq_bridge_py_basic-0.4.6/src/endpoints/structural/switch.rs +645 -0
  29. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/deduplication.rs +61 -8
  30. mq_bridge_py_basic-0.4.6/src/middleware/deferred_commit.rs +170 -0
  31. mq_bridge_py_basic-0.4.6/src/middleware/filter.rs +1278 -0
  32. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/mod.rs +11 -0
  33. mq_bridge_py_basic-0.4.6/src/middleware/raw_json.rs +31 -0
  34. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/compiled.rs +84 -3
  35. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/error.rs +4 -0
  36. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/schema.rs +0 -34
  37. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/tests.rs +48 -0
  38. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models/builders.rs +36 -6
  39. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models/defaults.rs +1 -19
  40. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models/serde_support.rs +1 -0
  41. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models/tests.rs +103 -1
  42. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models.rs +140 -18
  43. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/route.rs +506 -28
  44. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/source_ranges.rs +47 -0
  45. mq_bridge_py_basic-0.4.4/src/endpoints/structural/fanout.rs +0 -285
  46. mq_bridge_py_basic-0.4.4/src/endpoints/structural/switch.rs +0 -264
  47. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  48. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  49. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  50. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/dependabot.yml +0 -0
  51. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/benchmark.yml +0 -0
  52. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/publish-node.yml +0 -0
  53. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/publish-python.yml +0 -0
  54. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.github/workflows/release.yml +0 -0
  55. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/.gitignore +0 -0
  56. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/CONTRIBUTING.md +0 -0
  57. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/LICENSE +0 -0
  58. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/LICENSE.python +0 -0
  59. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/SECURITY.md +0 -0
  60. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/benches/ETL_BENCHMARKS.md +0 -0
  61. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/benches/performance_bench.rs +0 -0
  62. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/benches/router_bench.rs +0 -0
  63. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/benches/zeromq_backends.rs +0 -0
  64. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/bindings-common/Cargo.toml +0 -0
  65. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/bindings-common/src/lib.rs +0 -0
  66. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/bindings-common/src/logging.rs +0 -0
  67. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/build.rs +0 -0
  68. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/deny.toml +0 -0
  69. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/ARCHITECTURE.md +0 -0
  70. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/EXTENDING.md +0 -0
  71. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/docs/PLUGINS.md +0 -0
  72. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/examples/ipc_worker_queue.yaml +0 -0
  73. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/__init__.py +0 -0
  74. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/__init__.pyi +0 -0
  75. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/plugin_packaging.py +0 -0
  76. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/mq_bridge/py.typed +0 -0
  77. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/package-lock.json +0 -0
  78. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/pyproject.toml +0 -0
  79. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/Cargo.toml +0 -0
  80. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/LICENSE.python +0 -0
  81. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/README.md +0 -0
  82. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  83. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/example.py +0 -0
  84. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  85. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  86. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/consume_pull.py +0 -0
  87. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/dlt_source.py +0 -0
  88. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/json_route.py +0 -0
  89. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/memory.yaml +0 -0
  90. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/examples/raw_route.py +0 -0
  91. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/pyproject-basic.toml +0 -0
  92. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/pyproject-reduced.toml +0 -0
  93. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/src/lib.rs +0 -0
  94. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_config_types.py +0 -0
  95. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
  96. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_logging.py +0 -0
  97. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_packaging.py +0 -0
  98. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  99. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
  100. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_public_api.py +0 -0
  101. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/tests/test_routes.py +0 -0
  102. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/python/mq-bridge-py/uv.lock +0 -0
  103. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/benches/metadata_bench.rs +0 -0
  104. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  105. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  106. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/http/http_flamegraph.py +0 -0
  107. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  108. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/analysis/http/run_http_ladder.sh +0 -0
  109. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/ci/format_bench_output.sh +0 -0
  110. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/httparena/README.md +0 -0
  111. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
  112. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  113. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  114. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  115. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  116. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  117. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  118. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/README.md +0 -0
  119. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/postgres.yml +0 -0
  120. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/seed.sql +0 -0
  121. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/techempower/verify.sh +0 -0
  122. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/the-benchmarker/README.md +0 -0
  123. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  124. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  125. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  126. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/canonical_message.rs +0 -0
  127. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/checkpoint.rs +0 -0
  128. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/command_handler.rs +0 -0
  129. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/amqp.rs +0 -0
  130. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/aws.rs +0 -0
  131. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/clickhouse.rs +0 -0
  132. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/grpc.proto +0 -0
  133. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/grpc.rs +0 -0
  134. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/http/mod.rs +0 -0
  135. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/http/stream.rs +0 -0
  136. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/ibm_mq.rs +0 -0
  137. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/kafka.rs +0 -0
  138. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/endpoint.rs +0 -0
  139. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/framed.rs +0 -0
  140. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/ipc_unix.rs +0 -0
  141. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/ipc_windows.rs +0 -0
  142. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/memory_transport.rs +0 -0
  143. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/mod.rs +0 -0
  144. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/memory/transport.rs +0 -0
  145. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/dedup.rs +0 -0
  146. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/mod.rs +0 -0
  147. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/publisher.rs +0 -0
  148. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/readers.rs +0 -0
  149. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mongodb/tests.rs +0 -0
  150. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/mqtt.rs +0 -0
  151. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/nats.rs +0 -0
  152. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/poll.rs +0 -0
  153. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/VENDORED.md +0 -0
  154. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/mod.rs +0 -0
  155. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
  156. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
  157. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
  158. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
  159. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/pgoutput/values.rs +0 -0
  160. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/replication.rs +0 -0
  161. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/postgres/state.rs +0 -0
  162. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/redis_streams.rs +0 -0
  163. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/sled.rs +0 -0
  164. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/sqlx/dedup.rs +0 -0
  165. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/sqlx/mod.rs +0 -0
  166. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/sqlx/tests.rs +0 -0
  167. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/mod.rs +0 -0
  168. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/null.rs +0 -0
  169. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/reader.rs +0 -0
  170. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/response.rs +0 -0
  171. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/static_endpoint.rs +0 -0
  172. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/structural/stream_buffer.rs +0 -0
  173. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/websocket.rs +0 -0
  174. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/zeromq/codec.rs +0 -0
  175. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/zeromq/mod.rs +0 -0
  176. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/zeromq/omq.rs +0 -0
  177. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/endpoints/zeromq/zmq.rs +0 -0
  178. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/errors.rs +0 -0
  179. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/event_handler.rs +0 -0
  180. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/event_store.rs +0 -0
  181. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/extensions.rs +0 -0
  182. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/lib.rs +0 -0
  183. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/buffer.rs +0 -0
  184. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/compression.rs +0 -0
  185. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/cookie_jar.rs +0 -0
  186. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/delay.rs +0 -0
  187. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/dlq.rs +0 -0
  188. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/encryption.rs +0 -0
  189. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/id.rs +0 -0
  190. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/limiter.rs +0 -0
  191. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/metrics.rs +0 -0
  192. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/random_panic.rs +0 -0
  193. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/retry.rs +0 -0
  194. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/coerce.rs +0 -0
  195. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/mod.rs +0 -0
  196. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/transform/path.rs +0 -0
  197. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/middleware/weak_join.rs +0 -0
  198. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/models/secrets.rs +0 -0
  199. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/outcomes.rs +0 -0
  200. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/conformance.rs +0 -0
  201. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/endpoint.rs +0 -0
  202. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/message.rs +0 -0
  203. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/middleware.rs +0 -0
  204. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/mod.rs +0 -0
  205. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/sdk.rs +0 -0
  206. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/plugin/test_support.rs +0 -0
  207. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/publisher.rs +0 -0
  208. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/response.rs +0 -0
  209. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/base64_engine.rs +0 -0
  210. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/compression.rs +0 -0
  211. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/connection_registry.rs +0 -0
  212. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/crypto.rs +0 -0
  213. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/crypto_envelope.rs +0 -0
  214. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/interpolation.rs +0 -0
  215. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/mod.rs +0 -0
  216. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/support/plugin_abi.rs +0 -0
  217. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/test_utils.rs +0 -0
  218. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/traits.rs +0 -0
  219. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/src/type_handler.rs +0 -0
  220. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/README.md +0 -0
  221. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/armature_integration.rs +0 -0
  222. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/amqp.rs +0 -0
  223. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/aws.rs +0 -0
  224. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/clickhouse.rs +0 -0
  225. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/config.toml +0 -0
  226. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/amqp.yml +0 -0
  227. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/aws.yml +0 -0
  228. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/clickhouse.yml +0 -0
  229. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  230. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  231. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  232. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  233. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  234. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  235. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  236. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  237. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/kafka.yml +0 -0
  238. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mariadb.yml +0 -0
  239. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  240. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  241. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mongodb.yml +0 -0
  242. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mosquitto.conf +0 -0
  243. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  244. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  245. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  246. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  247. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mqtt.yml +0 -0
  248. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  249. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/mysql.yml +0 -0
  250. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/nats.yml +0 -0
  251. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/object_store.yml +0 -0
  252. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/postgres.yml +0 -0
  253. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
  254. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/docker-compose/redis.yml +0 -0
  255. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/file.rs +0 -0
  256. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/grpc.rs +0 -0
  257. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/grpc_tls.rs +0 -0
  258. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/http.rs +0 -0
  259. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/http_tls.rs +0 -0
  260. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/ibm_mq.rs +0 -0
  261. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/ibm_mq_tls.rs +0 -0
  262. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/ipc.rs +0 -0
  263. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/kafka.rs +0 -0
  264. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/kafka_tls.rs +0 -0
  265. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/logic_test.rs +0 -0
  266. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mariadb.rs +0 -0
  267. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/memory.rs +0 -0
  268. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mod.rs +0 -0
  269. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mongodb.rs +0 -0
  270. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mongodb_raw.rs +0 -0
  271. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mongodb_tls.rs +0 -0
  272. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mqtt.rs +0 -0
  273. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/mysql.rs +0 -0
  274. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/nats.rs +0 -0
  275. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/object_store.rs +0 -0
  276. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/performance_static.rs +0 -0
  277. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/postgres.rs +0 -0
  278. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/postgres_cdc.rs +0 -0
  279. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/redis_streams.rs +0 -0
  280. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/route.rs +0 -0
  281. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/scripts/gen_certs.sh +0 -0
  282. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/sqlite.rs +0 -0
  283. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/tls_helpers.rs +0 -0
  284. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/websocket.rs +0 -0
  285. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration/zeromq.rs +0 -0
  286. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/integration_test.rs +0 -0
  287. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/memory_leak_test.rs +0 -0
  288. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/ref_test.rs +0 -0
  289. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/reference_docs_test.rs +0 -0
  290. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/sqlite_test.rs +0 -0
  291. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/tls_example.rs +0 -0
  292. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/unit_tests.md +0 -0
  293. {mq_bridge_py_basic-0.4.4 → mq_bridge_py_basic-0.4.6}/tests/websocket_test.rs +0 -0
@@ -1,10 +1,20 @@
1
1
  name: CI
2
2
 
3
3
  on:
4
- push:
5
- branches: [main]
6
4
  pull_request:
7
5
  branches: [main, dev]
6
+ workflow_dispatch:
7
+
8
+ # Only the tip of a PR branch is worth testing; superseded runs are cancelled so
9
+ # they stop holding runner slots the integration jobs are waiting for.
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ # Nothing in CI writes back to the repository; artifacts move through the Actions
15
+ # runtime token, not this one.
16
+ permissions:
17
+ contents: read
8
18
 
9
19
  env:
10
20
  CARGO_TERM_COLOR: always
@@ -25,11 +35,6 @@ jobs:
25
35
 
26
36
  - name: Cache cargo build
27
37
  uses: Swatinem/rust-cache@v2
28
- with:
29
- # Differentiates the matrix `check` job per feature set; evaluates to an
30
- # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
31
- # job id, OS, rustc version, and lockfiles automatically.
32
- key: ${{ matrix.features }}
33
38
 
34
39
  - name: Check formatting
35
40
  run: cargo fmt --all -- --check
@@ -37,44 +42,37 @@ jobs:
37
42
  - name: Run clippy
38
43
  run: cargo clippy --all-targets --all-features -- -D warnings
39
44
 
40
- # Build with all features
45
+ # Every feature subset still gets its own `cargo check`, but sequentially in one
46
+ # job: the matrix cost 8 runner slots at the moment integration-build's dependents
47
+ # were starving, and none of this is on the critical path.
41
48
  build:
42
- name: Build
49
+ name: Build (feature subsets)
43
50
  runs-on: ubuntu-latest
44
- strategy:
45
- matrix:
46
- features:
47
- - ""
48
- - "full"
49
- - "kafka"
50
- # "amqp" # no recent changes, already included in full
51
- - "nats"
52
- - "grpc"
53
- - "mqtt"
54
- - "mongodb"
55
- - "http"
56
- # - "aws" # needs too long, already included in full
57
- # - "zeromq" # no recent changes, already included in full
58
51
  steps:
59
52
  - uses: actions/checkout@v4
60
-
53
+
61
54
  - name: Install Rust toolchain
62
55
  uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
63
-
56
+
64
57
  - name: Cache cargo build
65
58
  uses: Swatinem/rust-cache@v2
66
- with:
67
- # Differentiates the matrix `check` job per feature set; evaluates to an
68
- # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
69
- # job id, OS, rustc version, and lockfiles automatically.
70
- key: ${{ matrix.features }}
71
-
72
- - name: Check
59
+
60
+ # amqp/aws/zeromq are omitted: unchanged for a while and covered by `full`.
61
+ - name: Check each feature subset
73
62
  run: |
74
- if [ -z "${{ matrix.features }}" ]; then
75
- cargo check --all-targets
76
- else
77
- cargo check --all-targets --features "${{ matrix.features }}"
63
+ failed=""
64
+ for f in "" full kafka nats grpc mqtt mongodb http; do
65
+ echo "::group::cargo check --features ${f:-<default>}"
66
+ if [ -z "$f" ]; then
67
+ cargo check --all-targets || failed="$failed <default>"
68
+ else
69
+ cargo check --all-targets --features "$f" || failed="$failed $f"
70
+ fi
71
+ echo "::endgroup::"
72
+ done
73
+ if [ -n "$failed" ]; then
74
+ echo "::error::feature subsets failed:$failed"
75
+ exit 1
78
76
  fi
79
77
 
80
78
  # Unit tests
@@ -89,11 +87,6 @@ jobs:
89
87
 
90
88
  - name: Cache cargo build
91
89
  uses: Swatinem/rust-cache@v2
92
- with:
93
- # Differentiates the matrix `check` job per feature set; evaluates to an
94
- # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
95
- # job id, OS, rustc version, and lockfiles automatically.
96
- key: ${{ matrix.features }}
97
90
 
98
91
  - name: Run unit tests
99
92
  run: cargo test --lib --features=full
@@ -145,12 +138,32 @@ jobs:
145
138
  path: nextest-archive.tar.zst
146
139
  retention-days: 1
147
140
 
148
- # Integration tests (requires Docker) split into parallel jobs. Each runs the
149
- # prebuilt nextest archive from integration-build no recompilation.
150
- integration-others:
151
- name: Integration Others
141
+ # Integration tests (requires Docker), split across runners by measured runtime
142
+ # so no single job dominates the critical path. Each runs the prebuilt nextest
143
+ # archive from integration-build — no recompilation. `--no-capture` implies
144
+ # `--test-threads=1`, and tests tear their compose stacks down with `down -v`,
145
+ # so parallelism has to come from separate runners rather than from nextest.
146
+ integration:
147
+ name: Integration — ${{ matrix.name }}
152
148
  runs-on: ubuntu-latest
153
149
  needs: integration-build
150
+ timeout-minutes: 30
151
+ strategy:
152
+ fail-fast: false
153
+ matrix:
154
+ include:
155
+ - name: Status
156
+ filter: 'binary(integration_test) & test(=test_all_status)'
157
+ - name: Chaos
158
+ filter: 'binary(integration_test) & test(=test_all_chaos)'
159
+ - name: Logic
160
+ filter: 'binary(integration_test) & (test(=test_all_request_reply) | test(=test_all_subscriber_logic))'
161
+ - name: Endpoints
162
+ filter: 'binary(integration_test) & not test(=test_all_status) & not test(=test_all_chaos) & not test(=test_all_request_reply) & not test(=test_all_subscriber_logic) & not test(=test_all_performance_pipeline) & not test(=test_all_performance_direct)'
163
+ - name: Performance Pipeline
164
+ filter: 'binary(integration_test) & test(=test_all_performance_pipeline)'
165
+ - name: Performance Direct
166
+ filter: 'binary(integration_test) & test(=test_all_performance_direct)'
154
167
  services:
155
168
  docker:
156
169
  image: docker:dind
@@ -171,58 +184,17 @@ jobs:
171
184
  - name: Pre-pull docker images
172
185
  run: |
173
186
  find tests/integration/docker-compose -name "*.yml" | xargs -P 5 -I {} docker compose -f {} pull -q
174
- - name: Install JRE (for keytool)
175
- run: |
176
- sudo apt-get update
177
- sudo apt-get install -y default-jre-headless
178
-
179
- - name: Generate TLS certs for integration services
180
- run: |
181
- chmod +x tests/integration/scripts/gen_certs.sh
182
- ./tests/integration/scripts/gen_certs.sh mongodb
183
- ./tests/integration/scripts/gen_certs.sh kafka
184
- ./tests/integration/scripts/gen_certs.sh ibm-mq
185
-
186
- - name: Run chaos/stability tests
187
- run: |
188
- cargo nextest run --archive-file nextest-archive.tar.zst \
189
- --run-ignored all --no-capture \
190
- -E 'binary(integration_test) & test(=test_all_chaos)'
191
-
192
- - name: Run remaining integration tests (excluding chaos & performance)
193
- run: |
194
- cargo nextest run --archive-file nextest-archive.tar.zst \
195
- --run-ignored all --no-capture \
196
- -E 'binary(integration_test) & not test(=test_all_chaos) & not test(=test_all_performance_pipeline) & not test(=test_all_performance_direct)'
197
-
198
- integration-performance:
199
- name: Integration — Performance
200
- runs-on: ubuntu-latest
201
- needs: integration-build
202
- services:
203
- docker:
204
- image: docker:dind
205
- options: --privileged
206
- steps:
207
- - uses: actions/checkout@v4
208
-
209
- - name: Install cargo-nextest
210
- uses: taiki-e/install-action@v2
211
- with:
212
- tool: nextest
213
187
 
214
- - name: Download nextest archive
215
- uses: actions/download-artifact@v4
216
- with:
217
- name: integration-nextest-archive
218
-
219
- - name: Pre-pull docker images
220
- run: |
221
- find tests/integration/docker-compose -name "*.yml" | xargs -P 5 -I {} docker compose -f {} pull -q
222
188
  - name: Install JRE (for keytool)
189
+ timeout-minutes: 5
223
190
  run: |
224
- sudo apt-get update
225
- sudo apt-get install -y default-jre-headless
191
+ # Runner images ship a JDK; only pay the 46 MB download if they didn't.
192
+ # A degraded apt mirror used to stall this step for hours.
193
+ if command -v keytool >/dev/null 2>&1; then exit 0; fi
194
+ sudo apt-get update -qq
195
+ sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y \
196
+ -o Acquire::Retries=3 -o Acquire::http::Timeout=20 \
197
+ default-jre-headless
226
198
 
227
199
  - name: Generate TLS certs for integration services
228
200
  run: |
@@ -231,26 +203,18 @@ jobs:
231
203
  ./tests/integration/scripts/gen_certs.sh kafka
232
204
  ./tests/integration/scripts/gen_certs.sh ibm-mq
233
205
 
234
- - name: Run pipeline performance tests
235
- run: |
236
- cargo nextest run --archive-file nextest-archive.tar.zst \
237
- --run-ignored all --no-capture \
238
- -E 'binary(integration_test) & test(=test_all_performance_pipeline)'
239
-
240
- - name: Run other performance tests
206
+ - name: Run ${{ matrix.name }} integration tests
241
207
  run: |
242
208
  cargo nextest run --archive-file nextest-archive.tar.zst \
243
209
  --run-ignored all --no-capture \
244
- -E 'binary(integration_test) & test(=test_all_performance_direct)'
210
+ -E '${{ matrix.filter }}'
245
211
 
212
+ # Armature clones an external repo and runs its test suite: no docker stacks, no
213
+ # TLS certs, no keytool. It used to pay ~1.3m of setup for 1.7m of tests.
246
214
  integration-armature:
247
215
  name: Integration — Armature
248
216
  runs-on: ubuntu-latest
249
217
  needs: integration-build
250
- services:
251
- docker:
252
- image: docker:dind
253
- options: --privileged
254
218
  steps:
255
219
  - uses: actions/checkout@v4
256
220
 
@@ -264,21 +228,6 @@ jobs:
264
228
  with:
265
229
  name: integration-nextest-archive
266
230
 
267
- - name: Pre-pull docker images
268
- run: |
269
- find tests/integration/docker-compose -name "*.yml" | xargs -P 5 -I {} docker compose -f {} pull -q
270
- - name: Install JRE (for keytool)
271
- run: |
272
- sudo apt-get update
273
- sudo apt-get install -y default-jre-headless
274
-
275
- - name: Generate TLS certs for integration services
276
- run: |
277
- chmod +x tests/integration/scripts/gen_certs.sh
278
- ./tests/integration/scripts/gen_certs.sh mongodb
279
- ./tests/integration/scripts/gen_certs.sh kafka
280
- ./tests/integration/scripts/gen_certs.sh ibm-mq
281
-
282
231
  - name: Run armature integration tests
283
232
  run: |
284
233
  cargo nextest run --archive-file nextest-archive.tar.zst \
@@ -297,11 +246,6 @@ jobs:
297
246
 
298
247
  - name: Cache cargo build
299
248
  uses: Swatinem/rust-cache@v2
300
- with:
301
- # Differentiates the matrix `check` job per feature set; evaluates to an
302
- # empty string (no-op) in non-matrix jobs. rust-cache already keys on the
303
- # job id, OS, rustc version, and lockfiles automatically.
304
- key: ${{ matrix.features }}
305
249
 
306
250
  - name: Build documentation (deny warnings)
307
251
  run: RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps
@@ -21,6 +21,12 @@ on:
21
21
  - '.github/workflows/ibm-mq.yml'
22
22
  workflow_dispatch:
23
23
 
24
+ # Superseded PR runs are cancelled; push runs always finish so every pre-merge
25
+ # commit keeps its own verdict.
26
+ concurrency:
27
+ group: ${{ github.workflow }}-${{ github.ref }}
28
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
29
+
24
30
  env:
25
31
  CARGO_TERM_COLOR: always
26
32
  RUST_BACKTRACE: 1
@@ -144,9 +150,13 @@ jobs:
144
150
 
145
151
  - name: Install JDK (for keytool - TLS tests)
146
152
  if: steps.mqclient.outputs.available == 'true'
153
+ timeout-minutes: 5
147
154
  run: |
148
- sudo apt-get update
149
- sudo apt-get install -y default-jdk
155
+ if command -v keytool >/dev/null 2>&1; then exit 0; fi
156
+ sudo apt-get update -qq
157
+ sudo env DEBIAN_FRONTEND=noninteractive apt-get install -y \
158
+ -o Acquire::Retries=3 -o Acquire::http::Timeout=20 \
159
+ default-jdk
150
160
 
151
161
  - name: Generate TLS certificates
152
162
  if: steps.mqclient.outputs.available == 'true'
@@ -19,6 +19,12 @@ on:
19
19
  - "src/**"
20
20
  workflow_dispatch:
21
21
 
22
+ # Superseded PR runs are cancelled; push runs always finish so every pre-merge
23
+ # commit keeps its own verdict.
24
+ concurrency:
25
+ group: ${{ github.workflow }}-${{ github.ref }}
26
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
27
+
22
28
  env:
23
29
  CARGO_TERM_COLOR: always
24
30
 
@@ -19,6 +19,12 @@ on:
19
19
  - "src/**"
20
20
  workflow_dispatch:
21
21
 
22
+ # Superseded PR runs are cancelled; push runs always finish so every pre-merge
23
+ # commit keeps its own verdict.
24
+ concurrency:
25
+ group: ${{ github.workflow }}-${{ github.ref }}
26
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
27
+
22
28
  env:
23
29
  CARGO_TERM_COLOR: always
24
30
 
@@ -6,6 +6,12 @@ on:
6
6
  pull_request:
7
7
  branches: [main, dev]
8
8
 
9
+ # Superseded PR runs are cancelled; push runs always finish so every pre-merge
10
+ # commit keeps its own verdict.
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
14
+
9
15
  env:
10
16
  CARGO_TERM_COLOR: always
11
17
 
@@ -2,6 +2,93 @@
2
2
 
3
3
  All notable changes to `mq-bridge`. Newest first.
4
4
 
5
+ ## 0.4.4
6
+
7
+ ### Breaking
8
+
9
+ - **`idempotency` on the `file` and `object_store` sinks is replaced by `name_by`.** The old
10
+ field described a consequence rather than the thing it set. What it actually chooses is how
11
+ written objects and parts are *named*, and everything else — sortability, replay dedup,
12
+ whether `date_partition` applies, how errors are reported — follows from that name:
13
+
14
+ | `name_by` | Name | Consequence |
15
+ | --- | --- | --- |
16
+ | `write_time` | `<uuidv7>.<ext>`, optionally under `YYYY/MM/DD/` | unique per write, sorts by write order |
17
+ | `source_position` | `part-<topic>-<partition>-<start>-<end>.<ext>`, zero-padded, flat | repeats exactly on a replay, sorts by source order |
18
+ | `auto` (new default) | `source_position` where the input carries a replay position, else `write_time` | see below |
19
+
20
+ `idempotency: true|false` is still read and still means
21
+ `name_by: source_position|write_time`, so v0.4.x configs keep loading. An explicit `name_by`
22
+ wins over it.
23
+
24
+ - **An `object_store` sink now defaults to `source_position` naming over a replayable input**
25
+ (Kafka, Postgres CDC, a SQL cursor, a MongoDB change stream, or a file). Key order is the
26
+ only order a bucket has, so this is what makes `mqb copy orders.csv s3://…` come back in
27
+ source order at any `concurrency` without configuring anything — and it is what removed the
28
+ `concurrency > 1` warning from that route. Three consequences to know about:
29
+ - **A re-run into the same prefix writes nothing — where the source repeats its
30
+ positions.** The names repeat, and a repeat is a no-op. That covers a re-read of the same
31
+ file, Kafka offsets, a SQL cursor and a CDC stream. A file source in `subscribe` or
32
+ `group_subscribe` mode is the exception: it stamps a per-run epoch, so its names stay
33
+ distinct across runs and a re-run writes a second copy. Where the no-op does apply it is a
34
+ change of behaviour — the same command used to append a second copy under fresh uuid
35
+ names. Use a fresh prefix, or `name_by: write_time`, if you want the old behaviour. The
36
+ no-op also needs the prefix listing to succeed: a replay whose batches fall on different
37
+ boundaries names different objects, so where the listing is denied the sink can only catch
38
+ a repeat that lands on the exact same name and the rest is written twice.
39
+ - **`date_partition` does not apply** under `source_position`; parts are written flat.
40
+ - **Do not mix the two families in one prefix.** uuid names and `part-…` names do not sort
41
+ correctly against each other. A prefix written by an older version keeps working on its
42
+ own; point the upgraded route at a new prefix if a reader depends on listing order.
43
+
44
+ - **The `file` sink stays on `write_time` under `auto`** and must be told
45
+ `name_by: source_position` explicitly. There, positional naming turns `path` from a file
46
+ into a *directory* of part files — a change of structure, not of name, and not something to
47
+ derive on the operator's behalf.
48
+
49
+ - `object_store` `date_partition` is now `Option<bool>` (unset = on, and only for
50
+ `write_time`). Side effect: the "`date_partition` is a publisher-only option" warning used
51
+ to fire for *every* `object_store` consumer, because the field defaulted to `true` and the
52
+ check could not tell that from an explicit setting. It now fires only when the field was
53
+ actually set.
54
+
55
+ ### Changed
56
+
57
+ - **The `object_store` sink lists its prefix only on the `source_position` write path**, and
58
+ only once per publisher, immediately before its first write rather than when it opens. A
59
+ `write_time` sink never lists at all; a `source_position` restart into a populated prefix
60
+ pays for exactly one `LIST` and then skips the rest of the replay without re-encoding or
61
+ re-uploading. The listing cannot be deferred any further than this: `PutMode::Create` only
62
+ catches a repeat that lands on the same object name, so a replay whose batches fall on
63
+ different boundaries collides with nothing and would otherwise write every record a second
64
+ time under overlapping names. A listing that fails is retried on the next batch, unless it
65
+ failed for a reason retrying cannot clear (a denied `ListObjects`), in which case the sink
66
+ warns once and falls back to same-name-only deduplication.
67
+ - **The `concurrency > 1` warning now fires only for a `write_time` name**, which is the only
68
+ case where write order is not source order — under `auto` over a replayable input that is
69
+ now nobody. It names `name_by: source_position` where the input carries a replay position
70
+ and `concurrency: 1` otherwise, rather than pointing at a setting that would fail on an
71
+ input with no position.
72
+ - The `source_position` write path reports `SentBatch::Partial` like the ordinary path does.
73
+ A record that cannot be encoded splits the run instead of failing the whole batch: the
74
+ offsets around it are written under names covering exactly what went in, and the bad record
75
+ goes to the DLQ. (Encode failures are unreachable in practice today; this removes an
76
+ asymmetry rather than fixing an observed bug.)
77
+
78
+ ### Fixed
79
+
80
+ - A failed prefix listing no longer fails an `object_store` batch. The error was propagated as
81
+ non-retryable, which dropped a replay's batch on a bucket that denies `ListObjects`, or on a
82
+ transient listing hiccup. It is now logged and the sink degrades to same-name-only
83
+ deduplication: a transient failure is retried on the next batch, while a denied `ListObjects`
84
+ is latched after one warning and not retried.
85
+
86
+ - A route rejected for `name_by: source_position` over an input that carries no replay position
87
+ no longer leaves a directory behind at a `file` sink's `path`. The publisher opens before the
88
+ consumer, and the part-file sink creates its directory as it opens, so the rejected route used
89
+ to turn the operator's output *file* into an empty directory — after which a corrected run
90
+ failed on the leftover. The requirement is now checked before any sink opens.
91
+
5
92
  ## 0.4.0
6
93
 
7
94
  ### Breaking
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Looking for what middleware or structural endpoints exist, and how to configure them?**
4
4
  > [REFERENCE.md](docs/REFERENCE.md) is the complete, authoritative list — every middleware
5
- > (`retry`, `dlq`, `transform`, `id`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
5
+ > (`retry`, `dlq`, `transform`, `id`, `filter`, `deduplication`, `weak_join`, `buffer`, `limiter`, `delay`,
6
6
  > `cookie_jar`, `encryption`, `compression`, `metrics`, `random_panic`, `custom`) and every structural endpoint (`ref`,
7
7
  > `fanout`, `switch`, `request`, `response`, `reader`, `static`, `stream_buffer`, `null`,
8
8
  > `custom`), each with its fields, defaults, and a working YAML example. Do not infer these
@@ -77,8 +77,10 @@ src/
77
77
  │ ├── cookie_jar.rs # Cookie / metadata persistence across requests
78
78
  │ ├── deduplication.rs # Message deduplication (sled)
79
79
  │ ├── delay.rs # Artificial delay
80
+ │ ├── deferred_commit.rs # Hold commits for batches a middleware emptied
80
81
  │ ├── dlq.rs # Dead-letter queue
81
82
  │ ├── encryption.rs # AEAD payload encryption
83
+ │ ├── filter.rs # Expression predicate: keep only matching messages
82
84
  │ ├── id.rs # Replay-stable business identity into `mqb.id`
83
85
  │ ├── limiter.rs # Throughput limiting (msg/s)
84
86
  │ ├── metrics.rs # Metrics collection