在出现异常时从Observable返回中间值

时间:2018-08-03 08:54:09

标签: python reactive-programming rx-py

我想在RxPY中实现两步流程作为Observable。当第二步失败(或根本不执行)时,我想依靠第一步的结果。目标是首先提交一些数据,然后处理任何冲突。

在提交时(步骤1 ),每秒都会对服务器进行一次关于提交操作状态的轮询。操作完成后,我想停止轮询服务器并继续解决冲突(步骤2 ),但前提是存在任何冲突。同样,每秒对服务器进行一次操作状态轮询。当两个步骤都完成后,我想再次停止轮询,并返回服务器对步骤2的响应,或者如果未发生步骤2,则返回对步骤1的响应。我已经实现了以下行为:

step_1 = (Observable.of(Api.commit())
    .share()
    .replay(lambda i: i, buffer_size=1))

step_1_polling = (model_commit.combine_latest(Observable.timer(0, period=POLLING_INTERVAL), lambda a, b: [a, b])
    .switch_map(lambda i: Observable.of(Api.poll_server()))
    .filter(lambda q: q.state in [ResponseStateEnum.COMPLETED.value, ResponseStateEnum.FAILURE.value])
    .switch_map(lambda q: Observable.throw(Exception('Response state failure!')) if q.state == ResponseStateEnum.FAILURE else Observable.of(q))
    .share()
    .replay(lambda q: q, buffer_size=1))

step_1_polling.first().subscribe(lambda s: print_msg('Step 1 successful!'), lambda e: print_msg('Step 1 failed! Reason: %s' % str(e)))

step_2 = (step_1_polling.first()
    .filter(lambda q: q.difResult.state == ResponseDifResultStateEnum.CONFLICT.value)
    .with_latest_from(step_1, lambda a, b: [a, b])
    .tap(lambda i: print_msg('Resolving the conflicts!'))
    .switch_map(lambda i: Observable.of(Api.resolve_conflicts()))
    .share()
    .replay(lambda i: i, buffer_size=1))

step_2_polling = (step_2.combine_latest(Observable.timer(0, period=POLLING_INTERVAL), lambda a, b: [a, b])
    .switch_map(lambda i: Observable.of(Api.poll_server()))
    .filter(lambda q: q.state in [ResponseStateEnum.COMPLETED.value, ResponseStateEnum.FAILURE.value])
    .switch_map(lambda q: Observable.throw(Exception('Response state failure!')) if q.state == ResponseStateEnum.FAILURE.value else Observable.of(q))
    .share()
    .replay(lambda q: q, buffer_size=1))

result = step_2_polling.first()

result.subscribe(lambda s: print_msg('Step 2 successful!'), lambda e: print_msg('Step 2 failed! Reason: %s' % str(e)))

return result.catch_exception(lambda e: step_1)

现在的问题是,如果第2步完成,我返回的流只会发出一个值。如果没有冲突(即未传递步骤2开头的filter),则会向步骤2抛出sequence contains no elements异常。我按顺序添加了catch_exception运算符如果发生这种情况,请切换回步骤1的结果。但是,这似乎并不能解决问题。我在这里想念什么?

0 个答案:

没有答案