def on_next_right(right): ack = Ack() upper_ack = None has_inner_left_elem = False request_left_right = False request_right = False with self.lock: if 0 < inner_left_completed[0]: inner_left_completed[0] -= 1 request_right = True upper_ack = Continue() # new_state = self.WaitForLeftOrRight() new_state = state[0] elif isinstance(state[0], self.WaitForLeftOrRight): new_state = self.WaitForLeft(right_elem=right, right_ack=ack) elif isinstance(state[0], self.WaitForRightOrInner): state_: FlatZipObservable.WaitForRightOrInner = state[0] if inner_left_completed[0] == 0: new_state = self.Active(left_ack=state_.left_ack, right_elem=right, right_ack=ack, upper_ack=Continue()) else: inner_left_completed[0] -= 1 new_state = self.WaitForLeftOrRight() elif isinstance(state[0], self.WaitForRight): state_: FlatZipObservable.WaitForRight = state[0] has_inner_left_elem = True left_elem = state_.left_elem left_ack = state_.left_ack inner_left_elem = state_.inner_left_elem inner_left_ack = state_.inner_left_ack new_state = state[0] elif isinstance(state[0], source.Completed): return stop_ack else: raise NotImplementedError state[0] = new_state if has_inner_left_elem: zipped_elem = self.selector(left_elem, right, inner_left_elem) upper_ack = observer.on_next(zipped_elem) if isinstance(upper_ack, Stop): with self.lock: state[0] = self.Completed return upper_ack request_inner_elem = False with self.lock: if 0 < inner_left_completed[0]: # inner left completed, request new left and right new_state = self.WaitForLeftOrRight() request_left_right = True else: # state is the same, change state to active new_state = self.Active(left_ack=left_ack, right_elem=right, right_ack=ack, upper_ack=upper_ack) request_inner_elem = True state[0] = new_state if request_inner_elem: if isinstance(upper_ack, Continue) or isinstance( upper_ack, Stop): inner_left_ack.on_next(upper_ack) inner_left_ack.on_completed() else: upper_ack.observe_on(scheduler).subscribe( inner_left_ack) if request_left_right: if isinstance(upper_ack, Continue): left_ack.on_next(upper_ack) left_ack.on_completed() else: upper_ack.observe_on(scheduler).subscribe(left_ack) if request_left_right or request_right: if isinstance(upper_ack, Continue): ack.on_next(upper_ack) ack.on_completed() else: upper_ack.observe_on(scheduler).subscribe(ack) return ack
def on_completed(self): back_pressure_right = False back_pressure_left = False left_ack = None right_ack = None upper_ack = None complete_observer = False with source.lock: if isinstance(state[0], source.Active): # normal complete if right_completed[0]: state[0] = source.Completed() complete_observer = True else: # request new left and new right state_typed: source.Active = state[0] back_pressure_right = True back_pressure_left = True left_ack = state_typed.left_ack right_ack = state_typed.right_ack upper_ack = state_typed.upper_ack state[0] = source.WaitForLeftOrRight() elif isinstance(state[0], source.WaitForRightOrInner): # empty inner observable state_typed: source.WaitForRight = state[0] # count up number of inner completed (without right completed) inner_left_completed[0] += 1 state[0] = source.WaitForLeftOrRight() back_pressure_left = True left_ack = state_typed.left_ack upper_ack = Continue() if complete_observer: observer.on_completed() if back_pressure_left or back_pressure_right: def _(v): if isinstance(v, Stop): with source.lock: state[0] = source.Completed() upper_ack.subscribe(_) if back_pressure_left: # upper_ack should not be Stop if isinstance(upper_ack, Continue): left_ack.on_next(upper_ack) left_ack.on_completed() else: upper_ack.observe_on(scheduler).subscribe(left_ack) if back_pressure_right: if isinstance(upper_ack, Continue): right_ack.on_next(upper_ack) right_ack.on_completed() else: upper_ack.observe_on(scheduler).subscribe( right_ack)