队列触发¶
流程跑到某节点后挂起,等 Redis/Kafka 队列收到消息再继续。典型用途:下单后等支付消息到达再发货。需 server extra(redis_queue)或 redis extra(redis)。
流程定义¶
{
"flow_id": "order_fulfill",
"inputType": { "dataType": "object" },
"nodes": [
{ "type": "start", "id": "start", "next": "wait_pay" },
{
"type": "redis_queue",
"id": "wait_pay",
"event_type": "redis_message",
"queue_name": "payment_notifications",
"next": "decide"
},
{
"type": "if",
"id": "decide",
"condition": { "field": "$NODE.wait_pay.event_data.paid", "operator": "eq", "value": true },
"next": "ship",
"else_next": "cancel"
},
{ "type": "end", "id": "ship", "output": "已发货", "resultType": "success" },
{ "type": "end", "id": "cancel", "output": "已取消", "resultType": "success" }
]
}
队列节点的事件类型是固定的
redis_queue / kafka_queue 节点继承自事件节点,event_type 为必填字段,但节点会在构造时把它固定为 redis_message / kafka_message——外延服务(RedisQueueService 等)把队列消息包装成对应类型的 Event 发布。业务数据放在事件 data 里,恢复后经 $NODE.<id>.event_data 引用。
提交订单并挂起¶
from plaita import FlowExecution
from plaita.event.memory import InMemoryEventBus
flow = Flow.from_string(open("order_fulfill.json").read())
bus = InMemoryEventBus()
execution = FlowExecution(event_bus=bus)
step = execution.run_distributed(flow, {"order_id": "o-1"})
assert step["is_suspend"] is True
exec_id = step["execution_id"]
save_context(exec_id, step["context"])
队列消息到达触发恢复¶
生产中 RedisQueueService 阻塞监听 payment_notifications 队列,消息到达后包装成 redis_message 事件 publish。演示里直接 publish:
import asyncio
from plaita.event.core import Event
async def pay(exec_id):
await bus.publish(Event(
event_type="redis_message",
data={"paid": True, "order_id": "o-1"},
correlation_id=exec_id,
source="payment_system",
))
asyncio.run(pay(exec_id))
恢复¶
resume_type="event" 只消费事件并恢复挂起节点本身,后续节点用 resume_type="continue" 推进:
ctx = load_context(exec_id)
step = execution.run_distributed(
flow, None, saved_context=ctx,
resume_type="event",
resume_data={"paid": True, "order_id": "o-1"},
)
while not step["is_end"]:
step = execution.run_distributed(
flow, None, saved_context=step["context"], resume_type="continue",
)
print(step["result"]) # => "已发货"
Kafka 队列¶
把节点 type 换成 kafka_queue,配 bootstrap_servers / topic / group_id 等(event_type 会被固定为 kafka_message),配套 KafkaQueueService 监听 Kafka topic。流程侧写法不变。
{
"type": "kafka_queue",
"id": "wait_event",
"event_type": "kafka_message",
"bootstrap_servers": "localhost:9092",
"topic": "user_events",
"group_id": "flow_consumer",
"next": "end"
}
生产闭环¶
flowchart LR
App["下单"] --> FW["FlowWorker"]
FW -->|"挂起 wait_pay"| Bus[("EventBus")]
QSvc["RedisQueueService"] -->|监听队列| Q[("payment_notifications")]
Q --> QSvc
QSvc -->|publish payment_received| Bus
Bus -->|恢复| FW
FW -->|"if paid -> ship"| Done["已发货"]
ServiceManager 启动 RedisQueueService,把队列消息转成事件;FlowWorker 监听事件并恢复对应挂起流程。
要点回顾¶
redis_queue/kafka_queue节点声明等待,外延服务负责触发correlation_id=execution_id保证消息路由到正确的挂起流程- 流程侧与触发侧通过
EventBus解耦,可多实例负载均衡