Example #1
0
        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
Example #2
0
                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)