我正在开发旅行行程预订引擎。用例是这样的:什么是用异步事件实现状态引擎的正确方法?
客户预订一个涉及多个腿(一条腿是旅程的连续部分,由同一家公司工作)的旅程。例如。从亚特兰大到新德里的旅行可能由两条腿组成,亚特兰大 - 纽约和纽约 - 新德里。
每条腿都有自己的保留,可以处于“挂起”或“确认”状态(这实际上只是真实状态的捷径)。
一旦预订合作伙伴(例如,航空公司)确认预订,每个支票预订只允许从“挂起”转换到“确认”。这些是可能需要数秒至数天的异步事件。
所有支票预订都捆绑在代表客户预订状态的父预订中。只有在a)所有相关支线均“确认”后,才允许家长预订从“挂起”转换为“确认”,以及b)客户支付完成后。请注意,实际上“预订确认”和“付款确认”存在区别,但为简洁起见,我在此简化。
所有通信都是通过异步服务接口进行的,即可能需要几秒到几天的时间,直到收到支付预订或支付的确认。
请注意,行程预订子系统与支付子系统是分开的,即预订系统只能通过查询两个子系统来确定父预留状态。两个子系统都会收到异步事件,并且在发生某些事件时也会对预订系统执行回调。
另外请注意,该系统应该用于不同的客户,每个客户可以拥有自己的一组状态/转换(用于父级保留)。
问题:
什么是管理中心,即父母预订的状态常用的方法,它依赖于外部子系统的状态?
特别是,考虑到子系统确认的异步性,如何跟踪各个子状态?
是否有组件开箱即可实现这样的分布式FSM(在Python生态系统中)?
我一直在思考以下方法:
实现一个“父预约FSM”反复尝试从“待定”到“确认”,每次查询相应的开关的状态付款和支付预留状态。在这种情况下,FSM主动尝试进入下一个状态(或在某个时刻超时)。这将作为一个周期性的芹菜任务来实现,它很简单地查询子系统,例如每30-60秒。
实现一个抽象的FSM(即工作流),该FSM在其状态发生变化时接收来自每个子系统的回调。在这种情况下,FSM跟踪收到的所有回调/事件,并且一旦收到所有腿事件的“付款正常”和“腿正常”,它就会将状态切换为“确认”。在这种情况下,FSM被动地等待事件到达。这将作为父保留对象来实现,该对象跟踪它收到的回调,然后设置父保留的状态。
第一种方法没有出现可扩展性,而第二种方法有不得不单独跟踪状态的缺点。我真正想要的是一个组件,它可以解决这个问题,而不必明确型号代码,允许为父预留FSM设置任意配置。
实现在Python中,使用Celery/RabbitMQ和Django。
我不明白你对你提出的第二个解决方案的看法。你说它必须跟踪每个组件的状态,这是不利的。但是,如果每个组件都可以从挂起转换到确认,您是不是在跟踪它们? – 2014-11-22 21:23:06
@加里凯恩斯,是的,每个组件都跟踪它们。我的意思是预订系统将复制每个组件的状态跟踪。所以预订系统基本上重新实现了子系统的FSM,这就是我的缺点。 – miraculixx 2014-11-22 22:12:10