def signal_child_on_complete(self, ack: Ack, is_stop: bool):
                with source.lock:
                    current_state = state[0]
                    state[0] = WaitOnNextChild(ack)

                if isinstance(current_state, WaitOnNextChild) or isinstance(current_state, Active):
                    ack.subscribe(self.async_upstream_ack)
                elif isinstance(current_state, Cancelled):
                    ack.on_next(Stop())
                    ack.on_completed()
                elif isinstance(current_state, WaitComplete):
                    state_: WaitComplete = current_state
                    if not is_stop:
                        if state_.ex is None:
                            self.send_on_complete()
                        else:
                            observer.on_error(state_.ex)
                    else:
                        scheduler.report_failure(state_.ex)
Example #2
0
    def connect(self):
        with self.lock:
            if not self.is_connected and not self.is_connected_started:
                self.is_connected_started = True

                buffer_was_drained = Ack()

                def on_next(v):
                    if isinstance(v, Continue):
                        self.root_ack.on_next(Continue())
                        self.root_ack.on_completed()
                        source.is_connected = True
                        source.queue = None
                        # source.connected_ack = None
                        # todo: fill in
                    elif isinstance(v, Stop):
                        raise NotImplementedError
                    else:
                        raise NotImplementedError

                buffer_was_drained.subscribe(on_next=on_next)

                source = self

                class CustomObserver(Observer):
                    def __init__(self):
                        self.ack = None

                    def on_next(self, v):
                        ack = source.underlying.on_next(v)
                        self.ack = ack

                        def on_next(v):
                            if isinstance(v, Stop):
                                buffer_was_drained.on_next(v)
                                buffer_was_drained.on_completed()

                        ack.subscribe(on_next=on_next)

                        return ack

                    def on_error(self, err):
                        raise NotImplementedError

                    def on_completed(self):
                        if not source.scheduled_done:
                            if self.ack is None:
                                buffer_was_drained.on_next(Continue())
                                buffer_was_drained.on_completed()
                            else:

                                def on_next(v):
                                    if isinstance(v, Continue):
                                        buffer_was_drained.on_next(Continue())
                                        buffer_was_drained.on_completed()

                                self.ack.subscribe(on_next)
                        elif source.schedule_error is not None:
                            raise NotImplementedError
                        else:
                            source.underlying.on_completed()

                class EmptyObject:
                    pass

                self.queue.put(EmptyObject)
                disposable = IteratorAsObservable(iter(self.queue.get, EmptyObject)) \
                    .subscribe(CustomObserver(), self.scheduler, CurrentThreadScheduler())

                self.connected_ref = buffer_was_drained, disposable
        return self.connected_ref