aury-boot 0.0.4__py3-none-any.whl → 0.0.7__py3-none-any.whl
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.
- aury/boot/__init__.py +2 -2
- aury/boot/_version.py +2 -2
- aury/boot/application/__init__.py +60 -36
- aury/boot/application/adapter/__init__.py +112 -0
- aury/boot/application/adapter/base.py +511 -0
- aury/boot/application/adapter/config.py +242 -0
- aury/boot/application/adapter/decorators.py +259 -0
- aury/boot/application/adapter/exceptions.py +202 -0
- aury/boot/application/adapter/http.py +325 -0
- aury/boot/application/app/__init__.py +12 -8
- aury/boot/application/app/base.py +12 -0
- aury/boot/application/app/components.py +137 -44
- aury/boot/application/app/middlewares.py +9 -4
- aury/boot/application/app/startup.py +249 -0
- aury/boot/application/config/__init__.py +36 -1
- aury/boot/application/config/multi_instance.py +216 -0
- aury/boot/application/config/settings.py +398 -149
- aury/boot/application/constants/components.py +6 -0
- aury/boot/application/errors/handlers.py +17 -3
- aury/boot/application/middleware/logging.py +21 -120
- aury/boot/application/rpc/__init__.py +2 -2
- aury/boot/commands/__init__.py +30 -10
- aury/boot/commands/app.py +131 -1
- aury/boot/commands/docs.py +104 -17
- aury/boot/commands/generate.py +22 -22
- aury/boot/commands/init.py +68 -17
- aury/boot/commands/server/app.py +2 -3
- aury/boot/commands/templates/project/AGENTS.md.tpl +221 -0
- aury/boot/commands/templates/project/README.md.tpl +2 -2
- aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +59 -0
- aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +184 -0
- aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +206 -0
- aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +398 -0
- aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +95 -0
- aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +116 -0
- aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +118 -0
- aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +122 -0
- aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +32 -0
- aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +38 -0
- aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +115 -0
- aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +131 -0
- aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +56 -0
- aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +104 -0
- aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +102 -0
- aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +147 -0
- aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +403 -0
- aury/boot/commands/templates/project/{CLI.md.tpl → aury_docs/99-cli.md.tpl} +19 -19
- aury/boot/commands/templates/project/config.py.tpl +10 -10
- aury/boot/commands/templates/project/env_templates/_header.tpl +10 -0
- aury/boot/commands/templates/project/env_templates/admin.tpl +49 -0
- aury/boot/commands/templates/project/env_templates/cache.tpl +14 -0
- aury/boot/commands/templates/project/env_templates/database.tpl +22 -0
- aury/boot/commands/templates/project/env_templates/log.tpl +18 -0
- aury/boot/commands/templates/project/env_templates/messaging.tpl +46 -0
- aury/boot/commands/templates/project/env_templates/rpc.tpl +28 -0
- aury/boot/commands/templates/project/env_templates/scheduler.tpl +18 -0
- aury/boot/commands/templates/project/env_templates/service.tpl +18 -0
- aury/boot/commands/templates/project/env_templates/storage.tpl +38 -0
- aury/boot/commands/templates/project/env_templates/third_party.tpl +43 -0
- aury/boot/commands/templates/project/modules/tasks.py.tpl +1 -1
- aury/boot/common/logging/__init__.py +26 -674
- aury/boot/common/logging/context.py +132 -0
- aury/boot/common/logging/decorators.py +118 -0
- aury/boot/common/logging/format.py +315 -0
- aury/boot/common/logging/setup.py +214 -0
- aury/boot/contrib/admin_console/auth.py +2 -3
- aury/boot/contrib/admin_console/install.py +1 -1
- aury/boot/domain/models/mixins.py +48 -1
- aury/boot/domain/pagination/__init__.py +94 -0
- aury/boot/domain/repository/impl.py +1 -1
- aury/boot/domain/repository/interface.py +1 -1
- aury/boot/domain/transaction/__init__.py +8 -9
- aury/boot/infrastructure/__init__.py +86 -29
- aury/boot/infrastructure/cache/backends.py +102 -18
- aury/boot/infrastructure/cache/base.py +12 -0
- aury/boot/infrastructure/cache/manager.py +153 -91
- aury/boot/infrastructure/channel/__init__.py +24 -0
- aury/boot/infrastructure/channel/backends/__init__.py +9 -0
- aury/boot/infrastructure/channel/backends/memory.py +83 -0
- aury/boot/infrastructure/channel/backends/redis.py +88 -0
- aury/boot/infrastructure/channel/base.py +92 -0
- aury/boot/infrastructure/channel/manager.py +203 -0
- aury/boot/infrastructure/clients/__init__.py +22 -0
- aury/boot/infrastructure/clients/rabbitmq/__init__.py +9 -0
- aury/boot/infrastructure/clients/rabbitmq/config.py +46 -0
- aury/boot/infrastructure/clients/rabbitmq/manager.py +288 -0
- aury/boot/infrastructure/clients/redis/__init__.py +28 -0
- aury/boot/infrastructure/clients/redis/config.py +51 -0
- aury/boot/infrastructure/clients/redis/manager.py +264 -0
- aury/boot/infrastructure/database/config.py +7 -16
- aury/boot/infrastructure/database/manager.py +16 -38
- aury/boot/infrastructure/events/__init__.py +18 -21
- aury/boot/infrastructure/events/backends/__init__.py +11 -0
- aury/boot/infrastructure/events/backends/memory.py +86 -0
- aury/boot/infrastructure/events/backends/rabbitmq.py +193 -0
- aury/boot/infrastructure/events/backends/redis.py +162 -0
- aury/boot/infrastructure/events/base.py +127 -0
- aury/boot/infrastructure/events/manager.py +224 -0
- aury/boot/infrastructure/mq/__init__.py +24 -0
- aury/boot/infrastructure/mq/backends/__init__.py +9 -0
- aury/boot/infrastructure/mq/backends/rabbitmq.py +179 -0
- aury/boot/infrastructure/mq/backends/redis.py +167 -0
- aury/boot/infrastructure/mq/base.py +143 -0
- aury/boot/infrastructure/mq/manager.py +239 -0
- aury/boot/infrastructure/scheduler/manager.py +7 -3
- aury/boot/infrastructure/storage/__init__.py +9 -9
- aury/boot/infrastructure/storage/base.py +17 -5
- aury/boot/infrastructure/storage/factory.py +0 -1
- aury/boot/infrastructure/tasks/__init__.py +2 -2
- aury/boot/infrastructure/tasks/config.py +5 -13
- aury/boot/infrastructure/tasks/manager.py +55 -33
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/METADATA +20 -2
- aury_boot-0.0.7.dist-info/RECORD +197 -0
- aury/boot/commands/templates/project/DEVELOPMENT.md.tpl +0 -1397
- aury/boot/commands/templates/project/env.example.tpl +0 -213
- aury/boot/infrastructure/events/bus.py +0 -362
- aury/boot/infrastructure/events/config.py +0 -52
- aury/boot/infrastructure/events/consumer.py +0 -134
- aury/boot/infrastructure/events/models.py +0 -63
- aury_boot-0.0.4.dist-info/RECORD +0 -137
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/WHEEL +0 -0
- {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# 流式通道(Channel)
|
|
2
|
+
|
|
3
|
+
用于 SSE(Server-Sent Events)和实时通信。支持 memory 和 redis 后端。
|
|
4
|
+
|
|
5
|
+
## 核心概念
|
|
6
|
+
|
|
7
|
+
- **ChannelManager**:管理器,支持命名多实例(如 sse、notification 独立管理)
|
|
8
|
+
- **channel 参数**:通道名/Topic,用于区分不同的消息流(如 `user:123`、`order:456`)
|
|
9
|
+
|
|
10
|
+
## 13.1 基本用法
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from aury.boot.infrastructure.channel import ChannelManager
|
|
14
|
+
|
|
15
|
+
# 命名多实例(推荐)- 不同业务场景使用不同实例
|
|
16
|
+
sse_channel = ChannelManager.get_instance("sse")
|
|
17
|
+
notification_channel = ChannelManager.get_instance("notification")
|
|
18
|
+
|
|
19
|
+
# Memory 后端(单进程)
|
|
20
|
+
await sse_channel.initialize(backend="memory")
|
|
21
|
+
|
|
22
|
+
# Redis 后端(多进程/分布式)
|
|
23
|
+
from aury.boot.infrastructure.clients.redis import RedisClient
|
|
24
|
+
redis_client = RedisClient.get_instance()
|
|
25
|
+
await redis_client.initialize(url="redis://localhost:6379/0")
|
|
26
|
+
await notification_channel.initialize(backend="redis", redis_client=redis_client)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 13.2 发布和订阅(Topic 管理)
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
# 发布消息到指定 Topic
|
|
33
|
+
await sse_channel.publish("user:123", {{"event": "message", "data": "hello"}})
|
|
34
|
+
await sse_channel.publish("order:456", {{"status": "shipped"}})
|
|
35
|
+
|
|
36
|
+
# 发布到多个用户
|
|
37
|
+
for user_id in user_ids:
|
|
38
|
+
await sse_channel.publish(f"user:{{user_id}}", notification)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 13.3 SSE 端点示例
|
|
42
|
+
|
|
43
|
+
**文件**: `{package_name}/api/sse.py`
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import json
|
|
47
|
+
from fastapi import APIRouter
|
|
48
|
+
from fastapi.responses import StreamingResponse
|
|
49
|
+
from aury.boot.infrastructure.channel import ChannelManager
|
|
50
|
+
|
|
51
|
+
router = APIRouter(tags=["SSE"])
|
|
52
|
+
|
|
53
|
+
# 获取命名实例(在 app 启动时已初始化)
|
|
54
|
+
sse_channel = ChannelManager.get_instance("sse")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@router.get("/sse/{{user_id}}")
|
|
58
|
+
async def sse_stream(user_id: str):
|
|
59
|
+
\"\"\"SSE 实时消息流。\"\"\"
|
|
60
|
+
async def event_generator():
|
|
61
|
+
# user_id 作为 Topic,区分不同用户的消息流
|
|
62
|
+
async for message in sse_channel.subscribe(f"user:{{user_id}}"):
|
|
63
|
+
yield f"data: {{json.dumps(message)}}\n\n"
|
|
64
|
+
|
|
65
|
+
return StreamingResponse(
|
|
66
|
+
event_generator(),
|
|
67
|
+
media_type="text/event-stream",
|
|
68
|
+
headers={{"Cache-Control": "no-cache", "Connection": "keep-alive"}}
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@router.post("/notify/{{user_id}}")
|
|
73
|
+
async def send_notification(user_id: str, message: str):
|
|
74
|
+
\"\"\"\u53d1\u9001\u901a\u77e5\u3002\"\"\"
|
|
75
|
+
await sse_channel.publish(f"user:{{user_id}}", {{"message": message}})
|
|
76
|
+
return {{"status": "sent"}}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## 13.4 应用场景示例
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
# 不同业务场景使用不同的命名实例
|
|
83
|
+
sse_channel = ChannelManager.get_instance("sse") # 前端 SSE 推送
|
|
84
|
+
chat_channel = ChannelManager.get_instance("chat") # 聊天消息
|
|
85
|
+
notify_channel = ChannelManager.get_instance("notify") # 系统通知
|
|
86
|
+
|
|
87
|
+
# 分别初始化(可使用不同后端)
|
|
88
|
+
await sse_channel.initialize(backend="memory") # 单进程即可
|
|
89
|
+
await chat_channel.initialize(backend="redis", redis_client=redis_client) # 需要跨进程
|
|
90
|
+
await notify_channel.initialize(backend="redis", redis_client=redis_client)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 13.5 环境变量
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# 默认实例
|
|
97
|
+
CHANNEL__BACKEND=memory
|
|
98
|
+
|
|
99
|
+
# 多实例(格式:CHANNEL__{{INSTANCE}}__{{FIELD}})
|
|
100
|
+
CHANNEL__DEFAULT__BACKEND=redis
|
|
101
|
+
CHANNEL__DEFAULT__URL=redis://localhost:6379/3
|
|
102
|
+
CHANNEL__NOTIFICATIONS__BACKEND=redis
|
|
103
|
+
CHANNEL__NOTIFICATIONS__URL=redis://localhost:6379/4
|
|
104
|
+
```
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# 消息队列(MQ)
|
|
2
|
+
|
|
3
|
+
支持 `redis` 和 `rabbitmq` 后端的消息队列,用于异步任务解耦。
|
|
4
|
+
|
|
5
|
+
## 14.1 基本用法
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
from aury.boot.infrastructure.mq import MQManager
|
|
9
|
+
|
|
10
|
+
# 获取实例
|
|
11
|
+
mq = MQManager.get_instance()
|
|
12
|
+
|
|
13
|
+
# Redis 后端
|
|
14
|
+
await mq.initialize(backend="redis", url="redis://localhost:6379/0")
|
|
15
|
+
|
|
16
|
+
# RabbitMQ 后端
|
|
17
|
+
await mq.initialize(backend="rabbitmq", url="amqp://guest:guest@localhost:5672/")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 14.2 生产者
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# 发送消息
|
|
24
|
+
await mq.publish(
|
|
25
|
+
queue="orders",
|
|
26
|
+
message={{"order_id": "123", "action": "created"}}
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# 批量发送
|
|
30
|
+
await mq.publish_batch(
|
|
31
|
+
queue="orders",
|
|
32
|
+
messages=[
|
|
33
|
+
{{"order_id": "1", "action": "created"}},
|
|
34
|
+
{{"order_id": "2", "action": "updated"}},
|
|
35
|
+
]
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 14.3 消费者
|
|
40
|
+
|
|
41
|
+
**文件**: `{package_name}/workers/order_worker.py`
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from aury.boot.infrastructure.mq import MQManager
|
|
45
|
+
from aury.boot.common.logging import logger
|
|
46
|
+
|
|
47
|
+
mq = MQManager.get_instance()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
async def process_order(message: dict):
|
|
51
|
+
\"\"\"处理订单消息。\"\"\"
|
|
52
|
+
logger.info(f"处理订单: {{message['order_id']}}")
|
|
53
|
+
# 业务逻辑...
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def start_consumer():
|
|
57
|
+
\"\"\"启动消费者。\"\"\"
|
|
58
|
+
await mq.consume("orders", process_order)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# 带确认的消费
|
|
62
|
+
async def process_with_ack(message: dict, ack, nack):
|
|
63
|
+
try:
|
|
64
|
+
await process_order(message)
|
|
65
|
+
await ack()
|
|
66
|
+
except Exception:
|
|
67
|
+
await nack(requeue=True)
|
|
68
|
+
|
|
69
|
+
await mq.consume("orders", process_with_ack, auto_ack=False)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 14.4 多实例
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
# 不同用途的 MQ 实例
|
|
76
|
+
orders_mq = MQManager.get_instance("orders")
|
|
77
|
+
notifications_mq = MQManager.get_instance("notifications")
|
|
78
|
+
|
|
79
|
+
# 分别初始化
|
|
80
|
+
await orders_mq.initialize(backend="rabbitmq", url="amqp://localhost:5672/orders")
|
|
81
|
+
await notifications_mq.initialize(backend="redis", url="redis://localhost:6379/5")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 14.5 环境变量
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# 默认实例
|
|
88
|
+
MQ__BACKEND=redis
|
|
89
|
+
MQ__URL=redis://localhost:6379/0
|
|
90
|
+
|
|
91
|
+
# 多实例(格式:MQ__{{INSTANCE}}__{{FIELD}})
|
|
92
|
+
MQ__DEFAULT__BACKEND=redis
|
|
93
|
+
MQ__DEFAULT__URL=redis://localhost:6379/4
|
|
94
|
+
MQ__ORDERS__BACKEND=rabbitmq
|
|
95
|
+
MQ__ORDERS__URL=amqp://guest:guest@localhost:5672/
|
|
96
|
+
MQ__ORDERS__PREFETCH_COUNT=10
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 14.6 与异步任务(Dramatiq)的区别
|
|
100
|
+
|
|
101
|
+
- **MQ**:轻量级消息传递,适合简单的生产者-消费者模式
|
|
102
|
+
- **Dramatiq(TaskManager)**:功能更丰富,支持重试、延迟、优先级等
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# 事件总线(Events)
|
|
2
|
+
|
|
3
|
+
支持 `memory`、`redis`、`rabbitmq` 后端的事件发布订阅系统。
|
|
4
|
+
|
|
5
|
+
## 15.1 定义事件
|
|
6
|
+
|
|
7
|
+
**文件**: `{package_name}/events/__init__.py`
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from aury.boot.infrastructure.events import Event
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OrderCreatedEvent(Event):
|
|
14
|
+
\"\"\"订单创建事件。\"\"\"
|
|
15
|
+
order_id: str
|
|
16
|
+
amount: float
|
|
17
|
+
user_id: str
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def event_name(self) -> str:
|
|
21
|
+
return "order.created"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class UserRegisteredEvent(Event):
|
|
25
|
+
\"\"\"用户注册事件。\"\"\"
|
|
26
|
+
user_id: str
|
|
27
|
+
email: str
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def event_name(self) -> str:
|
|
31
|
+
return "user.registered"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 15.1.1 事件初始化
|
|
35
|
+
|
|
36
|
+
事件类基于 Pydantic BaseModel,支持以下初始化方式:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
# 方式 1:关键字参数(推荐)
|
|
40
|
+
event = OrderCreatedEvent(
|
|
41
|
+
order_id="order-123",
|
|
42
|
+
amount=99.99,
|
|
43
|
+
user_id="user-456",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# 方式 2:字典解包
|
|
47
|
+
event = OrderCreatedEvent(**{{
|
|
48
|
+
"order_id": "order-123",
|
|
49
|
+
"amount": 99.99,
|
|
50
|
+
"user_id": "user-456",
|
|
51
|
+
}})
|
|
52
|
+
|
|
53
|
+
# 方式 3:从实体创建
|
|
54
|
+
event = OrderCreatedEvent(
|
|
55
|
+
order_id=str(order.id),
|
|
56
|
+
amount=order.amount,
|
|
57
|
+
user_id=str(order.user_id),
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 15.2 订阅事件
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from aury.boot.infrastructure.events import EventBusManager
|
|
65
|
+
|
|
66
|
+
bus = EventBusManager.get_instance()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@bus.subscribe(OrderCreatedEvent)
|
|
70
|
+
async def on_order_created(event: OrderCreatedEvent):
|
|
71
|
+
\"\"\"处理订单创建事件。\"\"\"
|
|
72
|
+
logger.info(f"订单创建: {{event.order_id}}, 金额: {{event.amount}}")
|
|
73
|
+
# 发送通知、更新统计等...
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@bus.subscribe(UserRegisteredEvent)
|
|
77
|
+
async def send_welcome_email(event: UserRegisteredEvent):
|
|
78
|
+
\"\"\"发送欢迎邮件。\"\"\"
|
|
79
|
+
await email_service.send_welcome(event.email)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## 15.3 发布事件
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from {package_name}.events import OrderCreatedEvent
|
|
86
|
+
|
|
87
|
+
@router.post("/orders")
|
|
88
|
+
async def create_order(request: OrderCreateRequest):
|
|
89
|
+
# 创建订单
|
|
90
|
+
order = await order_service.create(request)
|
|
91
|
+
|
|
92
|
+
# 发布事件
|
|
93
|
+
await bus.publish(OrderCreatedEvent(
|
|
94
|
+
order_id=order.id,
|
|
95
|
+
amount=order.amount,
|
|
96
|
+
user_id=order.user_id
|
|
97
|
+
))
|
|
98
|
+
|
|
99
|
+
return BaseResponse(code=200, message="订单创建成功", data=order)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 15.4 多实例(EventBusManager)
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from aury.boot.infrastructure.events import EventBusManager
|
|
106
|
+
|
|
107
|
+
# 获取实例
|
|
108
|
+
bus = EventBusManager.get_instance()
|
|
109
|
+
domain_bus = EventBusManager.get_instance("domain")
|
|
110
|
+
|
|
111
|
+
# Memory 后端(单进程)
|
|
112
|
+
await bus.initialize(backend="memory")
|
|
113
|
+
|
|
114
|
+
# Redis Pub/Sub 后端
|
|
115
|
+
await bus.initialize(
|
|
116
|
+
backend="redis",
|
|
117
|
+
url="redis://localhost:6379/0",
|
|
118
|
+
channel_prefix="events:",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# RabbitMQ 后端
|
|
122
|
+
await bus.initialize(
|
|
123
|
+
backend="rabbitmq",
|
|
124
|
+
url="amqp://guest:guest@localhost:5672/",
|
|
125
|
+
exchange_name="app.events",
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## 15.5 环境变量
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# 默认实例
|
|
133
|
+
EVENT__BACKEND=memory
|
|
134
|
+
|
|
135
|
+
# 多实例(格式:EVENT__{{INSTANCE}}__{{FIELD}})
|
|
136
|
+
EVENT__DEFAULT__BACKEND=redis
|
|
137
|
+
EVENT__DEFAULT__URL=redis://localhost:6379/5
|
|
138
|
+
EVENT__DOMAIN__BACKEND=rabbitmq
|
|
139
|
+
EVENT__DOMAIN__URL=amqp://guest:guest@localhost:5672/
|
|
140
|
+
EVENT__DOMAIN__EXCHANGE_NAME=domain.events
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## 15.6 最佳实践
|
|
144
|
+
|
|
145
|
+
1. **事件应该是不可变的** - 使用 Pydantic 的 `frozen=True`
|
|
146
|
+
2. **订阅者应该快速完成** - 耗时操作使用任务队列
|
|
147
|
+
3. **避免循环事件** - 不要在订阅者中发布相同类型的事件
|