aury-boot 0.0.30__tar.gz → 0.0.32__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 (220) hide show
  1. {aury_boot-0.0.30 → aury_boot-0.0.32}/PKG-INFO +4 -1
  2. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/_version.py +2 -2
  3. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/__init__.py +2 -4
  4. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/app/components.py +2 -0
  5. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/config/settings.py +6 -0
  6. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/AGENTS.md.tpl +54 -0
  7. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/messaging.tpl +21 -13
  8. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/monitoring.tpl +2 -0
  9. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/__init__.py +4 -8
  10. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/channel/__init__.py +9 -8
  11. aury_boot-0.0.32/aury/boot/infrastructure/channel/backends/__init__.py +5 -0
  12. aury_boot-0.0.32/aury/boot/infrastructure/channel/backends/broadcaster.py +141 -0
  13. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/channel/base.py +5 -2
  14. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/channel/manager.py +25 -24
  15. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/__init__.py +4 -6
  16. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/backends/__init__.py +2 -4
  17. aury_boot-0.0.32/aury/boot/infrastructure/events/backends/broadcaster.py +189 -0
  18. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/base.py +9 -4
  19. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/manager.py +24 -20
  20. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/manager.py +2 -0
  21. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/rules.py +16 -0
  22. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/processor.py +31 -1
  23. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/provider.py +2 -0
  24. {aury_boot-0.0.30 → aury_boot-0.0.32}/pyproject.toml +4 -0
  25. aury_boot-0.0.30/aury/boot/infrastructure/channel/backends/__init__.py +0 -9
  26. aury_boot-0.0.30/aury/boot/infrastructure/channel/backends/memory.py +0 -126
  27. aury_boot-0.0.30/aury/boot/infrastructure/channel/backends/redis.py +0 -130
  28. aury_boot-0.0.30/aury/boot/infrastructure/events/backends/memory.py +0 -86
  29. aury_boot-0.0.30/aury/boot/infrastructure/events/backends/redis.py +0 -169
  30. {aury_boot-0.0.30 → aury_boot-0.0.32}/.gitignore +0 -0
  31. {aury_boot-0.0.30 → aury_boot-0.0.32}/README.md +0 -0
  32. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/__init__.py +0 -0
  33. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/__init__.py +0 -0
  34. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/base.py +0 -0
  35. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/config.py +0 -0
  36. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/decorators.py +0 -0
  37. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/exceptions.py +0 -0
  38. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/adapter/http.py +0 -0
  39. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/app/__init__.py +0 -0
  40. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/app/base.py +0 -0
  41. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/app/middlewares.py +0 -0
  42. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/app/startup.py +0 -0
  43. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/config/__init__.py +0 -0
  44. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/config/multi_instance.py +0 -0
  45. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/constants/__init__.py +0 -0
  46. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/constants/components.py +0 -0
  47. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/constants/scheduler.py +0 -0
  48. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/constants/service.py +0 -0
  49. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/__init__.py +0 -0
  50. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/chain.py +0 -0
  51. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/codes.py +0 -0
  52. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/exceptions.py +0 -0
  53. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/handlers.py +0 -0
  54. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/errors/response.py +0 -0
  55. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/interfaces/__init__.py +0 -0
  56. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/interfaces/egress.py +0 -0
  57. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/interfaces/ingress.py +0 -0
  58. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/middleware/__init__.py +0 -0
  59. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/middleware/logging.py +0 -0
  60. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/migrations/__init__.py +0 -0
  61. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/migrations/manager.py +0 -0
  62. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/migrations/setup.py +0 -0
  63. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/rpc/__init__.py +0 -0
  64. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/rpc/base.py +0 -0
  65. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/rpc/client.py +0 -0
  66. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/rpc/discovery.py +0 -0
  67. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/scheduler/__init__.py +0 -0
  68. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/scheduler/runner.py +0 -0
  69. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/application/server/__init__.py +0 -0
  70. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/__init__.py +0 -0
  71. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/add.py +0 -0
  72. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/app.py +0 -0
  73. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/config.py +0 -0
  74. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/docker.py +0 -0
  75. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/docs.py +0 -0
  76. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/generate.py +0 -0
  77. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/init.py +0 -0
  78. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/migrate/__init__.py +0 -0
  79. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/migrate/app.py +0 -0
  80. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/migrate/commands.py +0 -0
  81. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/pkg.py +0 -0
  82. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/scheduler.py +0 -0
  83. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/server/__init__.py +0 -0
  84. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/server/app.py +0 -0
  85. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/generate/api.py.tpl +0 -0
  86. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/generate/model.py.tpl +0 -0
  87. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/generate/repository.py.tpl +0 -0
  88. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/generate/schema.py.tpl +0 -0
  89. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/generate/service.py.tpl +0 -0
  90. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/README.md.tpl +0 -0
  91. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/admin_console_init.py.tpl +0 -0
  92. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/alert_rules.example.yaml.tpl +0 -0
  93. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +0 -0
  94. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +0 -0
  95. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +0 -0
  96. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +0 -0
  97. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +0 -0
  98. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +0 -0
  99. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +0 -0
  100. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +0 -0
  101. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +0 -0
  102. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +0 -0
  103. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +0 -0
  104. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +0 -0
  105. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +0 -0
  106. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +0 -0
  107. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +0 -0
  108. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +0 -0
  109. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +0 -0
  110. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/17-alerting.md.tpl +0 -0
  111. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/aury_docs/99-cli.md.tpl +0 -0
  112. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/config.py.tpl +0 -0
  113. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/conftest.py.tpl +0 -0
  114. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/_header.tpl +0 -0
  115. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/admin.tpl +0 -0
  116. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/cache.tpl +0 -0
  117. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/database.tpl +0 -0
  118. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/log.tpl +0 -0
  119. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/rpc.tpl +0 -0
  120. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/scheduler.tpl +0 -0
  121. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/service.tpl +0 -0
  122. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/storage.tpl +0 -0
  123. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/env_templates/third_party.tpl +0 -0
  124. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/gitignore.tpl +0 -0
  125. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/main.py.tpl +0 -0
  126. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/modules/api.py.tpl +0 -0
  127. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/modules/exceptions.py.tpl +0 -0
  128. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/modules/schedules.py.tpl +0 -0
  129. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/templates/project/modules/tasks.py.tpl +0 -0
  130. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/commands/worker.py +0 -0
  131. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/__init__.py +0 -0
  132. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/exceptions/__init__.py +0 -0
  133. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/i18n/__init__.py +0 -0
  134. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/i18n/translator.py +0 -0
  135. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/logging/__init__.py +0 -0
  136. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/logging/context.py +0 -0
  137. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/logging/decorators.py +0 -0
  138. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/logging/format.py +0 -0
  139. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/common/logging/setup.py +0 -0
  140. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/__init__.py +0 -0
  141. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/admin_console/__init__.py +0 -0
  142. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/admin_console/auth.py +0 -0
  143. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/admin_console/discovery.py +0 -0
  144. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/admin_console/install.py +0 -0
  145. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/contrib/admin_console/utils.py +0 -0
  146. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/__init__.py +0 -0
  147. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/exceptions/__init__.py +0 -0
  148. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/models/__init__.py +0 -0
  149. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/models/base.py +0 -0
  150. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/models/mixins.py +0 -0
  151. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/models/models.py +0 -0
  152. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/pagination/__init__.py +0 -0
  153. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/repository/__init__.py +0 -0
  154. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/repository/impl.py +0 -0
  155. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/repository/interceptors.py +0 -0
  156. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/repository/interface.py +0 -0
  157. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/repository/query_builder.py +0 -0
  158. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/service/__init__.py +0 -0
  159. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/service/base.py +0 -0
  160. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/domain/transaction/__init__.py +0 -0
  161. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/__init__.py +0 -0
  162. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/backends.py +0 -0
  163. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/base.py +0 -0
  164. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/exceptions.py +0 -0
  165. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/factory.py +0 -0
  166. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/cache/manager.py +0 -0
  167. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/__init__.py +0 -0
  168. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/rabbitmq/__init__.py +0 -0
  169. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/rabbitmq/config.py +0 -0
  170. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/rabbitmq/manager.py +0 -0
  171. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/redis/__init__.py +0 -0
  172. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/redis/config.py +0 -0
  173. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/clients/redis/manager.py +0 -0
  174. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/__init__.py +0 -0
  175. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/config.py +0 -0
  176. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/exceptions.py +0 -0
  177. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/manager.py +0 -0
  178. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/query_tools/__init__.py +0 -0
  179. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/database/strategies/__init__.py +0 -0
  180. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/di/__init__.py +0 -0
  181. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/di/container.py +0 -0
  182. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/backends/rabbitmq.py +0 -0
  183. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/events/middleware.py +0 -0
  184. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/__init__.py +0 -0
  185. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/__init__.py +0 -0
  186. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/aggregator.py +0 -0
  187. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/events.py +0 -0
  188. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/notifiers/__init__.py +0 -0
  189. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/notifiers/base.py +0 -0
  190. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/notifiers/feishu.py +0 -0
  191. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/alerting/notifiers/webhook.py +0 -0
  192. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/health/__init__.py +0 -0
  193. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/__init__.py +0 -0
  194. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/context.py +0 -0
  195. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/logging.py +0 -0
  196. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/monitoring/tracing/tracing.py +0 -0
  197. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/__init__.py +0 -0
  198. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/backends/__init__.py +0 -0
  199. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/backends/rabbitmq.py +0 -0
  200. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/backends/redis.py +0 -0
  201. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/base.py +0 -0
  202. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/mq/manager.py +0 -0
  203. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/scheduler/__init__.py +0 -0
  204. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/scheduler/exceptions.py +0 -0
  205. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/scheduler/manager.py +0 -0
  206. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/storage/__init__.py +0 -0
  207. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/storage/base.py +0 -0
  208. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/storage/exceptions.py +0 -0
  209. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/storage/factory.py +0 -0
  210. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/tasks/__init__.py +0 -0
  211. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/tasks/config.py +0 -0
  212. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/tasks/constants.py +0 -0
  213. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/tasks/exceptions.py +0 -0
  214. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/infrastructure/tasks/manager.py +0 -0
  215. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/testing/__init__.py +0 -0
  216. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/testing/base.py +0 -0
  217. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/testing/client.py +0 -0
  218. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/testing/factory.py +0 -0
  219. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/toolkit/__init__.py +0 -0
  220. {aury_boot-0.0.30 → aury_boot-0.0.32}/aury/boot/toolkit/http/__init__.py +0 -0
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.30
3
+ Version: 0.0.32
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: alembic>=1.17.2
7
7
  Requires-Dist: aury-sdk-storage[aws]>=0.0.6
8
8
  Requires-Dist: babel>=2.17.0
9
+ Requires-Dist: broadcaster[redis]>=0.3.1
9
10
  Requires-Dist: faker>=38.2.0
10
11
  Requires-Dist: fastapi>=0.122.0
11
12
  Requires-Dist: greenlet>=3.2.4
@@ -30,6 +31,8 @@ Requires-Dist: aury-sdk-storage[aws]>=0.0.1; extra == 'all'
30
31
  Requires-Dist: dramatiq>=1.18.0; extra == 'all'
31
32
  Requires-Dist: pika>=1.3.2; extra == 'all'
32
33
  Requires-Dist: redis>=7.1.0; extra == 'all'
34
+ Provides-Extra: broadcaster
35
+ Requires-Dist: broadcaster[redis]>=0.3.1; extra == 'broadcaster'
33
36
  Provides-Extra: dev
34
37
  Requires-Dist: mypy>=1.19.0; extra == 'dev'
35
38
  Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.30'
32
- __version_tuple__ = version_tuple = (0, 0, 30)
31
+ __version__ = version = '0.0.32'
32
+ __version_tuple__ = version_tuple = (0, 0, 32)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -24,6 +24,7 @@ from aury.boot.domain.transaction import (
24
24
  # 依赖注入容器(从 infrastructure 导入)
25
25
  from aury.boot.infrastructure.di import Container, Lifetime, Scope, ServiceDescriptor
26
26
  from aury.boot.infrastructure.events import (
27
+ BroadcasterEventBus,
27
28
  Event,
28
29
  EventBackend,
29
30
  EventBusManager,
@@ -31,9 +32,7 @@ from aury.boot.infrastructure.events import (
31
32
  EventType,
32
33
  IEventBus,
33
34
  # 后端实现
34
- MemoryEventBus,
35
35
  RabbitMQEventBus,
36
- RedisEventBus,
37
36
  )
38
37
 
39
38
  from . import interfaces, rpc
@@ -108,14 +107,13 @@ __all__ = [
108
107
  "IEventBus",
109
108
  "Lifetime",
110
109
  "LogSettings",
111
- "MemoryEventBus",
110
+ "BroadcasterEventBus",
112
111
  "Middleware",
113
112
  "MiddlewareName",
114
113
  "MigrationComponent",
115
114
  # 迁移
116
115
  "MigrationManager",
117
116
  "RabbitMQEventBus",
118
- "RedisEventBus",
119
117
  "RequestLoggingMiddleware",
120
118
  "SchedulerComponent",
121
119
  "SchedulerMode",
@@ -628,6 +628,7 @@ class TelemetryPlugin(Plugin):
628
628
  alert_on_slow_sql=config.alert.alert_on_slow_sql,
629
629
  alert_on_error=config.alert.alert_on_error,
630
630
  alert_callback=alert_callback,
631
+ slow_request_exclude_paths=config.alert.slow_request_exclude_paths,
631
632
  traces_endpoint=config.telemetry.traces_endpoint,
632
633
  traces_headers=config.telemetry.traces_headers,
633
634
  logs_endpoint=config.telemetry.logs_endpoint,
@@ -753,6 +754,7 @@ class AlertComponent(Component):
753
754
  "slow_sql_aggregate": config.alert.slow_sql_aggregate,
754
755
  "exception_aggregate": config.alert.exception_aggregate,
755
756
  "suppress_seconds": config.alert.suppress_seconds,
757
+ "slow_request_exclude_paths": config.alert.slow_request_exclude_paths,
756
758
  },
757
759
  notifiers=config.alert.get_notifiers(),
758
760
  )
@@ -696,6 +696,12 @@ class AlertSettings(BaseModel):
696
696
  description="是否对异常发送告警(默认只对 5xx 告警,4xx 业务异常不告警)"
697
697
  )
698
698
 
699
+ # 慢请求路径排除配置
700
+ slow_request_exclude_paths: list[str] = Field(
701
+ default_factory=list,
702
+ description="排除慢请求告警的路径列表(支持 * 通配符),如 SSE/WebSocket 长连接接口"
703
+ )
704
+
699
705
  # 默认累计触发配置
700
706
  aggregate_window: int = Field(
701
707
  default=10,
@@ -127,6 +127,60 @@ mypy {package_name}/
127
127
  - **[aury_docs/99-cli.md](./aury_docs/99-cli.md)** - CLI 命令参考
128
128
  - **[.env.example](./.env.example)** - 所有可用环境变量
129
129
 
130
+ ## 配置结构
131
+
132
+ 框架使用 `BaseConfig` 统一管理配置,环境变量通过 `__` 分隔符映射到嵌套配置:
133
+
134
+ ```python
135
+ # 配置结构(BaseConfig)
136
+ class BaseConfig(BaseSettings):
137
+ # 基础服务
138
+ server: ServerSettings # SERVER__*
139
+ cors: CORSSettings # CORS__*
140
+ log: LogSettings # LOG__*
141
+ health_check: HealthCheckSettings # HEALTH_CHECK__*
142
+ admin: AdminConsoleSettings # ADMIN__*
143
+
144
+ # 数据与缓存
145
+ database: DatabaseSettings # DATABASE__*
146
+ cache: CacheSettings # CACHE__*
147
+ channel: ChannelSettings # CHANNEL__*
148
+ storage: StorageSettings # STORAGE__*
149
+ migration: MigrationSettings # MIGRATION__*
150
+
151
+ # 服务编排
152
+ service: ServiceSettings # SERVICE__*
153
+ scheduler: SchedulerSettings # SCHEDULER__*
154
+
155
+ # 异步与事件
156
+ task: TaskSettings # TASK__*
157
+ event: EventSettings # EVENT__*
158
+
159
+ # 微服务通信
160
+ rpc_client: RPCClientSettings # RPC_CLIENT__*
161
+ rpc_service: RPCServiceSettings # RPC_SERVICE__*
162
+
163
+ # 监控告警
164
+ telemetry: TelemetrySettings # TELEMETRY__*
165
+ alert: AlertSettings # ALERT__*
166
+
167
+ model_config = SettingsConfigDict(
168
+ env_nested_delimiter="__", # 环境变量分隔符
169
+ )
170
+ ```
171
+
172
+ **环境变量命名规则**:`{SECTION}__{FIELD}`
173
+
174
+ ```bash
175
+ # 示例
176
+ DATABASE__URL=postgresql://...
177
+ DATABASE__POOL_SIZE=10
178
+ CACHE__CACHE_TYPE=redis
179
+ CACHE__URL=redis://localhost:6379
180
+ ALERT__ENABLED=true
181
+ ALERT__SLOW_REQUEST_THRESHOLD=1.0
182
+ ```
183
+
130
184
  ## 代码规范
131
185
 
132
186
  > 项目所有业务配置请通过应用 `settings`/配置对象获取,**不要**直接使用 `os.environ` 在业务代码中读环境变量。
@@ -2,14 +2,18 @@
2
2
  # =============================================================================
3
3
  # 流式通道配置 (CHANNEL__) - SSE/实时通信
4
4
  # =============================================================================
5
+ # 基于 Broadcaster 库,通过 URL scheme 切换后端
6
+ # 支持: memory:// | redis://host:port/db | kafka://host:port | postgres://...
7
+ #
5
8
  # 单实例配置:
6
- # CHANNEL__BACKEND=memory
7
- # CHANNEL__BACKEND=redis
8
- # CHANNEL__URL=redis://localhost:6379/3
9
+ # CHANNEL__BACKEND=broadcaster
10
+ # CHANNEL__URL=memory://
11
+ # 分布式: CHANNEL__URL=redis://localhost:6379/3
9
12
  #
10
13
  # 多实例配置 (格式: CHANNEL__{{INSTANCE}}__{{FIELD}}):
11
- # CHANNEL__SSE__BACKEND=memory
12
- # CHANNEL__NOTIFICATION__BACKEND=redis
14
+ # CHANNEL__SSE__BACKEND=broadcaster
15
+ # CHANNEL__SSE__URL=memory://
16
+ # CHANNEL__NOTIFICATION__BACKEND=broadcaster
13
17
  # CHANNEL__NOTIFICATION__URL=redis://localhost:6379/3
14
18
 
15
19
  # =============================================================================
@@ -32,18 +36,22 @@
32
36
  # =============================================================================
33
37
  # 事件总线配置 (EVENT__)
34
38
  # =============================================================================
39
+ # 基于 Broadcaster 库,通过 URL scheme 切换后端
40
+ # 支持: memory:// | redis://host:port/db | kafka://host:port | postgres://...
41
+ # RabbitMQ 需使用 backend=rabbitmq
42
+ #
35
43
  # 单实例配置:
36
- # EVENT__BROKER_URL=
37
- # EVENT__EXCHANGE_NAME=aury.events
38
-
44
+ # EVENT__BACKEND=broadcaster
45
+ # EVENT__URL=memory://
46
+ # 分布式: EVENT__URL=redis://localhost:6379/5
47
+ #
39
48
  # 多实例配置 (格式: EVENT__{{INSTANCE}}__{{FIELD}}):
40
- # EVENT__DEFAULT__BACKEND=memory
41
- # EVENT__DISTRIBUTED__BACKEND=redis
49
+ # EVENT__DEFAULT__BACKEND=broadcaster
50
+ # EVENT__DEFAULT__URL=memory://
51
+ # EVENT__DISTRIBUTED__BACKEND=broadcaster
42
52
  # EVENT__DISTRIBUTED__URL=redis://localhost:6379/5
43
- # EVENT__DISTRIBUTED__KEY_PREFIX=events:
44
53
  #
45
- # RabbitMQ 后端:
54
+ # RabbitMQ 后端 (复杂消息场景):
46
55
  # EVENT__DOMAIN__BACKEND=rabbitmq
47
56
  # EVENT__DOMAIN__URL=amqp://guest:guest@localhost:5672/
48
57
  # EVENT__DOMAIN__EXCHANGE_NAME=domain.events
49
- # EVENT__DOMAIN__EXCHANGE_TYPE=topic
@@ -21,6 +21,8 @@ ALERT__SLOW_SQL_THRESHOLD=0.5
21
21
  ALERT__ALERT_ON_SLOW_REQUEST=true
22
22
  ALERT__ALERT_ON_SLOW_SQL=true
23
23
  ALERT__ALERT_ON_ERROR=true
24
+ # 慢请求排除路径(SSE/WebSocket 等长连接接口,支持 * 通配符)
25
+ # ALERT__SLOW_REQUEST_EXCLUDE_PATHS=["*/subscribe", "*/ws", "*/stream"]
24
26
  # 聚合与抑制
25
27
  ALERT__AGGREGATE_WINDOW=10
26
28
  ALERT__SLOW_REQUEST_AGGREGATE=5
@@ -27,12 +27,11 @@ from .cache import (
27
27
 
28
28
  # 通道 (SSE/PubSub)
29
29
  from .channel import (
30
+ BroadcasterChannel,
30
31
  ChannelBackend,
31
32
  ChannelManager,
32
33
  ChannelMessage,
33
34
  IChannel,
34
- MemoryChannel,
35
- RedisChannel,
36
35
  )
37
36
 
38
37
  # RabbitMQ 客户端
@@ -47,15 +46,14 @@ from .di import Container, Lifetime, Scope, ServiceDescriptor
47
46
 
48
47
  # 事件总线
49
48
  from .events import (
49
+ BroadcasterEventBus,
50
50
  Event,
51
51
  EventBackend,
52
52
  EventBusManager,
53
53
  EventHandler,
54
54
  EventType,
55
55
  IEventBus,
56
- MemoryEventBus,
57
56
  RabbitMQEventBus,
58
- RedisEventBus,
59
57
  )
60
58
 
61
59
  # 消息队列
@@ -103,6 +101,7 @@ __all__ = [
103
101
  "CacheFactory",
104
102
  "CacheManager",
105
103
  # 通道
104
+ "BroadcasterChannel",
106
105
  "ChannelBackend",
107
106
  "ChannelManager",
108
107
  "ChannelMessage",
@@ -128,19 +127,16 @@ __all__ = [
128
127
  "MQMessage",
129
128
  "MemcachedCache",
130
129
  "MemoryCache",
131
- "MemoryChannel",
132
- "MemoryEventBus",
133
130
  "RabbitMQ",
134
131
  # RabbitMQ 客户端
135
132
  "RabbitMQClient",
136
133
  "RabbitMQConfig",
137
134
  "RabbitMQEventBus",
135
+ "BroadcasterEventBus",
138
136
  "RedisCache",
139
- "RedisChannel",
140
137
  # Redis 客户端
141
138
  "RedisClient",
142
139
  "RedisConfig",
143
- "RedisEventBus",
144
140
  "RedisMQ",
145
141
  "S3Storage",
146
142
  # 调度器
@@ -2,23 +2,24 @@
2
2
 
3
3
  提供发布/订阅模式的通道功能,用于 SSE、WebSocket 等实时通信场景。
4
4
 
5
- 支持的后端:
6
- - memory: 内存通道(单进程)
7
- - redis: Redis Pub/Sub(多进程/多实例)
5
+ 支持的后端(通过 Broadcaster 库):
6
+ - memory:// - 内存通道(单进程,开发/测试用)
7
+ - redis:// - Redis Pub/Sub(多进程/分布式)
8
+ - kafka:// - Apache Kafka
9
+ - postgres:// - PostgreSQL LISTEN/NOTIFY
8
10
  """
9
11
 
10
- from .backends import MemoryChannel, RedisChannel
12
+ from .backends import BroadcasterChannel
11
13
  from .base import ChannelBackend, ChannelMessage, IChannel
12
14
  from .manager import ChannelManager
13
15
 
14
16
  __all__ = [
15
17
  # 接口和类型
16
18
  "ChannelBackend",
17
- # 管理器
18
- "ChannelManager",
19
19
  "ChannelMessage",
20
20
  "IChannel",
21
+ # 管理器
22
+ "ChannelManager",
21
23
  # 后端实现
22
- "MemoryChannel",
23
- "RedisChannel",
24
+ "BroadcasterChannel",
24
25
  ]
@@ -0,0 +1,5 @@
1
+ """通道后端实现。"""
2
+
3
+ from .broadcaster import BroadcasterChannel
4
+
5
+ __all__ = ["BroadcasterChannel"]
@@ -0,0 +1,141 @@
1
+ """Broadcaster 通道后端。
2
+
3
+ 基于 Broadcaster 库实现,支持多种后端:
4
+ - memory:// - 内存(单进程,开发/测试用)
5
+ - redis:// - Redis Pub/Sub(多进程/分布式)
6
+ - kafka:// - Apache Kafka
7
+ - postgres:// - PostgreSQL LISTEN/NOTIFY
8
+
9
+ 优势:
10
+ - 共享连接池,支持成千上万并发订阅
11
+ - 自动重连机制
12
+ - 统一 API,通过 URL scheme 切换后端
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ from collections.abc import AsyncIterator
19
+ from datetime import datetime
20
+
21
+ from broadcaster import Broadcast
22
+
23
+ from aury.boot.common.logging import logger
24
+
25
+ from ..base import ChannelMessage, IChannel
26
+
27
+
28
+ class BroadcasterChannel(IChannel):
29
+ """Broadcaster 通道实现。
30
+
31
+ 使用 Broadcaster 库统一处理多种后端,解决原生实现的连接池问题:
32
+ - 共享单个连接处理所有订阅
33
+ - 内部通过 asyncio.Queue 分发消息
34
+ - 支持成千上万并发订阅者
35
+ """
36
+
37
+ def __init__(self, url: str) -> None:
38
+ """初始化 Broadcaster 通道。
39
+
40
+ Args:
41
+ url: 连接 URL,支持的 scheme:
42
+ - memory:// - 内存后端
43
+ - redis://host:port/db - Redis Pub/Sub
44
+ - kafka://host:port - Apache Kafka
45
+ - postgres://user:pass@host:port/db - PostgreSQL
46
+ """
47
+ self._url = url
48
+ self._broadcast = Broadcast(url)
49
+ self._connected = False
50
+
51
+ async def _ensure_connected(self) -> None:
52
+ """确保已连接。"""
53
+ if not self._connected:
54
+ await self._broadcast.connect()
55
+ self._connected = True
56
+ logger.debug(f"Broadcaster 通道已连接: {self._mask_url(self._url)}")
57
+
58
+ def _mask_url(self, url: str) -> str:
59
+ """URL 脱敏(隐藏密码)。"""
60
+ if "@" in url:
61
+ parts = url.split("@")
62
+ prefix = parts[0]
63
+ suffix = parts[1]
64
+ if ":" in prefix:
65
+ scheme_and_user = prefix.rsplit(":", 1)[0]
66
+ return f"{scheme_and_user}:***@{suffix}"
67
+ return url
68
+
69
+ async def publish(self, channel: str, message: ChannelMessage) -> None:
70
+ """发布消息到通道。"""
71
+ await self._ensure_connected()
72
+
73
+ message.channel = channel
74
+ # 序列化消息
75
+ data = {
76
+ "data": message.data,
77
+ "event": message.event,
78
+ "id": message.id,
79
+ "channel": message.channel,
80
+ "timestamp": message.timestamp.isoformat(),
81
+ }
82
+ await self._broadcast.publish(channel=channel, message=json.dumps(data))
83
+
84
+ async def subscribe(self, channel: str) -> AsyncIterator[ChannelMessage]:
85
+ """订阅通道。
86
+
87
+ Broadcaster 内部共享连接,每个订阅者不会创建新的连接。
88
+ """
89
+ await self._ensure_connected()
90
+
91
+ async with self._broadcast.subscribe(channel=channel) as subscriber:
92
+ async for event in subscriber:
93
+ try:
94
+ data = json.loads(event.message)
95
+ message = ChannelMessage(
96
+ data=data.get("data"),
97
+ event=data.get("event"),
98
+ id=data.get("id"),
99
+ channel=data.get("channel") or channel,
100
+ timestamp=datetime.fromisoformat(data["timestamp"])
101
+ if data.get("timestamp")
102
+ else datetime.now(),
103
+ )
104
+ yield message
105
+ except (json.JSONDecodeError, KeyError, TypeError) as e:
106
+ logger.warning(f"解析通道消息失败: {e}")
107
+
108
+ async def psubscribe(self, pattern: str) -> AsyncIterator[ChannelMessage]:
109
+ """模式订阅(通配符)。
110
+
111
+ 注意:Broadcaster 目前不支持模式订阅,此方法会抛出 NotImplementedError。
112
+ 如需模式订阅,请使用具体的 channel 名称。
113
+
114
+ Args:
115
+ pattern: 通道模式
116
+
117
+ Raises:
118
+ NotImplementedError: Broadcaster 不支持模式订阅
119
+ """
120
+ raise NotImplementedError(
121
+ "Broadcaster 后端不支持模式订阅 (psubscribe)。"
122
+ "请使用具体的 channel 名称。"
123
+ )
124
+
125
+ async def unsubscribe(self, channel: str) -> None:
126
+ """取消订阅通道。
127
+
128
+ 注意:Broadcaster 的订阅通过上下文管理器自动处理,
129
+ 退出 subscribe() 的 async for 循环即可取消订阅。
130
+ """
131
+ pass
132
+
133
+ async def close(self) -> None:
134
+ """关闭通道。"""
135
+ if self._connected:
136
+ await self._broadcast.disconnect()
137
+ self._connected = False
138
+ logger.debug("Broadcaster 通道已关闭")
139
+
140
+
141
+ __all__ = ["BroadcasterChannel"]
@@ -16,8 +16,11 @@ from typing import Any
16
16
  class ChannelBackend(Enum):
17
17
  """通道后端类型。"""
18
18
 
19
- MEMORY = "memory"
20
- REDIS = "redis"
19
+ # Broadcaster 统一后端(支持 memory/redis/kafka/postgres,通过 URL scheme 区分)
20
+ BROADCASTER = "broadcaster"
21
+ # 未来扩展
22
+ RABBITMQ = "rabbitmq"
23
+ ROCKETMQ = "rocketmq"
21
24
 
22
25
 
23
26
  @dataclass
@@ -9,8 +9,7 @@ from collections.abc import AsyncIterator
9
9
 
10
10
  from aury.boot.common.logging import logger
11
11
 
12
- from .backends.memory import MemoryChannel
13
- from .backends.redis import RedisChannel
12
+ from .backends.broadcaster import BroadcasterChannel
14
13
  from .base import ChannelBackend, ChannelMessage, IChannel
15
14
 
16
15
 
@@ -51,7 +50,6 @@ class ChannelManager:
51
50
  self._backend: IChannel | None = None
52
51
  self._backend_type: ChannelBackend | None = None
53
52
  self._initialized: bool = False
54
- self._redis_client = None
55
53
  self._url: str | None = None
56
54
 
57
55
  @classmethod
@@ -84,17 +82,19 @@ class ChannelManager:
84
82
 
85
83
  async def initialize(
86
84
  self,
87
- backend: ChannelBackend | str = ChannelBackend.MEMORY,
85
+ backend: ChannelBackend | str = ChannelBackend.BROADCASTER,
88
86
  *,
89
- url: str | None = None,
90
- max_subscribers: int = 1000,
87
+ url: str = "memory://",
91
88
  ) -> ChannelManager:
92
89
  """初始化通道(链式调用)。
93
90
 
94
91
  Args:
95
- backend: 后端类型
96
- url: Redis 连接 URL(当 backend=redis 时需要)
97
- max_subscribers: 内存后端的最大订阅者数量
92
+ backend: 后端类型,默认 broadcaster
93
+ url: 连接 URL,支持:
94
+ - memory:// - 内存后端(单进程,默认)
95
+ - redis://host:port/db - Redis Pub/Sub
96
+ - kafka://host:port - Apache Kafka
97
+ - postgres://user:pass@host/db - PostgreSQL
98
98
 
99
99
  Returns:
100
100
  self: 支持链式调用
@@ -110,24 +110,28 @@ class ChannelManager:
110
110
  self._backend_type = backend
111
111
  self._url = url
112
112
 
113
- if backend == ChannelBackend.MEMORY:
114
- self._backend = MemoryChannel(max_subscribers=max_subscribers)
115
- elif backend == ChannelBackend.REDIS:
116
- if url is None:
117
- raise ValueError("Redis 通道需要提供 url 参数")
118
- # 内部创建 RedisClient
119
- from aury.boot.infrastructure.clients.redis import RedisClient
120
-
121
- self._redis_client = RedisClient()
122
- await self._redis_client.configure(url=url).initialize()
123
- self._backend = RedisChannel(self._redis_client)
113
+ if backend == ChannelBackend.BROADCASTER:
114
+ self._backend = BroadcasterChannel(url)
115
+ elif backend in (ChannelBackend.RABBITMQ, ChannelBackend.ROCKETMQ):
116
+ raise NotImplementedError(f"{backend.value} 后端暂未实现")
124
117
  else:
125
118
  raise ValueError(f"不支持的通道后端: {backend}")
126
119
 
127
120
  self._initialized = True
128
- logger.info(f"通道管理器 [{self.name}] 初始化完成: {backend.value}")
121
+ logger.info(f"通道管理器 [{self.name}] 初始化完成: {backend.value}, url={self._mask_url(url)}")
129
122
  return self
130
123
 
124
+ def _mask_url(self, url: str) -> str:
125
+ """URL 脱敏(隐藏密码)。"""
126
+ if "@" in url:
127
+ parts = url.split("@")
128
+ prefix = parts[0]
129
+ suffix = parts[1]
130
+ if ":" in prefix:
131
+ scheme_and_user = prefix.rsplit(":", 1)[0]
132
+ return f"{scheme_and_user}:***@{suffix}"
133
+ return url
134
+
131
135
  @property
132
136
  def backend(self) -> IChannel:
133
137
  """获取通道后端。"""
@@ -218,9 +222,6 @@ class ChannelManager:
218
222
  if self._backend:
219
223
  await self._backend.close()
220
224
  self._backend = None
221
- if self._redis_client:
222
- await self._redis_client.cleanup()
223
- self._redis_client = None
224
225
  self._initialized = False
225
226
  logger.info(f"通道管理器 [{self.name}] 已关闭")
226
227
 
@@ -3,12 +3,11 @@
3
3
  提供发布/订阅模式的事件总线功能,用于模块间解耦通信。
4
4
 
5
5
  支持的后端:
6
- - memory: 内存事件总线(单进程)
7
- - redis: Redis Pub/Sub(多进程/多实例)
8
- - rabbitmq: RabbitMQ Exchange(分布式)
6
+ - broadcaster: 基于 broadcaster 库(推荐,支持 memory/redis/kafka/postgres)
7
+ - rabbitmq: RabbitMQ Exchange(复杂消息场景)
9
8
  """
10
9
 
11
- from .backends import MemoryEventBus, RabbitMQEventBus, RedisEventBus
10
+ from .backends import BroadcasterEventBus, RabbitMQEventBus
12
11
  from .base import Event, EventBackend, EventHandler, EventType, IEventBus
13
12
  from .manager import EventBusManager
14
13
 
@@ -22,9 +21,8 @@ __all__ = [
22
21
  "EventType",
23
22
  "IEventBus",
24
23
  # 后端实现
25
- "MemoryEventBus",
24
+ "BroadcasterEventBus",
26
25
  "RabbitMQEventBus",
27
- "RedisEventBus",
28
26
  ]
29
27
 
30
28
 
@@ -1,11 +1,9 @@
1
1
  """事件总线后端实现。"""
2
2
 
3
- from .memory import MemoryEventBus
3
+ from .broadcaster import BroadcasterEventBus
4
4
  from .rabbitmq import RabbitMQEventBus
5
- from .redis import RedisEventBus
6
5
 
7
6
  __all__ = [
8
- "MemoryEventBus",
7
+ "BroadcasterEventBus",
9
8
  "RabbitMQEventBus",
10
- "RedisEventBus",
11
9
  ]