class ObserveOnMultiCastObserver(MultiCastObserver):
    next_observer: MultiCastObserver
    scheduler: Scheduler
    source_scheduler: Scheduler

    def __post_init__(self):
        self.trampoline = TrampolineScheduler()

        if self.scheduler.is_order_guaranteed:

            def schedule_func(action):
                self.scheduler.schedule(action)

        # if the order of schedule actions cannot be guaranteed
        # by the scheduler, then use a TrampolineScheduler on top
        # of the scheduler to guarantee the order
        else:

            def schedule_func(action):
                def action_on_scheduler(_, __):
                    self.trampoline.schedule(action)

                self.scheduler.schedule(action_on_scheduler)

        self.schedule_func = schedule_func

    def on_next(self, elem: ElementType):
        ack_subject = AckSubject()

        if isinstance(elem, list):
            elem = elem
        else:
            try:
                elem = list(elem)
            except Exception as exc:
                self.next_observer.on_error(exc)
                return

        def action(_, __):
            def subscribe_action(_, __):
                self.next_observer.on_next(elem)

            self.source_scheduler.schedule(subscribe_action)

        self.schedule_func(action)
        return ack_subject

    def on_error(self, exc):
        self.next_observer.on_error(exc)

    def on_completed(self):
        def action(_, __):
            def subscribe_action(_, __):
                self.next_observer.on_completed()

            self.source_scheduler.schedule(subscribe_action)

        self.schedule_func(action)
    def __post_init__(self):
        self.trampoline = TrampolineScheduler()

        if self.scheduler.is_order_guaranteed:

            def schedule_func(action):
                self.scheduler.schedule(action)

        # if the order of schedule actions cannot be guaranteed
        # by the scheduler, then use a TrampolineScheduler on top
        # of the scheduler to guarantee the order
        else:

            def schedule_func(action):
                def action_on_scheduler(_, __):
                    self.trampoline.schedule(action)

                self.scheduler.schedule(action_on_scheduler)

        self.schedule_func = schedule_func
Пример #3
0
def to_iterator(source: FlowableSubscribeMixin, scheduler: Scheduler = None):
    @dataclass
    class ToIteratorObserver(Observer):
        received: List[ElementType]
        is_completed: bool
        exception: Optional[Exception]

        def on_next(self, elem: ElementType) -> Ack:
            if not isinstance(elem, list):
                elem = list(elem)

            self.received.append(elem)
            return continue_ack

        def on_error(self, exc: Exception):
            self.exception = exc

        def on_completed(self):
            self.is_completed = True

    observer = ToIteratorObserver(
        received=[],
        is_completed=False,
        exception=None,
    )
    subscribe_scheduler = TrampolineScheduler()
    scheduler = scheduler or subscribe_scheduler

    source.subscribe(
        observer=observer,
        scheduler=scheduler,
        subscribe_scheduler=subscribe_scheduler,
    )

    def gen():
        while True:
            while True:
                if len(observer.received):
                    break

                if observer.is_completed:
                    return  # StopIteration

                if observer.exception is not None:
                    raise observer.exception

                scheduler.sleep(0.1)

            yield from observer.received.pop(0)

    return gen()
    def subscribe(
            self,
            on_next: Callable[[Any], None] = None,
            on_error: Callable[[Any], None] = None,
            on_completed: Callable[[], None] = None,
            scheduler: Scheduler = None,
            subscribe_scheduler: Scheduler = None,
            observer: Observer = None,
    ) -> rx.typing.Disposable:
        """ Calling `subscribe` method starts some kind of process that

        start a chain reaction where downsream `Flowables`
        call the `subscribe` method of their linked upstream `Flowable` until
        the sources start emitting data. Once a `Flowable` is subscribed, we
        allow it to have mutable states where it make sense.
        """

        assert isinstance(self, SharedFlowableMixin) is False, \
            'a shared Flowable cannot be subscribed, use Flowable inside MultiCast instead'

        subscribe_scheduler_ = subscribe_scheduler or TrampolineScheduler()
        scheduler_ = scheduler or subscribe_scheduler_

        subscriber = init_subscriber(
            scheduler=scheduler_,
            subscribe_scheduler=subscribe_scheduler_,
        )

        subscription = self.unsafe_subscribe(subscriber=subscriber)

        assert isinstance(subscription, Subscription), \
            f'"{subscription}" must be of type Subscription'

        disposable = self._observe(
            observable=subscription.observable,
            on_next=on_next,
            on_completed=on_completed,
            on_error=on_error,
            observer=observer,
            subscribe_scheduler=subscribe_scheduler_,
        )

        assert isinstance(disposable, rx.typing.Disposable), \
            f'"{disposable}" must be of type Disposable'

        return disposable
Пример #5
0
    def unsafe_subscribe(self, subscriber: Subscriber):
        scheduler = self._scheduler or TrampolineScheduler()

        updated_subscriber = init_subscriber(
            scheduler=subscriber.scheduler,
            subscribe_scheduler=scheduler,
        )

        subscription = self._source.unsafe_subscribe(updated_subscriber)

        class SubscribeOnObservable(Observable):
            def observe(_, observer_info: ObserverInfo):
                def action(_, __):
                    return subscription.observable.observe(observer_info)

                disposable = scheduler.schedule(action)

                return disposable

        observable = SubscribeOnObservable()

        return init_subscription(observable=observable)
        def gen_subscribe_schedulers():
            yield subscriber.subscribe_scheduler

            for _ in range(self.source.lift_index):
                yield TrampolineScheduler()
Пример #7
0
 def gen_subscribe_schedulers():
     for _ in range(diff_schedulers):
         yield TrampolineScheduler()
Пример #8
0
class ObserveOnObserver(Observer):
    observer: Observer
    scheduler: Scheduler

    def __post_init__(self):
        self.trampoline = TrampolineScheduler()

        if self.scheduler.is_order_guaranteed:

            def schedule_func(action):
                self.scheduler.schedule(action)

        # if the order of schedule actions cannot be guaranteed
        # by the scheduler, then use a TrampolineScheduler on top
        # of the scheduler to guarantee the order
        else:

            def schedule_func(action):
                def action_on_scheduler(_, __):
                    self.trampoline.schedule(action)

                self.scheduler.schedule(action_on_scheduler)

        self.schedule_func = schedule_func

    def on_next(self, elem: ElementType):
        ack_subject = AckSubject()

        if isinstance(elem, list):
            elem = elem
        else:
            try:
                elem = list(elem)
            except Exception as exc:
                self.observer.on_error(exc)
                return stop_ack

        def action(_, __):
            inner_ack = self.observer.on_next(elem)

            if isinstance(inner_ack, ContinueAck):
                ack_subject.on_next(inner_ack)
            elif isinstance(inner_ack, StopAck):
                ack_subject.on_next(inner_ack)
            elif inner_ack is None:
                raise Exception(
                    f'observer {self.observer} returned None instead of an Ack'
                )
            else:
                inner_ack.subscribe(ack_subject)

        self.schedule_func(action)
        return ack_subject

    def on_error(self, exc):
        self.observer.on_error(exc)

    def on_completed(self):
        def action(_, __):
            self.observer.on_completed()

        self.schedule_func(action)
    def __post_init__(self):
        self.is_first = True
        self.is_stopped = False
        self.subscribe_scheduler = TrampolineScheduler()

        self._observable_subject = None
Пример #10
0
        def _subscribe_core(self,
                            observer: typing.Observer,
                            scheduler: typing.Scheduler = None):
            class RxBPScheduler(SchedulerBase):
                def __init__(self, underlying):
                    super().__init__()

                    self.underlying = underlying

                def sleep(self, seconds: float) -> None:
                    pass

                @property
                def now(self) -> datetime:
                    return self.underlying.now

                @property
                def is_order_guaranteed(self) -> bool:
                    # unknown property, therefore select pessimistically
                    return False

                def schedule(self,
                             action: ScheduledAction,
                             state: TState = None) -> Disposable:
                    return self.underlying.schedule(action=action, state=state)

                def schedule_relative(self,
                                      duetime: RelativeTime,
                                      action: ScheduledAction,
                                      state: TState = None) -> Disposable:
                    return self.underlying.schedule_relative(duetime=duetime,
                                                             action=action,
                                                             state=state)

                def schedule_absolute(self,
                                      duetime: AbsoluteTime,
                                      action: ScheduledAction,
                                      state: TState = None) -> Disposable:
                    return self.underlying.schedule_absolute(duetime=duetime,
                                                             action=action,
                                                             state=state)

                def schedule_periodic(
                        self,
                        period: RelativeTime,
                        action: ScheduledPeriodicAction,
                        state: Optional[TState] = None) -> Disposable:
                    raise NotImplementedError

            class ToRxObserver(Observer):
                @property
                def is_volatile(self):
                    return False

                def on_next(self, elem: ElementType):
                    for e in elem:
                        observer.on_next(e)
                    return continue_ack

                def on_error(self, err):
                    observer.on_error(err)

                def on_completed(self):
                    observer.on_completed()

            to_rx_observer = ToRxObserver()

            if batched is True:

                def on_next(v):
                    batch = list(v())
                    observer.on_next(batch)
                    return continue_ack

                to_rx_observer.on_next = on_next

            trampoline_scheduler = subscribe_schduler or TrampolineScheduler()
            scheduler_ = RxBPScheduler(
                underlying=scheduler
            ) if scheduler is not None else trampoline_scheduler
            subscriber = init_subscriber(
                scheduler=scheduler_, subscribe_scheduler=trampoline_scheduler)
            # observer_info = init_observer_info(observer=to_rx_observer)
            return source.subscribe(
                observer=to_rx_observer,
                subscribe_scheduler=subscriber.subscribe_scheduler,
                scheduler=subscriber.subscribe_scheduler,
            )