DefStream-RabbitMQ 0.1.25__tar.gz → 0.1.27__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 (450) hide show
  1. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/PKG-INFO +2 -2
  2. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/build/RabbitMQ/DefStream_RabbitMQ.egg-info/SOURCES.txt +30 -0
  3. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/README.en.md +1 -1
  4. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/README.md +1 -1
  5. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/RabbitMQ.en.md +125 -0
  6. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/RabbitMQ.md +116 -0
  7. defstream_rabbitmq-0.1.27/issues/feature/62/CHANGELOG.md +26 -0
  8. defstream_rabbitmq-0.1.27/issues/feature/62/IMPLEMENTS.md +26 -0
  9. defstream_rabbitmq-0.1.27/issues/feature/62/PLAN.md +175 -0
  10. defstream_rabbitmq-0.1.27/issues/feature/62/README.md +69 -0
  11. defstream_rabbitmq-0.1.27/issues/feature/62/REQUIREMENTS.md +122 -0
  12. defstream_rabbitmq-0.1.27/issues/feature/62/TASKS.md +35 -0
  13. defstream_rabbitmq-0.1.27/issues/feature/62/implements/1793777682327.md +8 -0
  14. defstream_rabbitmq-0.1.27/issues/feature/62/implements/1793778339166.md +7 -0
  15. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793772101827.md +17 -0
  16. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793774701691.md +13 -0
  17. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793775544541.md +13 -0
  18. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793775771772.md +13 -0
  19. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793777337621.md +15 -0
  20. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793777847993.md +11 -0
  21. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793778003070.md +21 -0
  22. defstream_rabbitmq-0.1.27/issues/feature/62/tasks/1793778440735.md +9 -0
  23. defstream_rabbitmq-0.1.27/issues/fix/64/CHANGELOG.md +3 -0
  24. defstream_rabbitmq-0.1.27/issues/fix/64/IMPLEMENTS.md +20 -0
  25. defstream_rabbitmq-0.1.27/issues/fix/64/PLAN.md +69 -0
  26. defstream_rabbitmq-0.1.27/issues/fix/64/README.md +45 -0
  27. defstream_rabbitmq-0.1.27/issues/fix/64/REQUIREMENTS.md +63 -0
  28. defstream_rabbitmq-0.1.27/issues/fix/64/TASKS.md +21 -0
  29. defstream_rabbitmq-0.1.27/issues/fix/64/implements/1793807653096.md +10 -0
  30. defstream_rabbitmq-0.1.27/issues/fix/64/implements/1793807663436.md +9 -0
  31. defstream_rabbitmq-0.1.27/issues/fix/64/tasks/1793806949650.md +8 -0
  32. defstream_rabbitmq-0.1.27/issues/fix/64/tasks/1793807182094.md +7 -0
  33. defstream_rabbitmq-0.1.27/issues/fix/64/tasks/1793807663435.md +13 -0
  34. defstream_rabbitmq-0.1.27/issues/fix/64/tasks/1793807722809.md +31 -0
  35. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/RabbitMQ/Sample.Stream.py +7 -11
  36. defstream_rabbitmq-0.1.27/samples/Broker/RabbitMQ/Sample.Timer.py +90 -0
  37. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Connection.py +35 -0
  38. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Connection.py +37 -0
  39. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Consumer.py +5 -1
  40. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/__init__.py +2 -0
  41. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/__init__.py +6 -0
  42. defstream_rabbitmq-0.1.27/tests/rabbitmq/test_rabbitmq_timers.py +288 -0
  43. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_protocol_contracts.py +113 -2
  44. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.dev/scripts/editable_view.py +0 -0
  45. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.dev/scripts/tests/__init__.py +0 -0
  46. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.dev/scripts/tests/test_editable_view.py +0 -0
  47. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.distribution-target +0 -0
  48. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/ISSUE_TEMPLATE/01.feature.yml +0 -0
  49. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/ISSUE_TEMPLATE/02.bug.yml +0 -0
  50. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/ISSUE_TEMPLATE/03.fix.yml +0 -0
  51. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/ISSUE_TEMPLATE/04.task.yml +0 -0
  52. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  53. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  54. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/build_backend.py +0 -0
  55. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/build_distributions.py +0 -0
  56. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/check_distributions.py +0 -0
  57. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/create-issues-from-reviews.mjs +0 -0
  58. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/create-pr-from-issue.mjs +0 -0
  59. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/prepare_upload.py +0 -0
  60. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/run_core_tests.py +0 -0
  61. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/__init__.py +0 -0
  62. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/create-issues-from-reviews.test.mjs +0 -0
  63. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/create-pr-from-issue.test.mjs +0 -0
  64. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/test_build_backend.py +0 -0
  65. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/test_distributions.py +0 -0
  66. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/scripts/tests/test_release.py +0 -0
  67. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/workflows/ci.yml +0 -0
  68. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/workflows/create-issues-from-reviews.yml +0 -0
  69. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.github/workflows/create-pr-from-issue.yml +0 -0
  70. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/.gitignore +0 -0
  71. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/LICENSE +0 -0
  72. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/README.en.md +0 -0
  73. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/README.md +0 -0
  74. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/README.setup.md +0 -0
  75. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Contracts.en.md +0 -0
  76. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Contracts.md +0 -0
  77. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/GettingStarted.en.md +0 -0
  78. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/GettingStarted.md +0 -0
  79. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/LifecycleHooks.en.md +0 -0
  80. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/LifecycleHooks.md +0 -0
  81. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Operations.en.md +0 -0
  82. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Operations.md +0 -0
  83. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Packaging.en.md +0 -0
  84. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Packaging.md +0 -0
  85. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Redis.en.md +0 -0
  86. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Redis.md +0 -0
  87. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Tasks.en.md +0 -0
  88. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/docs/Tasks.md +0 -0
  89. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/instructions/CODE.instructions.md +0 -0
  90. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/instructions/DOCS.instructions.md +0 -0
  91. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/instructions/README.instructions.md +0 -0
  92. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/bug/16/IMPLEMENTS.md +0 -0
  93. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/bug/16/ISSUE.md +0 -0
  94. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/bug/16/README.md +0 -0
  95. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/bug/16/REQUIREMENTS.md +0 -0
  96. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/1/IMPLEMENTS.md +0 -0
  97. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/1/README.md +0 -0
  98. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/1/REQUIREMENTS.md +0 -0
  99. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/1/TASK.md +0 -0
  100. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/1/ci.refs.json +0 -0
  101. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/CHANGELOG.md +0 -0
  102. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/IMPLEMENTS.md +0 -0
  103. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/PLAN.md +0 -0
  104. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/README.md +0 -0
  105. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/REQUIREMENTS.md +0 -0
  106. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/TASKS.md +0 -0
  107. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793274693488.md +0 -0
  108. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793275218996.md +0 -0
  109. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793275899489.md +0 -0
  110. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793276075771.md +0 -0
  111. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793276518340.md +0 -0
  112. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793277364116.md +0 -0
  113. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793278267422.md +0 -0
  114. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793278764701.md +0 -0
  115. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/implements/1793279849390.md +0 -0
  116. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793272872217.md +0 -0
  117. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793274121654.md +0 -0
  118. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793274231988.md +0 -0
  119. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793275218995.md +0 -0
  120. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793275501812.md +0 -0
  121. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793275955973.md +0 -0
  122. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793276099601.md +0 -0
  123. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793276518341.md +0 -0
  124. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793277424063.md +0 -0
  125. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793278267423.md +0 -0
  126. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793278764702.md +0 -0
  127. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/46/tasks/1793279849391.md +0 -0
  128. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/CHANGELOG.md +0 -0
  129. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/IMPLEMENTS.md +0 -0
  130. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/PLAN.md +0 -0
  131. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/README.md +0 -0
  132. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/REQUIREMENTS.md +0 -0
  133. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/TASKS.md +0 -0
  134. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/implements/1793271568985.md +0 -0
  135. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/implements/1793272077065.md +0 -0
  136. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/tasks/1793271236067.md +0 -0
  137. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/tasks/1793271384432.md +0 -0
  138. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/tasks/1793271506089.md +0 -0
  139. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/tasks/1793271819682.md +0 -0
  140. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/47/tasks/1793272077066.md +0 -0
  141. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/CHANGELOG.md +0 -0
  142. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/IMPLEMENTS.md +0 -0
  143. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/PLAN.md +0 -0
  144. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/README.md +0 -0
  145. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/REQUIREMENTS.md +0 -0
  146. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/TASKS.md +0 -0
  147. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/implements/1793714914193.md +0 -0
  148. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/implements/1793717149425.md +0 -0
  149. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/tasks/1793705387888.md +0 -0
  150. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/tasks/1793714914194.md +0 -0
  151. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/tasks/1793715537355.md +0 -0
  152. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/55/tasks/1793717149426.md +0 -0
  153. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/8/IMPLEMENTS.md +0 -0
  154. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/8/README.md +0 -0
  155. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/8/REQUIREMENTS.md +0 -0
  156. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/feature/8/ci.refs.json +0 -0
  157. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/10/IMPLEMENTS.md +0 -0
  158. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/10/README.md +0 -0
  159. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/10/REQUIREMENTS.md +0 -0
  160. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/13/README.md +0 -0
  161. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/21/IMPLEMENTS.md +0 -0
  162. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/21/ISSUE.md +0 -0
  163. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/21/README.md +0 -0
  164. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/21/REQUIREMENTS.md +0 -0
  165. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/24/IMPLEMENTS.md +0 -0
  166. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/24/ISSUE.md +0 -0
  167. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/24/README.md +0 -0
  168. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/24/REQUIREMENTS.md +0 -0
  169. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/25/IMPLEMENTS.md +0 -0
  170. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/25/ISSUE.md +0 -0
  171. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/25/README.md +0 -0
  172. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/25/REQUIREMENTS.md +0 -0
  173. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/25/TASK.md +0 -0
  174. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/26/IMPLEMENTS.md +0 -0
  175. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/26/ISSUE.md +0 -0
  176. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/26/README.md +0 -0
  177. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/26/REQUIREMENTS.md +0 -0
  178. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/29/ISSUE.md +0 -0
  179. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/29/README.md +0 -0
  180. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/29/REQUIREMENTS.md +0 -0
  181. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/29/TASK.md +0 -0
  182. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/3/IMPLEMENTS.md +0 -0
  183. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/3/README.md +0 -0
  184. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/3/REQUIREMENTS.md +0 -0
  185. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/3/ci.refs.json +0 -0
  186. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/CHANGELOG.md +0 -0
  187. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/IMPLEMENTS.md +0 -0
  188. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/PLAN.md +0 -0
  189. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/README.md +0 -0
  190. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/REQUIREMENTS.md +0 -0
  191. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/TASKS.md +0 -0
  192. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/implements/1793257519898.md +0 -0
  193. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/implements/1793257826069.md +0 -0
  194. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/tasks/1793256929057.md +0 -0
  195. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/tasks/1793256990072.md +0 -0
  196. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/tasks/1793257216492.md +0 -0
  197. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/tasks/1793257519899.md +0 -0
  198. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/41/tasks/1793257826068.md +0 -0
  199. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/CHANGELOG.md +0 -0
  200. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/IMPLEMENTS.md +0 -0
  201. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/PLAN.md +0 -0
  202. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/README.md +0 -0
  203. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/REQUIREMENTS.md +0 -0
  204. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/TASKS.md +0 -0
  205. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/implements/1793260818660.md +0 -0
  206. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/implements/1793261447018.md +0 -0
  207. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/tasks/1793260818661.md +0 -0
  208. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/tasks/1793261447019.md +0 -0
  209. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/43/tasks/1793262314955.md +0 -0
  210. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/CHANGELOG.md +0 -0
  211. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/IMPLEMENTS.md +0 -0
  212. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/PLAN.md +0 -0
  213. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/README.md +0 -0
  214. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/REQUIREMENTS.md +0 -0
  215. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/TASKS.md +0 -0
  216. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/implements/1793282630353.md +0 -0
  217. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/50/tasks/1793282630354.md +0 -0
  218. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/CHANGELOG.md +0 -0
  219. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/IMPLEMENTS.md +0 -0
  220. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/PLAN.md +0 -0
  221. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/README.md +0 -0
  222. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/REQUIREMENTS.md +0 -0
  223. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/TASKS.md +0 -0
  224. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793294516720.md +0 -0
  225. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793295445979.md +0 -0
  226. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793295838896.md +0 -0
  227. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793296500296.md +0 -0
  228. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793299630936.md +0 -0
  229. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793301537859.md +0 -0
  230. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793301829543.md +0 -0
  231. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793302547669.md +0 -0
  232. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793327181557.md +0 -0
  233. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793329241422.md +0 -0
  234. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793516005517.md +0 -0
  235. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793516879583.md +0 -0
  236. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793517548589.md +0 -0
  237. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/implements/1793518878753.md +0 -0
  238. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793294230195.md +0 -0
  239. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793295445976.md +0 -0
  240. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793295838893.md +0 -0
  241. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793296500299.md +0 -0
  242. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793297795667.md +0 -0
  243. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793299630939.md +0 -0
  244. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793301829546.md +0 -0
  245. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793302844699.md +0 -0
  246. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793327181558.md +0 -0
  247. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793327685707.md +0 -0
  248. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793328011412.md +0 -0
  249. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793329241423.md +0 -0
  250. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793516005518.md +0 -0
  251. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793516879584.md +0 -0
  252. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793517548590.md +0 -0
  253. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/53/tasks/1793518878754.md +0 -0
  254. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/6/IMPLEMENTS.md +0 -0
  255. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/6/README.md +0 -0
  256. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/fix/6/REQUIREMENTS.md +0 -0
  257. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/18/IMPLEMENTS.md +0 -0
  258. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/18/README.md +0 -0
  259. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/18/REQUIREMENTS.md +0 -0
  260. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/IMPLEMENTS.md +0 -0
  261. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/ISSUE.md +0 -0
  262. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/PLAN.md +0 -0
  263. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/README.md +0 -0
  264. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/REQUIREMENTS.md +0 -0
  265. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/32/TASK.md +0 -0
  266. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/34/CHANGELOG.md +0 -0
  267. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/34/IMPLEMENTS.md +0 -0
  268. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/34/PLAN.md +0 -0
  269. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/34/README.md +0 -0
  270. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/34/REQUIREMENTS.md +0 -0
  271. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/36/CHANGELOG.md +0 -0
  272. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/36/IMPLEMENTS.md +0 -0
  273. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/36/PLAN.md +0 -0
  274. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/36/README.md +0 -0
  275. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/36/REQUIREMENTS.md +0 -0
  276. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/CHANGELOG.md +0 -0
  277. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/IMPLEMENTS.md +0 -0
  278. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/PLAN.md +0 -0
  279. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/README.md +0 -0
  280. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/REQUIREMENTS.md +0 -0
  281. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/TASKS.md +0 -0
  282. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/docs/CopilotReviewIssues.md +0 -0
  283. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/docs/CopilotReviewIssuesSetup.md +0 -0
  284. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/implements/1793291844133.md +0 -0
  285. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/tasks/1793291844134.md +0 -0
  286. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/38/tasks/1793292234123.md +0 -0
  287. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/CHANGELOG.md +0 -0
  288. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/IMPLEMENTS.md +0 -0
  289. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/PLAN.md +0 -0
  290. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/README.md +0 -0
  291. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/REQUIREMENTS.md +0 -0
  292. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/TASKS.md +0 -0
  293. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793623390266.md +0 -0
  294. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793625464717.md +0 -0
  295. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793626388737.md +0 -0
  296. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793626820522.md +0 -0
  297. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793627348502.md +0 -0
  298. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793628366252.md +0 -0
  299. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793629199999.md +0 -0
  300. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/implements/1793631035346.md +0 -0
  301. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793620359610.md +0 -0
  302. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793621161604.md +0 -0
  303. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793621502459.md +0 -0
  304. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793621903677.md +0 -0
  305. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793623390265.md +0 -0
  306. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793625269565.md +0 -0
  307. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793626388737.md +0 -0
  308. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793626820522.md +0 -0
  309. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793627348502.md +0 -0
  310. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793627590185.md +0 -0
  311. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793628366252.md +0 -0
  312. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793629199998.md +0 -0
  313. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/39/tasks/1793631035345.md +0 -0
  314. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/CHANGELOG.md +0 -0
  315. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/IMPLEMENTS.md +0 -0
  316. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/PLAN.md +0 -0
  317. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/README.md +0 -0
  318. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/REQUIREMENTS.md +0 -0
  319. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/TASKS.md +0 -0
  320. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/implements/1793395003714.md +0 -0
  321. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/tasks/1793395003713.md +0 -0
  322. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/issues/task/57/tasks/1793395058100.md +0 -0
  323. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/pyproject.toml +0 -0
  324. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/rabbitmq/README.md +0 -0
  325. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/rabbitmq/enabled_plugins +0 -0
  326. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/rabbitmq/rabbitmq-3.yml +0 -0
  327. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/rabbitmq/rabbitmq-4.yml +0 -0
  328. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/redis/README.md +0 -0
  329. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/redis/redis-6.yml +0 -0
  330. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/res/docker/redis/redis-7.yml +0 -0
  331. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/RabbitMQ/Sample.RPC.py +0 -0
  332. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/RabbitMQ/Sample.py +0 -0
  333. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/Redis/Sample.Stream.py +0 -0
  334. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/Redis/Sample.py +0 -0
  335. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Broker/Sample.py +0 -0
  336. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Worker/RabbitMQ/Client.py +0 -0
  337. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Worker/RabbitMQ/Tasks.py +0 -0
  338. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Worker/RabbitMQ/Worker.py +0 -0
  339. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Worker/Redis/Sample.py +0 -0
  340. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/samples/Worker/Sample.py +0 -0
  341. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/setup.cfg +0 -0
  342. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/setup.py +0 -0
  343. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Configuration.py +0 -0
  344. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Consumer.py +0 -0
  345. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Errors.py +0 -0
  346. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Event.py +0 -0
  347. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Configuration.py +0 -0
  348. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Event.py +0 -0
  349. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Exchange.py +0 -0
  350. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Queue.py +0 -0
  351. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Serializer.py +0 -0
  352. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Stream.py +0 -0
  353. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/RabbitMQ/Subscription.py +0 -0
  354. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Configuration.py +0 -0
  355. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Connection.py +0 -0
  356. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Consumer.py +0 -0
  357. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Event.py +0 -0
  358. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Queue.py +0 -0
  359. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Serializer.py +0 -0
  360. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/Subscription.py +0 -0
  361. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/Redis/__init__.py +0 -0
  362. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Implements/__init__.py +0 -0
  363. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Priority.py +0 -0
  364. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Broker/Protocol.py +0 -0
  365. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Descriptor/DataObject.py +0 -0
  366. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Descriptor/Types.py +0 -0
  367. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Descriptor/Value.py +0 -0
  368. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Descriptor/__init__.py +0 -0
  369. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extension.py +0 -0
  370. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Metrics.py +0 -0
  371. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Ping.py +0 -0
  372. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Play.html +0 -0
  373. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Play.py +0 -0
  374. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Specifications.py +0 -0
  375. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Status.html +0 -0
  376. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/Status.py +0 -0
  377. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Extensions/__init__.py +0 -0
  378. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Inspector.py +0 -0
  379. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/Response.py +0 -0
  380. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Inspector/__init__.py +0 -0
  381. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Pattern.py +0 -0
  382. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Array.py +0 -0
  383. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Common.py +0 -0
  384. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Compare.py +0 -0
  385. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Condition.py +0 -0
  386. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/DataObject.py +0 -0
  387. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/DateTime.py +0 -0
  388. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Number.py +0 -0
  389. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Object.py +0 -0
  390. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Size.py +0 -0
  391. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/String.py +0 -0
  392. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/Type.py +0 -0
  393. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Patterns/__init__.py +0 -0
  394. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Validate.py +0 -0
  395. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/Validator.py +0 -0
  396. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Validator/__init__.py +0 -0
  397. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Executor.py +0 -0
  398. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Message.py +0 -0
  399. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Pool.py +0 -0
  400. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Run.py +0 -0
  401. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Specification.py +0 -0
  402. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Startup.py +0 -0
  403. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/Worker.py +0 -0
  404. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/Worker/__init__.py +0 -0
  405. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/src/__init__.py +0 -0
  406. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/__init__.py +0 -0
  407. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/_support.py +0 -0
  408. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/_support_inspector.py +0 -0
  409. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/_support_inspector_play.py +0 -0
  410. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/_support_task_messages.py +0 -0
  411. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/__init__.py +0 -0
  412. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_inspector.py +0 -0
  413. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_inspector_play.py +0 -0
  414. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_broker_methods.py +0 -0
  415. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_integration.py +0 -0
  416. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_logging.py +0 -0
  417. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_priorities.py +0 -0
  418. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_rpc.py +0 -0
  419. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_rpc_integration.py +0 -0
  420. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_timeouts.py +0 -0
  421. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_rabbitmq_worker.py +0 -0
  422. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_specifications.py +0 -0
  423. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_task_messages.py +0 -0
  424. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/rabbitmq/test_task_priorities.py +0 -0
  425. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/__init__.py +0 -0
  426. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_inspector.py +0 -0
  427. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_inspector_play.py +0 -0
  428. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_redis.py +0 -0
  429. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_redis_integration.py +0 -0
  430. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_redis_logging.py +0 -0
  431. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_task_messages.py +0 -0
  432. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/redis/test_task_priorities.py +0 -0
  433. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_broker_packaging.py +0 -0
  434. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_descriptor.py +0 -0
  435. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_inspector.py +0 -0
  436. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_inspector_logging.py +0 -0
  437. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_inspector_play.py +0 -0
  438. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_lifecycle_hooks.py +0 -0
  439. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_logging.py +0 -0
  440. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_pool_callbacks.py +0 -0
  441. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_process_signals.py +0 -0
  442. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_runner_hooks.py +0 -0
  443. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_specifications.py +0 -0
  444. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_status.py +0 -0
  445. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_status_ui.cjs +0 -0
  446. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_task_messages.py +0 -0
  447. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_validator_patterns.py +0 -0
  448. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_worker.py +0 -0
  449. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_worker_recovery.py +0 -0
  450. {defstream_rabbitmq-0.1.25 → defstream_rabbitmq-0.1.27}/tests/test_worker_startup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: DefStream-RabbitMQ
3
- Version: 0.1.25
3
+ Version: 0.1.27
4
4
  Summary: Synchronous message processing with pluggable broker adapters
5
5
  Home-page: https://github.com/yong5eon/DefStream
6
6
  Author: Heo Yongseon
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.14
16
16
  Requires-Python: >=3.9
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE
19
- Requires-Dist: DefStream==0.1.25
19
+ Requires-Dist: DefStream==0.1.27
20
20
  Requires-Dist: pika>=1.3.2
21
21
  Dynamic: author
22
22
  Dynamic: classifier
@@ -112,6 +112,22 @@ issues/feature/55/tasks/1793705387888.md
112
112
  issues/feature/55/tasks/1793714914194.md
113
113
  issues/feature/55/tasks/1793715537355.md
114
114
  issues/feature/55/tasks/1793717149426.md
115
+ issues/feature/62/CHANGELOG.md
116
+ issues/feature/62/IMPLEMENTS.md
117
+ issues/feature/62/PLAN.md
118
+ issues/feature/62/README.md
119
+ issues/feature/62/REQUIREMENTS.md
120
+ issues/feature/62/TASKS.md
121
+ issues/feature/62/implements/1793777682327.md
122
+ issues/feature/62/implements/1793778339166.md
123
+ issues/feature/62/tasks/1793772101827.md
124
+ issues/feature/62/tasks/1793774701691.md
125
+ issues/feature/62/tasks/1793775544541.md
126
+ issues/feature/62/tasks/1793775771772.md
127
+ issues/feature/62/tasks/1793777337621.md
128
+ issues/feature/62/tasks/1793777847993.md
129
+ issues/feature/62/tasks/1793778003070.md
130
+ issues/feature/62/tasks/1793778440735.md
115
131
  issues/feature/8/IMPLEMENTS.md
116
132
  issues/feature/8/README.md
117
133
  issues/feature/8/REQUIREMENTS.md
@@ -216,6 +232,18 @@ issues/fix/53/tasks/1793518878754.md
216
232
  issues/fix/6/IMPLEMENTS.md
217
233
  issues/fix/6/README.md
218
234
  issues/fix/6/REQUIREMENTS.md
235
+ issues/fix/64/CHANGELOG.md
236
+ issues/fix/64/IMPLEMENTS.md
237
+ issues/fix/64/PLAN.md
238
+ issues/fix/64/README.md
239
+ issues/fix/64/REQUIREMENTS.md
240
+ issues/fix/64/TASKS.md
241
+ issues/fix/64/implements/1793807653096.md
242
+ issues/fix/64/implements/1793807663436.md
243
+ issues/fix/64/tasks/1793806949650.md
244
+ issues/fix/64/tasks/1793807182094.md
245
+ issues/fix/64/tasks/1793807663435.md
246
+ issues/fix/64/tasks/1793807722809.md
219
247
  issues/task/18/IMPLEMENTS.md
220
248
  issues/task/18/README.md
221
249
  issues/task/18/REQUIREMENTS.md
@@ -292,6 +320,7 @@ res/docker/redis/redis-7.yml
292
320
  samples/Broker/Sample.py
293
321
  samples/Broker/RabbitMQ/Sample.RPC.py
294
322
  samples/Broker/RabbitMQ/Sample.Stream.py
323
+ samples/Broker/RabbitMQ/Sample.Timer.py
295
324
  samples/Broker/RabbitMQ/Sample.py
296
325
  samples/Broker/Redis/Sample.Stream.py
297
326
  samples/Broker/Redis/Sample.py
@@ -402,6 +431,7 @@ tests/rabbitmq/test_rabbitmq_priorities.py
402
431
  tests/rabbitmq/test_rabbitmq_rpc.py
403
432
  tests/rabbitmq/test_rabbitmq_rpc_integration.py
404
433
  tests/rabbitmq/test_rabbitmq_timeouts.py
434
+ tests/rabbitmq/test_rabbitmq_timers.py
405
435
  tests/rabbitmq/test_rabbitmq_worker.py
406
436
  tests/rabbitmq/test_specifications.py
407
437
  tests/rabbitmq/test_task_messages.py
@@ -35,5 +35,5 @@ Messages published by a producer pass through the broker to a Worker Consumer, a
35
35
  - [Lifecycle hooks](./LifecycleHooks.en.md): hook order and resource management across Workers, pools, and tasks
36
36
  - [Request/reply contracts and validation](./Contracts.en.md): schemas, validators, and task contracts
37
37
  - [Operations and monitoring](./Operations.en.md): Inspector, logging, and operational broker considerations
38
- - [RabbitMQ](./RabbitMQ.en.md): queues, exchanges, streams, RPC, and RabbitMQ workers
38
+ - [RabbitMQ](./RabbitMQ.en.md): queues, exchanges, streams, RPC, connection timers, and RabbitMQ workers
39
39
  - [Redis Streams](./Redis.en.md): messages, consumer groups, acknowledgements, and Redis workers
@@ -35,5 +35,5 @@ Producer가 발행한 메시지는 브로커를 거쳐 Worker의 Consumer로 전
35
35
  - [생명주기 훅](./LifecycleHooks.md): Worker·풀·작업 훅의 실행 순서와 자원 관리
36
36
  - [요청·응답 계약과 검증](./Contracts.md): 스키마, validator와 작업 계약
37
37
  - [운영과 모니터링](./Operations.md): Inspector, 로깅, 브로커 선택과 운영 고려사항
38
- - [RabbitMQ](./RabbitMQ.md): 큐, Exchange, 스트림, RPC와 RabbitMQ Worker
38
+ - [RabbitMQ](./RabbitMQ.md): 큐, Exchange, 스트림, RPC, 연결 타이머와 RabbitMQ Worker
39
39
  - [Redis Streams](./Redis.md): 메시지, consumer group, ACK와 Redis Worker
@@ -88,6 +88,116 @@ Call `ack()` on success, `nack()` for redelivery, or `reject()` to reject.
88
88
  Rejected messages go to the broker-configured dead-letter destination or are
89
89
  discarded when none is configured.
90
90
 
91
+ ### Connection timers
92
+
93
+ RabbitMQ connections support the optional `SetTimer` protocol.
94
+ `set_timer(cb, seconds)` schedules a one-shot callback using integer seconds
95
+ from registration and returns a cancelable `Timer`. The callback takes no
96
+ arguments and returns no value. Code using a connection can check support
97
+ with `isinstance(connection, SetTimer)`. Timer support is not required by
98
+ the base `Connection` contract or Redis connections.
99
+
100
+ This example consumes an empty queue and stops consumption from a callback
101
+ after five seconds. It requires local RabbitMQ and leaves
102
+ `defstream.example.timer` in place. Messages sent to this queue by other
103
+ producers are printed and acknowledged.
104
+
105
+ ```python
106
+ from DefStream.Broker import Event, SetTimer
107
+ from DefStream.Broker.Implements.RabbitMQ import Configuration, Connection
108
+
109
+
110
+ def receive(event: Event) -> None:
111
+ print(event.body)
112
+ event.ack()
113
+
114
+
115
+ connection = Connection(Configuration(
116
+ host='127.0.0.1',
117
+ port=5672,
118
+ username='guest',
119
+ password='guest',
120
+ ))
121
+ try:
122
+ connection.connect()
123
+ if not isinstance(connection, SetTimer):
124
+ raise TypeError('Connection does not support timers')
125
+ connection.create_queue('defstream.example.timer')
126
+ consumer = connection.consumer()
127
+ consumer.subs('defstream.example.timer', receive)
128
+
129
+ def expired() -> None:
130
+ print('Timer fired')
131
+ consumer.stop()
132
+
133
+ timer = connection.set_timer(cb=expired, seconds=5)
134
+ try:
135
+ consumer.run()
136
+ finally:
137
+ timer.remove()
138
+ consumer.close()
139
+ finally:
140
+ connection.close()
141
+ ```
142
+
143
+ Call `timer.remove()` before execution to cancel the scheduled callback.
144
+ The handle belongs to the connection that registered it; reopening a connection
145
+ does not redirect cancellation to the new connection.
146
+ Already-fired or canceled timers, closed connections, and negative or zero
147
+ delays retain Pika's behavior and errors. `remove()` does not interrupt a
148
+ callback that is already running.
149
+
150
+ For repetition, register the next timer inside the callback.
151
+ The following excerpt replaces the `expired` definition and the one-shot
152
+ registration, execution, and consumer cleanup above, after preparing the
153
+ subscription through `consumer.subs(...)`. Keep the outer `finally` that
154
+ closes the connection. It fires three times at five-second intervals, then
155
+ stops, retaining the latest handle for cancellation.
156
+
157
+ ```python
158
+ from DefStream.Broker import Consumer, SetTimer, Timer
159
+
160
+
161
+ def run_repeated(connection: SetTimer, consumer: Consumer) -> None:
162
+ remaining = 3
163
+ timer: Timer
164
+
165
+ def tick() -> None:
166
+ nonlocal remaining, timer
167
+ print('Timer fired')
168
+ remaining -= 1
169
+ if remaining:
170
+ timer = connection.set_timer(tick, 5)
171
+ else:
172
+ consumer.stop()
173
+
174
+ timer = connection.set_timer(tick, 5)
175
+ try:
176
+ consumer.run()
177
+ finally:
178
+ timer.remove()
179
+
180
+
181
+ try:
182
+ run_repeated(connection, consumer)
183
+ finally:
184
+ consumer.close()
185
+ ```
186
+
187
+ The implementation delegates directly to Pika's `call_later` and
188
+ `remove_timeout`. Callbacks run only while Pika processes events, such as
189
+ during `consumer.run()`. Registering a timer and calling `sleep()` alone
190
+ does not dispatch it. Long message handlers and other event-loop work can
191
+ delay execution. Callbacks run on the connection owner thread, and their
192
+ exceptions propagate through the existing event-processing path.
193
+
194
+ Registration and cancellation follow Pika's owner-thread restrictions;
195
+ no additional thread safety is provided. Consumer exit does not automatically
196
+ cancel connection timers, so callers must cancel reservations when appropriate.
197
+ The examples cancel before closing the connection; cancellation on a closed
198
+ connection is not guaranteed to succeed. No separate timer thread,
199
+ general-purpose scheduler, or automatic cleanup layer is provided.
200
+
91
201
  ### Logging
92
202
 
93
203
  `Connection`, `Consumer`, `Queue`, `Exchange`, `Stream`, and `Event` expose a class
@@ -383,3 +493,18 @@ publishing the reply but before ACK, the task may be redelivered and run again.
383
493
  - [Sample.py](../samples/Broker/RabbitMQ/Sample.py)
384
494
  - [Sample.Stream.py](../samples/Broker/RabbitMQ/Sample.Stream.py)
385
495
  - [Sample.RPC.py](../samples/Broker/RabbitMQ/Sample.RPC.py)
496
+ - [Sample.Timer.py](../samples/Broker/RabbitMQ/Sample.Timer.py): one-shot cancellation and repetition by re-registering callbacks
497
+
498
+ The timer sample uses local RabbitMQ at `127.0.0.1:5672` with the `guest` account.
499
+ Enable the RabbitMQ implementation in your development environment and run it
500
+ from the repository root.
501
+
502
+ ```shell
503
+ python samples/Broker/RabbitMQ/Sample.Timer.py
504
+ ```
505
+
506
+ Each run creates a uniquely named empty queue, cancels one callback before
507
+ execution, then logs three timer callbacks at one-second intervals and stops
508
+ consumption. It cleans up the latest timer, consumer channel, sample queue,
509
+ and connection. The Stream sample also uses the connection's `set_timer`
510
+ instead of a separate timer thread to stop consumption.
@@ -103,6 +103,109 @@ finally:
103
103
  일반 연결의 heartbeat는 애플리케이션 작업·유휴 시간에 맞게 설정하고 처리되도록 관리하세요.
104
104
  연결과 그 리소스는 **소유 스레드에서만 사용**해야 하며, 스레드·프로세스 사이에 공유하지 마세요.
105
105
 
106
+ ### 연결 타이머
107
+
108
+ RabbitMQ 연결은 선택적 `SetTimer` 프로토콜을 지원합니다.
109
+ `set_timer(cb, seconds)`는 등록 시점부터 정수 초 단위로 일회성 콜백을 예약하고,
110
+ 취소할 수 있는 `Timer`를 반환합니다. 콜백은 인자 없이 호출되며 반환값이 없습니다.
111
+ 연결을 사용하는 코드에서 `isinstance(connection, SetTimer)`로 지원 여부를 확인할 수 있습니다.
112
+ 기본 `Connection` 계약과 Redis 연결에는 타이머 지원이 강제되지 않습니다.
113
+
114
+ 다음 예제는 메시지가 없는 큐를 소비하면서 5초 뒤 콜백으로 소비를 중단합니다.
115
+ 로컬 RabbitMQ가 필요하며 `defstream.example.timer` 큐는 실행 후에도 유지합니다.
116
+ 다른 생산자가 이 큐에 보낸 메시지는 출력한 뒤 ACK합니다.
117
+
118
+ ```python
119
+ from DefStream.Broker import Event, SetTimer
120
+ from DefStream.Broker.Implements.RabbitMQ import Configuration, Connection
121
+
122
+
123
+ def receive(event: Event) -> None:
124
+ print(event.body)
125
+ event.ack()
126
+
127
+
128
+ connection = Connection(Configuration(
129
+ host='127.0.0.1',
130
+ port=5672,
131
+ username='guest',
132
+ password='guest',
133
+ ))
134
+ try:
135
+ connection.connect()
136
+ if not isinstance(connection, SetTimer):
137
+ raise TypeError('Connection does not support timers')
138
+ connection.create_queue('defstream.example.timer')
139
+ consumer = connection.consumer()
140
+ consumer.subs('defstream.example.timer', receive)
141
+
142
+ def expired() -> None:
143
+ print('Timer fired')
144
+ consumer.stop()
145
+
146
+ timer = connection.set_timer(cb=expired, seconds=5)
147
+ try:
148
+ consumer.run()
149
+ finally:
150
+ timer.remove()
151
+ consumer.close()
152
+ finally:
153
+ connection.close()
154
+ ```
155
+
156
+ 실행 전에 `timer.remove()`를 호출하면 해당 예약을 취소합니다.
157
+ 핸들은 등록 당시 연결에 연결되며, 연결을 다시 열어도 새 연결의 타이머를 취소하지 않습니다.
158
+ 이미 실행·취소된 예약, 닫힌 연결, 음수·0초 지연의 동작과 오류는 Pika API를 그대로 따릅니다.
159
+ `remove()`는 실행 중인 콜백을 강제로 중단하지 않습니다.
160
+
161
+ 반복 실행은 콜백 안에서 다음 타이머를 등록하면 됩니다.
162
+ 아래는 반복 실행용 발췌입니다. 위 예제에서 `consumer.subs(...)`까지 준비한 뒤,
163
+ `expired` 정의와 일회성 타이머 등록·실행·소비자 정리 부분을 아래 코드로 교체합니다.
164
+ 바깥쪽 `finally`의 연결 종료는 유지합니다.
165
+ 5초 간격으로 세 번 실행하고 중단하며, 취소할 때 사용할 최신 핸들을 보관합니다.
166
+
167
+ ```python
168
+ from DefStream.Broker import Consumer, SetTimer, Timer
169
+
170
+
171
+ def run_repeated(connection: SetTimer, consumer: Consumer) -> None:
172
+ remaining = 3
173
+ timer: Timer
174
+
175
+ def tick() -> None:
176
+ nonlocal remaining, timer
177
+ print('Timer fired')
178
+ remaining -= 1
179
+ if remaining:
180
+ timer = connection.set_timer(tick, 5)
181
+ else:
182
+ consumer.stop()
183
+
184
+ timer = connection.set_timer(tick, 5)
185
+ try:
186
+ consumer.run()
187
+ finally:
188
+ timer.remove()
189
+
190
+
191
+ try:
192
+ run_repeated(connection, consumer)
193
+ finally:
194
+ consumer.close()
195
+ ```
196
+
197
+ RabbitMQ 구현은 Pika의 `call_later`·`remove_timeout`에 직접 위임합니다.
198
+ `consumer.run()`과 같은 Pika 이벤트 처리가 진행되어야 콜백이 실행됩니다.
199
+ 단순히 등록 후 `sleep()`하는 것만으로는 실행되지 않으며,
200
+ 긴 메시지 처리나 이벤트 루프 작업 때문에 실행이 늦어질 수 있습니다.
201
+ 콜백은 연결 소유 스레드에서 실행되고, 예외는 기존 이벤트 처리 경로로 전파됩니다.
202
+
203
+ 등록·취소는 Pika의 소유 스레드 제약을 따르며 추가 스레드 안전성을 제공하지 않습니다.
204
+ Consumer 종료 시 연결 타이머를 자동으로 취소하지 않으므로,
205
+ 필요한 예약은 호출자가 적절한 시점에 취소해야 합니다.
206
+ 위 예제는 연결을 닫기 전에 취소하며, 닫힌 연결에서 취소가 항상 성공한다고 보장하지 않습니다.
207
+ 별도 타이머 스레드·범용 스케줄러·자동 정리 계층은 제공하지 않습니다.
208
+
106
209
  ### 로깅
107
210
 
108
211
  여섯 클래스는 `Broker.RabbitMQ.ClassName` 이름의 클래스 멤버
@@ -370,3 +473,16 @@ sequenceDiagram
370
473
  - [Sample.py](../samples/Broker/RabbitMQ/Sample.py)
371
474
  - [Sample.Stream.py](../samples/Broker/RabbitMQ/Sample.Stream.py)
372
475
  - [Sample.RPC.py](../samples/Broker/RabbitMQ/Sample.RPC.py)
476
+ - [Sample.Timer.py](../samples/Broker/RabbitMQ/Sample.Timer.py): 일회성 예약 취소와 콜백 재등록에 의한 반복 실행
477
+
478
+ 타이머 샘플은 로컬 RabbitMQ의 `127.0.0.1:5672`와 `guest` 계정을 사용합니다.
479
+ 개발 환경에서 RabbitMQ 구현체를 사용할 수 있어야 하며, 저장소 루트에서 실행하세요.
480
+
481
+ ```shell
482
+ python samples/Broker/RabbitMQ/Sample.Timer.py
483
+ ```
484
+
485
+ 실행마다 고유한 빈 큐를 만들고, 취소한 콜백은 실행하지 않으며,
486
+ 1초 간격으로 세 번 출력한 뒤 소비를 중단합니다.
487
+ 종료 시 최신 타이머·소비 채널·샘플 큐·연결을 정리합니다.
488
+ Stream 샘플의 소비 중단도 별도 스레드 타이머 대신 연결의 `set_timer`를 사용합니다.
@@ -0,0 +1,26 @@
1
+ # 연결 타이머 등록과 취소
2
+
3
+ ## 추가된 기능
4
+
5
+ RabbitMQ 연결에서 `set_timer(cb, seconds)`로 일회성 콜백을 예약하고,
6
+ 반환된 `Timer`의 `remove()`로 취소할 수 있습니다.
7
+ 호출자는 Pika 연결이나 내부 타이머 ID를 직접 다루지 않아도 됩니다.
8
+
9
+ `SetTimer`는 연결의 선택적 기능이며, `Timer`, `TimerCallback`과 함께
10
+ `DefStream.Broker` 및 `DefStream.Broker.Connection`에서 import할 수 있습니다.
11
+ 반복 실행은 콜백에서 다음 타이머를 등록하는 방식으로 구성합니다.
12
+
13
+ [실행 가능한 타이머 샘플](../../../samples/Broker/RabbitMQ/Sample.Timer.py)에서
14
+ 취소와 재등록을 확인할 수 있습니다. 기존 Stream 샘플의 소비 중단도
15
+ 외부 스레드 타이머 대신 연결 타이머를 사용합니다.
16
+
17
+ ## 사용 조건
18
+
19
+ - 지연 시간은 등록 시점부터 정수 초 단위로 지정합니다.
20
+ - RabbitMQ 소비 루프 등 Pika의 이벤트 처리가 진행되어야 콜백이 실행됩니다.
21
+ - 등록·취소는 연결 소유 스레드에서 수행하며, 긴 이벤트 처리로 실행이 지연될 수 있습니다.
22
+ - Consumer 종료 시 예약을 자동 취소하지 않습니다. 취소 시점과 연결의 사용 순서는 호출자가 관리합니다.
23
+ - 중복 취소·종료된 연결·음수·0초 등의 동작과 오류는 기반 Pika API를 따릅니다.
24
+ - Redis 타이머 지원이나 기존 Consumer·Worker API 변경은 포함하지 않습니다.
25
+
26
+ 자세한 사용법은 [RabbitMQ 연결 타이머 안내](../../../docs/RabbitMQ.md#연결-타이머)를 참고하세요.
@@ -0,0 +1,26 @@
1
+ # 연결 타이머 구현 결과
2
+
3
+ ## 구현 내용
4
+
5
+ - [공통 연결 계약](../../../src/Broker/Connection.py)에 `Timer`, `TimerCallback`, `SetTimer`를 추가하고 [Broker 공개 진입점](../../../src/Broker/__init__.py)에서도 노출했다.
6
+ - `Timer`, `SetTimer`의 런타임 검사·추상 메서드 선언과 `set_timer(cb: TimerCallback, seconds: int) -> Timer` 시그니처를 확정 명세대로 구현했다.
7
+ - [RabbitMQ 연결](../../../src/Broker/Implements/RabbitMQ/Connection.py)은 `SetTimer`를 명시적으로 상속한다. 기존 연결 확인 후 즉시 `call_later(seconds, cb)`로 일회성 예약을 등록하므로 지연 시간은 등록 시점부터 계산된다.
8
+ - 반환하는 구체 `Timer`는 등록 당시 실제 연결과 불투명 핸들만 보관한다. `remove()`는 해당 연결의 `remove_timeout`에 직접 위임하여 상위 연결 객체가 재연결되어도 취소 대상이 바뀌지 않는다.
9
+ - 콜백 래퍼·스레드·추가 동기화·상태 검사·자동 정리 계층은 추가하지 않았다. 스레드 제약·취소·입력값·오류 동작은 Pika API를 따른다.
10
+ - 한국어·영어 [RabbitMQ 사용 안내](../../../docs/RabbitMQ.md)에 일회성·취소·재등록 예제와 사용 제약을 반영했다.
11
+ - 실행 가능한 [타이머 샘플](../../../samples/Broker/RabbitMQ/Sample.Timer.py)을 추가하고, [Stream 샘플](../../../samples/Broker/RabbitMQ/Sample.Stream.py)의 별도 스레드 타이머와 중계 함수를 연결의 `set_timer(consumer.stop, 1)`로 교체했다.
12
+
13
+ ## 유지한 범위
14
+
15
+ Consumer·Worker·Ping·Pool·Executor·Event·Redis 구현과 연결·소비 종료 처리는 변경하지 않았다. 기본 Connection 계약에 타이머를 강제하지 않으며, 별도 이슈 #63·#64의 리팩터링을 포함하지 않았다.
16
+
17
+ ## 검증과 제한
18
+
19
+ 샘플 검증 추가 후 단위·회귀 45개가 통과했으며 실제 브로커 테스트 4개는 기본 실행에서 건너뛰었다. 별도 유휴 실행 테스트는 로컬 RabbitMQ 연결 실패로 동작 검증까지 진행하지 못했다. 타입·구문 진단과 사용 예제 검증 결과는 [작업 종합](./TASKS.md)에 구분하여 기록했다.
20
+
21
+ 구현은 반영했지만 유휴 실행·실제 소유 스레드·취소·재등록·콜백 예외의 실제 브로커 인수 확인은 남아 있다.
22
+
23
+ ## 구현 기록
24
+
25
+ - [연결 타이머 계약과 RabbitMQ 등록·취소 구현](./implements/1793777682327.md)
26
+ - [실행 가능한 연결 타이머 샘플 추가](./implements/1793778339166.md)
@@ -0,0 +1,175 @@
1
+ # Connection 기반 타이머 작업 계획
2
+
3
+ ## 기준과 현재 상태
4
+
5
+ - 범위와 공개 계약은 [요구사항](./REQUIREMENTS.md)을 따른다. 작업 브랜치·분기 기준·병합 대상은 [이슈 정보](./README.md)에 모은다.
6
+ - 계약·RabbitMQ 구현·테스트·한국어와 영어 매뉴얼을 반영했다. 단위·회귀 검증은 통과했으며 실제 RabbitMQ 검증은 서버 연결 불가로 남아 있다. 세부 결과는 [구현 종합](./IMPLEMENTS.md)과 [작업 종합](./TASKS.md)을 따른다.
7
+ - [워커 리팩토링 #63](https://github.com/yong5eon/DefStream/issues/63)과 [Recoverable 명시적 상속 #64](https://github.com/yong5eon/DefStream/issues/64)는 별도 작업이며 이번 선행 조건이 아니다.
8
+
9
+ ## 구현 방향
10
+
11
+ 추가할 동작은 다음 두 경로로 한정한다.
12
+
13
+ ```text
14
+ connection.set_timer(cb, seconds)
15
+ → 현재 Pika 연결의 call_later(seconds, cb)
16
+ → 취소 핸들을 보관하는 Timer 반환
17
+
18
+ timer.remove()
19
+ → 등록 당시 Pika 연결의 remove_timeout(등록 핸들)
20
+ ```
21
+
22
+ - 등록 시 콜백과 초 단위 지연 시간을 그대로 전달한다. 콜백을 다른 함수로 감싸거나 소비 시작까지 등록을 미루지 않는다.
23
+ - 반환 객체는 기반 연결과 등록 핸들만 보관하는 작은 구현체로 둔다. 호출자는 내부 Pika 객체나 타이머 ID를 다루지 않는다.
24
+ - 핸들은 등록 당시의 실제 연결을 참조한다. 취소 시 상위 연결 객체의 현재 연결을 다시 조회하지 않아, 재연결 후 다른 연결에 이전 핸들을 전달하지 않는다.
25
+ - `remove`는 기반 취소 API를 호출한다. 실행·취소 상태 플래그, 타이머 목록, 중복 취소 방지, 별도 입력 검증, 자동 정리 계층은 추가하지 않는다.
26
+ - 기존 `connected()`와 오류 관찰 관례를 재사용한다. 새 폴백이나 오류를 정상 반환으로 바꾸는 처리는 추가하지 않는다.
27
+ - 기존 Consumer의 확인용 타이머, `run`·`stop`·`close`, 연결 종료 처리에는 손대지 않는다.
28
+
29
+ ## 변경 대상
30
+
31
+ | 대상 | 변경 내용 |
32
+ | --- | --- |
33
+ | [공통 연결 계약](../../../src/Broker/Connection.py) | `Timer`, `TimerCallback`, `SetTimer`와 `__all__` 등록 |
34
+ | [Broker 공개 진입점](../../../src/Broker/__init__.py) | 세 계약의 import와 `__all__` 재노출 |
35
+ | [RabbitMQ 연결](../../../src/Broker/Implements/RabbitMQ/Connection.py) | `SetTimer` 명시적 상속, `set_timer`, 취소 핸들 구현 |
36
+ | [프로토콜 계약 테스트](../../../tests/test_protocol_contracts.py) | 공개 타입·시그니처·데코레이터·선택적 지원 검증 |
37
+ | [타이머 테스트](../../../tests/rabbitmq/test_rabbitmq_timers.py) 신규 | 등록·취소 위임 단위 테스트와 opt-in 실제 타이머 테스트 |
38
+ | [타이머 샘플](../../../samples/Broker/RabbitMQ/Sample.Timer.py) 신규·[Stream 샘플](../../../samples/Broker/RabbitMQ/Sample.Stream.py) | 실행 가능한 취소·재등록 예제와 기존 외부 타이머 교체 |
39
+ | [RabbitMQ 한국어 안내](../../../docs/RabbitMQ.md)·[영어 안내](../../../docs/RabbitMQ.en.md) | 지원 범위와 등록·취소·재등록 사용법 |
40
+ | [매뉴얼 한국어 진입점](../../../docs/README.md)·[영어 진입점](../../../docs/README.en.md) | 기존 RabbitMQ 안내 항목에 연결 타이머 주제 반영 |
41
+ | 이 이슈의 기록 문서 | 진행 상태·검증 결과·최종 변경 로그 기록 |
42
+
43
+ 새 제품 소스 모듈은 만들지 않는 방향으로 진행한다. 구체 타이머는 RabbitMQ 연결 모듈 안에 `Timer` 클래스로 두고 공통 계약을 `BaseTimer`로 import하여 명시적으로 구현한다. 구체 핸들 클래스를 RabbitMQ 패키지의 새 공개 진입점으로 노출할 필요는 없다.
44
+
45
+ ## 수행 순서와 완료 조건
46
+
47
+ ### 1. 공통 계약과 공개 import 추가
48
+
49
+ 선행 조건: 확정 요구사항 확인.
50
+
51
+ 1. 공통 연결 계약 모듈에 다음 선언을 추가한다.
52
+ - `Timer`: `@runtime_checkable`, `remove(self) -> None`에 `@abstractmethod`
53
+ - `TimerCallback`: `__call__(self) -> None`, 추가 데코레이터 없음
54
+ - `SetTimer`: `@runtime_checkable`, `set_timer(self, cb: TimerCallback, seconds: int) -> Timer`에 `@abstractmethod`
55
+ 2. `cb`, `seconds`는 기본값 없는 위치 또는 키워드 인자로 유지한다. 위치 전용·키워드 전용 제한을 추가하지 않는다.
56
+ 3. 모듈과 Broker 패키지의 `__all__`·import를 함께 갱신한다. 사용자는 `DefStream.Broker` 및 `DefStream.Broker.Connection`에서 같은 계약을 import할 수 있어야 한다.
57
+ 4. 기본 `Connection`과 Consumer의 필수 메서드는 변경하지 않는다.
58
+ 5. 기존 계약 테스트에 공개 경로, 타입 힌트와 시그니처, 런타임 판별, 명시적 상속 시 필수 메서드 미구현 여부를 검증하는 항목을 추가한다.
59
+
60
+ 완료 조건: 요구사항 R1·R2의 선언과 공개 import가 일치하며 기존 계약은 유지된다.
61
+
62
+ ### 2. RabbitMQ 등록·취소 구현
63
+
64
+ 선행 조건: 1단계의 공통 계약 추가.
65
+
66
+ 1. 실제 개발 환경의 Pika `call_later`·`remove_timeout` 선언과 반환 핸들 타입을 확인하고 타입 힌트에 반영한다. 반환 핸들을 임의로 정수 ID로 가정하거나 근거 없는 캐스팅으로 숨기지 않는다.
67
+ 2. RabbitMQ `Connection`의 기존 상속 목록에 `SetTimer`를 추가한다.
68
+ 3. `set_timer`는 기존 `connected()`로 연결을 얻고 즉시 `call_later(seconds, cb)`를 호출한다. 설정값 변환·보정·추가 검증은 하지 않는다.
69
+ 4. 등록 당시 Pika 연결과 반환 핸들을 보관하는 구체 `Timer`를 반환한다.
70
+ 5. 구체 `Timer.remove()`는 보관한 연결의 `remove_timeout`에 보관한 핸들을 전달한다. 중복 호출과 종료된 연결의 결과도 기반 API에 맡긴다.
71
+ 6. 등록·취소의 기반 오류는 숨기지 않는다. 콜백은 그대로 전달하여 예외가 기존 Pika 이벤트 처리 경로에서 드러나게 한다.
72
+
73
+ 완료 조건: 요구사항 R1~R3을 만족하며 추가 스레드·이벤트 큐·상태 관리 계층이 없다.
74
+
75
+ ### 3. 직접 영향 범위 검증
76
+
77
+ 선행 조건: 1·2단계 구현.
78
+
79
+ 기존 `unittest`와 `unittest.mock` 관례를 사용한다. 새 검증 라이브러리는 추가하지 않는다.
80
+
81
+ #### 단위 테스트
82
+
83
+ | 항목 | 검증 방법과 기대 결과 | 요구사항 |
84
+ | --- | --- | --- |
85
+ | 공개 계약 | 두 공개 import 경로가 같은 타입을 가리키고 `__all__`에 포함되는지 확인 | R1·R2 |
86
+ | 선택적 기능 | RabbitMQ 연결은 `SetTimer`로 판별되고 기본 Connection·Consumer·Redis에는 타이머 의무가 추가되지 않았는지 확인 | R1·R4 |
87
+ | 정확한 등록 | 위치·키워드 호출 모두 `call_later(seconds, cb)`에 동일한 값과 같은 콜백 객체를 한 번 전달하는지 확인 | R2·R3 |
88
+ | 콜백 계약 | 일반 함수와 `__call__` 객체를 `TimerCallback`으로 사용할 수 있고 등록 자체가 콜백을 호출하지 않는지 확인 | R2 |
89
+ | 반환·취소 | 반환 핸들이 `Timer` 계약을 충족하고 `remove_timeout`에 기반 핸들을 그대로 전달하는지 확인 | R2·R3 |
90
+ | 연결 대응 | 상위 연결 객체의 연결 참조가 바뀌어도 기존 핸들은 등록 당시 연결에 취소를 요청하는지 확인 | R3 |
91
+ | 오류 전파 | 기반 등록·취소 API가 발생시킨 예외를 그대로 관찰할 수 있는지 확인 | R3 |
92
+ | 얇은 위임 | 중복 취소를 자체 차단하지 않고 0·음수도 기반 API에 전달하는지 확인. 기반 동작을 새 정책으로 재정의하지 않음 | R3 |
93
+
94
+ #### 실제 RabbitMQ 테스트
95
+
96
+ - 신규 타이머 테스트 모듈의 `RabbitMQTimerIntegrationTests`에 기존 `RABBITMQ_TESTS=1` opt-in 방식을 적용한다. 포트는 기존 `rabbitmq_test_port()`를 사용한다.
97
+ - 연결·소비·타이머 등록은 같은 소유 스레드에서 수행한다. 다른 스레드의 안전성을 검증한다는 명목으로 제품에 동기화 기능을 추가하지 않는다.
98
+ - 테스트 전용 이름의 빈 큐를 구독하여 메시지 없는 소비 대기 중 콜백 실행과 소유 스레드 일치를 확인한다.
99
+ - 개별 취소 후 미실행, 콜백 재등록에 의한 반복 실행, 콜백 예외가 `consumer.run()` 호출자에게 전달되는 동작을 확인한다.
100
+ - 테스트에 유한 실행 제한을 두고, 테스트가 만든 큐·채널·연결은 테스트의 정리 코드에서 정리한다. 이를 제품의 자동 정리 요구로 옮기지 않는다.
101
+ - 실제 서버를 사용할 수 없으면 단위 테스트로 유휴 실행까지 검증했다고 쓰지 않고 통합 검증 미실행으로 기록한다.
102
+
103
+ 완료 조건: 아래 명령과 진단 결과를 실제 수행 기록에 남긴다. 실패가 이번 변경에서 발생했으면 수정하고 관련 없는 기존 실패는 근거와 함께 구분한다.
104
+
105
+ ### 4. 한국어·영어 사용 안내
106
+
107
+ 선행 조건: 3단계에서 공개 동작 확인.
108
+
109
+ 1. 두 RabbitMQ 매뉴얼에 같은 범위의 연결 타이머 절을 추가한다.
110
+ 2. `isinstance(connection, SetTimer)`로 지원 여부를 확인하고 연결 후 `set_timer`로 등록하는 방법을 안내한다.
111
+ 3. 빈 큐 소비 중 실행되는 일회성 콜백과 콜백 안의 재등록, `Timer.remove()`를 설명한다. 기존 Consumer API를 그대로 사용하며 제품에 새로운 실행 API를 만들지 않는다.
112
+ 4. 초 단위·등록 시점 기준·Pika 이벤트 처리 필요·소유 스레드 제약·실행 지연 가능성·호출자의 취소 책임을 명시한다.
113
+ 5. 예제는 필요한 import·연결·구독·실행·테스트 자원 정리까지 확인 가능하게 작성한다. 종료된 연결의 핸들을 무조건 안전하게 취소할 수 있다고 보장하지 않는다.
114
+ 6. 두 매뉴얼 진입점의 기존 RabbitMQ 항목에 타이머 주제를 반영한다. 별도 타이머 매뉴얼이나 다이어그램은 단순 등록·취소 설명에 필요하지 않으면 만들지 않는다.
115
+ 7. 루트 README 요약에 타이머 안내가 필요한지만 확인한다. 필요할 때에만 한국어·영어 요약을 함께 갱신하며, 상세 사용법은 매뉴얼에 둔다.
116
+ 8. 사용자 요청으로 실행 가능한 타이머 샘플을 추가하고 기존 Stream 샘플도 연결 타이머를 이용하도록 갱신한다. 샘플의 등록·취소·재등록·자원 정리를 단위 검증하며, import 시 연결과 로깅 설정이 실행되지 않는지 기존 검증에 포함한다.
117
+
118
+ 완료 조건: 요구사항 R5와 실제 구현이 일치하며 미지원 브로커나 추가 스레드 안전성을 보장하는 표현이 없다.
119
+
120
+ ### 5. 결과 정리와 범위 확인
121
+
122
+ 선행 조건: 3·4단계 완료.
123
+
124
+ 1. 변경 파일 목록을 확인하여 Consumer·Worker·Ping·Pool·Executor·Event·Redis 구현이 섞이지 않았는지 확인한다. #63·#64의 작업은 하지 않는다.
125
+ 2. 구현 단계는 `implements/`, 검증 등 구현 외 작업은 `tasks/`에 실제 수행 시점의 기록을 남긴다.
126
+ 3. 구현 결과를 `IMPLEMENTS.md`, 작업 결과를 `TASKS.md`에 종합한다. 이 단계에서 아직 없는 구현 문서를 빈 파일로 미리 만들지 않는다.
127
+ 4. 실제 제공된 타이머 등록·취소 기능과 사용 제약만 이슈의 `CHANGELOG.md`에 작성한다. 내부 계획·문서 작성·테스트 통과를 고객 기능으로 나열하지 않는다.
128
+ 5. README와 이 계획의 진행 상태를 갱신한다. 필요한 검증이 남았다면 전체 구현 완료로 표시하지 않는다.
129
+
130
+ ## 검증 명령과 환경
131
+
132
+ 명령은 저장소 루트에서 개발 환경에 선택된 `python`으로 실행한다. 아래 타이머 테스트 모듈·클래스는 구현 단계에서 추가했다.
133
+
134
+ ### 먼저 실행할 단위·회귀 검증
135
+
136
+ 실제 RabbitMQ opt-in 환경변수가 꺼진 상태에서 다음 모듈을 한 번의 실행으로 검사한다.
137
+
138
+ ```shell
139
+ python -m unittest tests.test_protocol_contracts tests.rabbitmq.test_rabbitmq_timers tests.rabbitmq.test_rabbitmq_broker_methods tests.rabbitmq.test_rabbitmq_logging tests.rabbitmq.test_rabbitmq_timeouts -v
140
+ ```
141
+
142
+ - 등록·취소 단위 테스트와 공통 계약, 기존 연결 API·로깅·시간 설정 검증을 포함한다.
143
+ - 변경 Python 파일의 구문·타입 진단을 확인한다. 새로운 타입 검사 도구를 설치하거나 저장소 전체의 기존 진단을 정리하지 않는다.
144
+ - 이 범위의 결과에서 더 넓은 영향이 확인될 때만 관련 검증으로 확대한다. 전체 Worker·프로세스 테스트를 이번 선행 조건으로 삼지 않는다.
145
+ - 설치된 코드가 현재 소스를 가리키는지 먼저 확인한다. 의존성·선택 구현체가 없어서 검증이 실패할 때에만 [기존 개발용 설치 절차](../../../docs/Packaging.md)를 따른다. 이 경우 공통 계약 테스트가 RabbitMQ·Redis를 모두 import한다는 점을 고려하고 기존 선택을 임의로 축소하지 않는다.
146
+
147
+ ### 실제 RabbitMQ 검증
148
+
149
+ 테스트 사용이 허용된 서버에만 접속한다. 기존 `RABBITMQ_PORT` 설정을 이용하며, 테스트를 위해 운영 서버에 큐를 생성하거나 별도 서버를 자동 설치하지 않는다.
150
+
151
+ 다음은 PowerShell에서 opt-in하는 실행 예시이다. 환경변수는 해당 검증 프로세스에서만 설정한다.
152
+
153
+ ```powershell
154
+ $env:RABBITMQ_TESTS = '1'
155
+ python -m unittest tests.rabbitmq.test_rabbitmq_timers.RabbitMQTimerIntegrationTests -v
156
+ ```
157
+
158
+ ### 문서·변경 범위 검증
159
+
160
+ - 한국어·영어 예제와 공개 import·시그니처를 대조하고 상대 링크·코드 펜스를 검사한다.
161
+ - 이슈 문서에는 로컬 절대 경로를 남기지 않는다.
162
+ - `git diff --check`와 변경 파일 목록을 확인한다. 문서 검증과 단위·회귀·실제 브로커 검증 결과는 구분하여 기록한다.
163
+
164
+ ## 진행 상태
165
+
166
+ - [x] 확정 요구사항과 현재 구현·공개 경로·기존 테스트·문서 위치 확인
167
+ - [x] 범위에 맞는 구현·검증 계획 작성
168
+ - [x] 공통 계약·공개 import와 계약 테스트 추가
169
+ - [x] RabbitMQ 등록·취소와 단위 테스트 구현
170
+ - [x] 단위·회귀 검증
171
+ - [ ] 실제 RabbitMQ 검증: 로컬 서버 연결 단계에서 `AMQPConnectionError`
172
+ - [x] 한국어·영어 매뉴얼 갱신
173
+ - [x] 실행 가능한 타이머 샘플 추가와 Stream 샘플 전환·단위 검증
174
+ - [x] 종합 결과·고객 변경 로그 작성
175
+ - [ ] 최종 인수 확인: 실제 RabbitMQ 검증 완료 후 판단
@@ -0,0 +1,69 @@
1
+ # Consumer 소유 스레드 기반 타이머 등록·취소 지원
2
+
3
+ ## 이슈와 작업 상태
4
+
5
+ - 원본: GitHub Issues [#62](https://github.com/yong5eon/DefStream/issues/62)
6
+ - 제목: Consumer 소유 스레드 기반 타이머 등록·취소 지원
7
+ - 상태: Open
8
+ - 유형·레이블: 기능 (`feature`), 원본 이슈에 적용됨
9
+ - 원본 레이블: `feature`, `rabbitmq`
10
+ - 작업 대상: `yong5eon/DefStream`, 작업 브랜치 `feature/62`
11
+ - 분기 기준: `origin/master`와 동일한 로컬 `master`의 `f1bf897`
12
+ - 병합 대상: `master`
13
+ - 로컬 진행 상태: 타이머 구현·실행 샘플·사용 문서 반영, 단위·회귀 45개 통과, 실제 RabbitMQ 검증은 서버 연결 불가
14
+ - 댓글: 없음
15
+
16
+ ## 작업 문서
17
+
18
+ - [요구사항 명세](./REQUIREMENTS.md)
19
+ - [작업 계획](./PLAN.md)
20
+ - [구현 종합](./IMPLEMENTS.md)
21
+ - [작업 종합](./TASKS.md)
22
+ - [변경 로그](./CHANGELOG.md)
23
+ - [최신 구현 기록](./implements/1793778339166.md)
24
+ - [최신 작업 기록](./tasks/1793778440735.md)
25
+
26
+ ## 이슈 원문
27
+
28
+ ## 해결하려는 문제
29
+
30
+ RabbitMQ Consumer로 메시지를 소비하면서, 메시지가 없는 동안에도 연결 유지용 콜백 등을 일정 시간 뒤 실행할 필요가 있습니다.
31
+
32
+ 현재 `Consumer.call(callback)`은 연결 소유 스레드로 콜백을 전달하지만 지연 타이머의 등록·취소 API는 제공하지 않습니다. 따라서 호출자가 Pika의 `BlockingConnection.call_later()`·`remove_timeout()`에 직접 의존하거나 별도 스레드 타이머의 수명주기를 관리해야 합니다.
33
+
34
+ `threading.Timer`에서 직접 출력·소비 중단을 처리하면 메시지 처리와 동시 실행될 수 있고, 타이머 스레드에서 발생한 예외도 소비 루프로 자동 전파되지 않습니다. `Consumer.call()`로 다시 전달할 수는 있지만 타이머 생성·재등록·취소·소비 종료 후 실행 방지는 호출자가 계속 관리해야 합니다.
35
+
36
+ ## 제안하는 해결 방법
37
+
38
+ DefStream의 소비자 API를 통해 소비자 소유 스레드에서 실행되는 타이머를 등록·취소할 수 있게 지원해 주세요. 우선 현재 사용 사례인 RabbitMQ Consumer를 대상으로 합니다.
39
+
40
+ - 지연 시간과 콜백을 지정해 일회성 타이머를 등록하고 취소 가능한 핸들을 반환합니다.
41
+ - 메시지가 없는 소비 대기 중에도 콜백이 소비자 소유 스레드에서 실행되어야 합니다.
42
+ - 반복 실행은 콜백에서 다음 타이머를 재등록하는 방식으로도 충분합니다. 별도 범용 스케줄러나 전용 타이머 스레드는 요구하지 않습니다.
43
+ - 소비 종료·close 시 남은 타이머가 이후에 실행되지 않도록 수명주기를 정리합니다.
44
+ - 콜백 오류는 기존 소비 루프의 오류 처리·전파 방식과 일관되게 드러내며 별도 스레드에서 조용히 유실하지 않습니다.
45
+ - 호출자는 Pika 연결 객체·구현체 타이머 ID를 직접 다루지 않아도 되어야 합니다.
46
+
47
+ 구체적인 메서드 이름과 핸들 타입은 구현 시 기존 인터페이스와 대조해 결정하면 됩니다. 예를 들어 지연 콜백 등록과 해당 핸들 취소 형태를 고려할 수 있으며, 이 예시를 확정 API로 지정하는 것은 아닙니다.
48
+
49
+ ### 확인 기준
50
+
51
+ - 메시지가 없는 동안에도 예약 콜백이 실행되고 메시지 처리와 같은 소유 스레드에서 실행되는지 확인합니다.
52
+ - 취소한 타이머와 소비 종료 후의 타이머가 실행되지 않는지 확인합니다.
53
+ - 재등록을 통한 주기 실행과 정상·오류 종료의 자원 정리를 검증합니다.
54
+ - 콜백 예외가 기존 소비 오류 처리 경계로 전파되는지 확인합니다.
55
+ - 기존 구독·ACK·소비 순서와 `Consumer.call()` 동작을 유지합니다.
56
+ - 지원 범위·시간 단위·실행 지연 가능성·등록 및 취소 사용법을 관련 매뉴얼에 반영합니다.
57
+
58
+ ## 고려한 대안
59
+
60
+ - Pika 연결의 타이머를 직접 사용: 같은 스레드에서 실행할 수 있지만 호출자가 브로커 구현체에 결합됩니다.
61
+ - `threading.Timer`와 `Consumer.call()` 조합: 실행 스레드 전달은 가능하지만 별도 스레드·타이머 수명주기를 호출자가 관리해야 합니다.
62
+ - 메시지를 받을 때만 경과 시간 검사: 유휴 중 실행이 필요한 요구를 충족하지 못합니다.
63
+
64
+ ## 추가 정보
65
+
66
+ 연결 유지용 출력은 사용 예시일 뿐이며 DefStream이 HTTP·SSE 프로토콜이나 해당 출력 내용을 구현해 달라는 요청은 아닙니다. 우선 타이머 등록·취소와 소비자 수명주기 통합만 지원하면 됩니다.
67
+
68
+ - 현재 구현: https://github.com/yong5eon/DefStream/blob/master/src/Broker/Implements/RabbitMQ/Consumer.py
69
+ - Pika BlockingConnection API: https://pika.readthedocs.io/en/stable/modules/adapters/blocking.html