基于铁路模式的作业包
operation的Python项目详细描述
操作
Python的Railway Oriented Programming实现。在
动机
铁路事件处理的副作用可以是非常优雅的。 此包允许您为每个流或事件创建一个专用管道,以有序的方式执行任务。在
基本用途
- 使用
phases
方法创建从Operation
继承的类:
fromoperationimportOperationclassSomeOperation(Operation):defphases(self):return['phase_one','phase_two','phase_three']defphase_one(self):self.options['option_for_second_phase']=Truedefphase_two(self):if'option_for_second_phase'inself.options:return'an option got passed from first phase, cool!'defphase_three(self):self.options['reached_third_phase']=True
- 在操作管理器中,使用
SomeOperation(options).run()
,其中options
是操作流的输入。在
示例
例如,如果创建一个操作,该操作首先连接到数据库,然后通过id获取a文档,对其进行验证,最后发送该条目的用户_id的post请求,它可以如下所示:
^{pr2}$特点
断开操作
调用break_operation(message?)
可以在无效结果上中断操作(事件的处理程序)管道,而不会使整个操作失败。
此类用例的一个例子是,如果某个实体不存在,则在签入数据库时-如果不存在,则不继续操作。在
在下面的流程中,我们要处理一个名为OrderCreated
的CRUD事件,
如果我们的数据库中没有用户详细信息,我们将不想继续,因为只有注册用户才能创建订单:
fromoperationimportOperationclassOrderCreated(Operation):defphases(self):return['validate_user_exists','create_an_order','...','...']defvalidate_user_exists(self):user=db.user_collection.find_one({'id':self.options['user_id']})ifnotuser:self.break_operation(message='user not in mongo collection')defcreate_an_order(self):...
操作失败
通过调用fail_operation(message?)
,我们可以停止,并使操作失败。
例如,在与另一个服务或远程数据库发生暂时的网络连接问题时,这非常有用,
当您要将操作结果对象发送到失败队列时,以便以后处理阶段中的事件
它失败了,而且使用了当前的选项。在
我们也可以raise
一个异常,它将被视为一个失败的操作,但在这种情况下,服务调用有一个包装器/
数据库访问已经捕捉到异常,这非常有用:
其他处理mongo连接的模块:
frompymongoimportMongoClientclassUserCollection:definit_connection(self):try:returnMongoClient('<MongoDB_URL>').db.user_collectionexceptExceptionase:returnNone...
我们的业务:
frommodels.userimportUserCollectionfromoperationimportOperationclassOrderCreated(Operation):defphases(self):return['validate_user_exists','create_an_order','...','...']defvalidate_user_exists(self):user_collection=UserCollection().init_connection()ifnotuser_collection:self.fail_operation(message='mongo connection failure')defcreate_an_order(self):...
模式
模式机制允许我们验证传递给操作的消息(事件负载), 在操作开始之前:
schema=Schema({'user_id':int,'logged_in':bool})event_payload={'user_id':'not a number','logged_in':True}OrderCreated(options=event_payload,schema=schema).run()
此运行将导致失败,并显示失败消息:
schema.SchemaUnexpectedTypeError: 'not a number' should be instance of 'int'
入口阶段
进入阶段允许我们使用特定阶段的操作,并跳过之前的阶段。 最常见的用例是在出现故障时重新运行操作,或者只使用 整个行动。在
event_payload={'user_id':123,'logged_in':True}OrderCreated(options=event_payload,entry_phase='create_an_order').run()
- 项目
标签: