Example #1
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            is_open = [False]

            def on_next(left: _T) -> None:
                if is_open[0]:
                    observer.on_next(left)

            def on_completed() -> None:
                if is_open[0]:
                    observer.on_completed()

            subs = source.subscribe(
                on_next, observer.on_error, on_completed, scheduler=scheduler
            )
            subscriptions = CompositeDisposable(subs)

            right_subscription = SingleAssignmentDisposable()
            subscriptions.add(right_subscription)

            def on_next2(x: Any) -> None:
                is_open[0] = True
                right_subscription.dispose()

            def on_completed2():
                right_subscription.dispose()

            right_subscription.disposable = obs.subscribe(
                on_next2, observer.on_error, on_completed2, scheduler=scheduler
            )

            return subscriptions
Example #2
0
    def _subscribe_core(
        self,
        observer: Optional[abc.ObserverBase[_T]] = None,
        scheduler: Optional[abc.SchedulerBase] = None,
    ) -> abc.DisposableBase:
        self.subscriptions.append(Subscription(self.scheduler.clock))
        index = len(self.subscriptions) - 1
        disp = CompositeDisposable()

        def get_action(
                notification: Notification[_T]) -> abc.ScheduledAction[_T]:
            def action(scheduler: abc.SchedulerBase,
                       state: Any = None) -> abc.DisposableBase:
                if observer:
                    notification.accept(observer)
                return Disposable()

            return action

        for message in self.messages:
            notification = message.value
            if not isinstance(notification, Notification):
                raise ValueError("Must be notification")

            # Don't make closures within a loop
            action = get_action(notification)
            disp.add(self.scheduler.schedule_relative(message.time, action))

        def dispose() -> None:
            start = self.subscriptions[index].subscribe
            end = self.scheduler.to_seconds(self.scheduler.now)
            self.subscriptions[index] = Subscription(start, int(end))
            disp.dispose()

        return Disposable(dispose)
Example #3
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            delays = CompositeDisposable()
            at_end = [False]

            def done():
                if at_end[0] and delays.length == 0:
                    observer.on_completed()

            subscription = SerialDisposable()

            def start():
                def on_next(x: _T) -> None:
                    try:
                        assert mapper
                        delay = mapper(x)
                    except Exception as error:  # pylint: disable=broad-except
                        observer.on_error(error)
                        return

                    d = SingleAssignmentDisposable()
                    delays.add(d)

                    def on_next(_: Any) -> None:
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    def on_completed() -> None:
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    d.disposable = delay.subscribe(on_next,
                                                   observer.on_error,
                                                   on_completed,
                                                   scheduler=scheduler)

                def on_completed() -> None:
                    at_end[0] = True
                    subscription.dispose()
                    done()

                subscription.disposable = source.subscribe(on_next,
                                                           observer.on_error,
                                                           on_completed,
                                                           scheduler=scheduler)

            if not sub_delay:
                start()
            else:
                subscription.disposable = sub_delay.subscribe(
                    lambda _: start(), observer.on_error, start)

            return CompositeDisposable(subscription, delays)
Example #4
0
def test_groupdisposable_contains():
    d1 = Disposable()
    d2 = Disposable()

    g = CompositeDisposable(d1, d2)

    assert g.length == 2
    assert g.contains(d1)
    assert g.contains(d2)
Example #5
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            active_count = [0]
            group = CompositeDisposable()
            is_stopped = [False]
            queue: List[Observable[_T]] = []

            def subscribe(xs: Observable[_T]):
                subscription = SingleAssignmentDisposable()
                group.add(subscription)

                @synchronized(source.lock)
                def on_completed():
                    group.remove(subscription)
                    if queue:
                        s = queue.pop(0)
                        subscribe(s)
                    else:
                        active_count[0] -= 1
                        if is_stopped[0] and active_count[0] == 0:
                            observer.on_completed()

                on_next = synchronized(source.lock)(observer.on_next)
                on_error = synchronized(source.lock)(observer.on_error)
                subscription.disposable = xs.subscribe(on_next,
                                                       on_error,
                                                       on_completed,
                                                       scheduler=scheduler)

            def on_next(inner_source: Observable[_T]) -> None:
                assert max_concurrent
                if active_count[0] < max_concurrent:
                    active_count[0] += 1
                    subscribe(inner_source)
                else:
                    queue.append(inner_source)

            def on_completed():
                is_stopped[0] = True
                if active_count[0] == 0:
                    observer.on_completed()

            group.add(
                source.subscribe(on_next,
                                 observer.on_error,
                                 on_completed,
                                 scheduler=scheduler))
            return group
Example #6
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            m = SerialDisposable()
            d = CompositeDisposable(m)
            r = RefCountDisposable(d)
            window: Subject[_T] = Subject()

            observer.on_next(add_ref(window, r))

            def on_next(value: _T) -> None:
                window.on_next(value)

            def on_error(error: Exception) -> None:
                window.on_error(error)
                observer.on_error(error)

            def on_completed() -> None:
                window.on_completed()
                observer.on_completed()

            d.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler))

            def create_window_on_completed():
                try:
                    window_close = closing_mapper()
                except Exception as exception:
                    observer.on_error(exception)
                    return

                def on_completed():
                    nonlocal window
                    window.on_completed()
                    window = Subject()
                    observer.on_next(add_ref(window, r))
                    create_window_on_completed()

                m1 = SingleAssignmentDisposable()
                m.disposable = m1
                m1.disposable = window_close.pipe(ops.take(1)).subscribe(
                    noop, on_error, on_completed, scheduler=scheduler)

            create_window_on_completed()
            return r
Example #7
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        seconds = max(0.0, self.to_seconds(duetime))

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = action(self, state)

        log.debug("timeout: %s", seconds)
        timer = self._reactor.callLater(seconds, interval)

        def dispose() -> None:
            if not timer.called:
                timer.cancel()

        return CompositeDisposable(sad, Disposable(dispose))
Example #8
0
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        scheduler = scheduler or CurrentThreadScheduler.singleton()

        subscription = SerialDisposable()
        cancelable = SerialDisposable()

        def action(scheduler: abc.SchedulerBase,
                   state: Optional[Exception] = None) -> None:
            try:
                source = next(sources_)
            except StopIteration:
                observer.on_completed()
                return

            # Allow source to be a factory method taking an error
            source = source(state) if callable(source) else source
            current = (reactivex.from_future(source) if isinstance(
                source, Future) else source)

            d = SingleAssignmentDisposable()
            subscription.disposable = d

            def on_resume(state: Optional[Exception] = None) -> None:
                scheduler.schedule(action, state)

            d.disposable = current.subscribe(observer.on_next,
                                             on_resume,
                                             on_resume,
                                             scheduler=scheduler)

        cancelable.disposable = scheduler.schedule(action)
        return CompositeDisposable(subscription, cancelable)
Example #9
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        handle = self._loop.call_soon_threadsafe(interval)

        def dispose() -> None:
            if self._on_self_loop_or_not_running():
                handle.cancel()
                return

            future: "Future[int]" = Future()

            def cancel_handle() -> None:
                handle.cancel()
                future.set_result(0)

            self._loop.call_soon_threadsafe(cancel_handle)
            future.result()

        return CompositeDisposable(sad, Disposable(dispose))
Example #10
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        timer = self._eventlet.spawn(interval)

        def dispose() -> None:
            timer.kill()

        return CompositeDisposable(sad, Disposable(dispose))
Example #11
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        sad = SingleAssignmentDisposable()
        is_disposed = False

        def invoke_action() -> None:
            if not is_disposed:
                sad.disposable = action(self, state)

        log.debug("relative timeout: %sms", msecs)

        # Use static method, let Qt C++ handle QTimer lifetime
        self._qtcore.QTimer.singleShot(msecs, invoke_action)

        def dispose() -> None:
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(sad, Disposable(dispose))
Example #12
0
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )
        iterator = iter(iterable)
        disposed = False

        def action(_: abc.SchedulerBase, __: Any = None) -> None:
            nonlocal disposed

            try:
                while not disposed:
                    value = next(iterator)
                    observer.on_next(value)
            except StopIteration:
                observer.on_completed()
            except Exception as error:  # pylint: disable=broad-except
                observer.on_error(error)

        def dispose() -> None:
            nonlocal disposed
            disposed = True

        disp = Disposable(dispose)
        return CompositeDisposable(_scheduler.schedule(action), disp)
Example #13
0
    def schedule(self,
                 action: typing.ScheduledAction[_TState],
                 state: Optional[_TState] = None) -> abc.DisposableBase:
        """Schedules an action to be executed.

        Args:
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        sad = SingleAssignmentDisposable()
        is_disposed = False

        def invoke_action() -> None:
            if not is_disposed:
                sad.disposable = action(self, state)

        self._wx.CallAfter(invoke_action)

        def dispose() -> None:
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(sad, Disposable(dispose))
Example #14
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        sad = SingleAssignmentDisposable()

        def invoke_action() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        msecs = max(0, int(self.to_seconds(duetime) * 1000.0))
        timer = self._root.after(msecs, invoke_action)

        def dispose() -> None:
            self._root.after_cancel(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Example #15
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """

        seconds = self.to_seconds(duetime)
        if seconds <= 0.0:
            return self.schedule(action, state=state)

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        log.debug("timeout: %s", seconds)
        timer = self._loop.call_later(seconds, interval)

        def dispose() -> None:
            self._loop.remove_timeout(timer)
            self._loop.remove_timeout(timer)

        return CompositeDisposable(sad, Disposable(dispose))
Example #16
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            has_current = [False]
            is_stopped = [False]
            m = SingleAssignmentDisposable()
            g = CompositeDisposable()

            g.add(m)

            def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None:
                if not has_current[0]:
                    has_current[0] = True

                    inner_source = (
                        reactivex.from_future(inner_source)
                        if isinstance(inner_source, Future)
                        else inner_source
                    )

                    inner_subscription = SingleAssignmentDisposable()
                    g.add(inner_subscription)

                    def on_completed_inner():
                        g.remove(inner_subscription)
                        has_current[0] = False
                        if is_stopped[0] and len(g) == 1:
                            observer.on_completed()

                    inner_subscription.disposable = inner_source.subscribe(
                        observer.on_next,
                        observer.on_error,
                        on_completed_inner,
                        scheduler=scheduler,
                    )

            def on_completed() -> None:
                is_stopped[0] = True
                if not has_current[0] and len(g) == 1:
                    observer.on_completed()

            m.disposable = source.subscribe(
                on_next, observer.on_error, on_completed, scheduler=scheduler
            )
            return g
Example #17
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            switched = [False]
            _id = [0]

            original = SingleAssignmentDisposable()
            subscription = SerialDisposable()
            timer = SerialDisposable()
            subscription.disposable = original

            def create_timer() -> None:
                my_id = _id[0]

                def action(scheduler: abc.SchedulerBase, state: Any = None):
                    switched[0] = _id[0] == my_id
                    timer_wins = switched[0]
                    if timer_wins:
                        subscription.disposable = obs.subscribe(
                            observer, scheduler=scheduler)

                if isinstance(duetime, datetime):
                    timer.disposable = _scheduler.schedule_absolute(
                        duetime, action)
                else:
                    timer.disposable = _scheduler.schedule_relative(
                        duetime, action)

            create_timer()

            def on_next(value: _T) -> None:
                send_wins = not switched[0]
                if send_wins:
                    _id[0] += 1
                    observer.on_next(value)
                    create_timer()

            def on_error(error: Exception) -> None:
                on_error_wins = not switched[0]
                if on_error_wins:
                    _id[0] += 1
                    observer.on_error(error)

            def on_completed() -> None:
                on_completed_wins = not switched[0]
                if on_completed_wins:
                    _id[0] += 1
                    observer.on_completed()

            original.disposable = source.subscribe(on_next,
                                                   on_error,
                                                   on_completed,
                                                   scheduler=scheduler_)
            return CompositeDisposable(subscription, timer)
Example #18
0
    def schedule_relative(
        self,
        duetime: typing.RelativeTime,
        action: typing.ScheduledAction[_TState],
        state: Optional[_TState] = None,
    ) -> abc.DisposableBase:
        """Schedules an action to be executed after duetime.

        Args:
            duetime: Relative time after which to execute the action.
            action: Action to be executed.
            state: [Optional] state to be given to the action function.

        Returns:
            The disposable object used to cancel the scheduled action
            (best effort).
        """
        seconds = self.to_seconds(duetime)
        if seconds <= 0:
            return self.schedule(action, state=state)

        sad = SingleAssignmentDisposable()

        def interval() -> None:
            sad.disposable = self.invoke_action(action, state=state)

        # the operations on the list used here are atomic, so there is no
        # need to protect its access with a lock
        handle: List[asyncio.Handle] = []

        def stage2() -> None:
            handle.append(self._loop.call_later(seconds, interval))

        handle.append(self._loop.call_soon_threadsafe(stage2))

        def dispose() -> None:
            def do_cancel_handles() -> None:
                try:
                    handle.pop().cancel()
                    handle.pop().cancel()
                except Exception:
                    pass

            if self._on_self_loop_or_not_running():
                do_cancel_handles()
                return

            future: "Future[int]" = Future()

            def cancel_handle() -> None:
                do_cancel_handles()
                future.set_result(0)

            self._loop.call_soon_threadsafe(cancel_handle)
            future.result()

        return CompositeDisposable(sad, Disposable(dispose))
Example #19
0
 def subscribe(
     observer: abc.ObserverBase[_T],
     scheduler: Optional[abc.SchedulerBase] = None,
 ) -> abc.DisposableBase:
     return CompositeDisposable(
         merged_disposable.disposable
         if merged_disposable else Disposable(),
         underlying_observable.subscribe(observer, scheduler=scheduler),
     )
Example #20
0
File: using.py Project: lizh06/RxPY
    def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        disp: abc.DisposableBase = Disposable()

        try:
            resource = resource_factory()
            if resource is not None:
                disp = resource

            source = observable_factory(resource)
        except Exception as exception:  # pylint: disable=broad-except
            d = reactivex.throw(exception).subscribe(observer,
                                                     scheduler=scheduler)
            return CompositeDisposable(d, disp)

        return CompositeDisposable(
            source.subscribe(observer, scheduler=scheduler), disp)
Example #21
0
File: zip.py Project: lizh06/RxPY
    def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> CompositeDisposable:
        n = len(sources)
        queues: List[List[Any]] = [[] for _ in range(n)]
        lock = RLock()
        is_completed = [False] * n

        @synchronized(lock)
        def next_(i: int) -> None:
            if all(len(q) for q in queues):
                try:
                    queued_values = [x.pop(0) for x in queues]
                    res = tuple(queued_values)
                except Exception as ex:  # pylint: disable=broad-except
                    observer.on_error(ex)
                    return

                observer.on_next(res)

                # after sending the zipped values, complete the observer if at least one
                # upstream observable is completed and its queue has length zero
                if any((done for queue, done in zip(queues, is_completed)
                        if len(queue) == 0)):
                    observer.on_completed()

        def completed(i: int) -> None:
            is_completed[i] = True
            if len(queues[i]) == 0:
                observer.on_completed()

        subscriptions: List[Optional[abc.DisposableBase]] = [None] * n

        def func(i: int) -> None:
            source: Observable[Any] = sources[i]
            if isinstance(source, Future):
                source = from_future(source)

            sad = SingleAssignmentDisposable()

            def on_next(x: Any) -> None:
                queues[i].append(x)
                next_(i)

            sad.disposable = source.subscribe(on_next,
                                              observer.on_error,
                                              lambda: completed(i),
                                              scheduler=scheduler)
            subscriptions[i] = sad

        for idx in range(n):
            func(idx)
        return CompositeDisposable(subscriptions)
Example #22
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            group = CompositeDisposable()
            is_stopped = [False]
            m = SingleAssignmentDisposable()
            group.add(m)

            def on_next(inner_source: Union[Observable[_T], "Future[_T]"]):
                inner_subscription = SingleAssignmentDisposable()
                group.add(inner_subscription)

                inner_source = (from_future(inner_source) if isinstance(
                    inner_source, Future) else inner_source)

                @synchronized(source.lock)
                def on_completed():
                    group.remove(inner_subscription)
                    if is_stopped[0] and len(group) == 1:
                        observer.on_completed()

                on_next: typing.OnNext[_T] = synchronized(source.lock)(
                    observer.on_next)
                on_error = synchronized(source.lock)(observer.on_error)
                subscription = inner_source.subscribe(on_next,
                                                      on_error,
                                                      on_completed,
                                                      scheduler=scheduler)
                inner_subscription.disposable = subscription

            def on_completed():
                is_stopped[0] = True
                if len(group) == 1:
                    observer.on_completed()

            m.disposable = source.subscribe(on_next,
                                            observer.on_error,
                                            on_completed,
                                            scheduler=scheduler)
            return group
Example #23
0
def test_groupdisposable_clear():
    disp1 = [False]
    disp2 = [False]

    def action1():
        disp1[0] = True

    d1 = Disposable(action1)

    def action2():
        disp2[0] = True

    d2 = Disposable(action2)

    g = CompositeDisposable(d1, d2)
    assert g.length == 2

    g.clear()
    assert disp1[0]
    assert disp2[0]
    assert not g.length

    disp3 = [False]

    def action3():
        disp3[0] = True

    d3 = Disposable(action3)
    g.add(d3)
    assert not disp3[0]
    assert g.length == 1
Example #24
0
File: _do.py Project: lizh06/RxPY
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:

            was_invoked = [False]

            def on_completed():
                observer.on_completed()
                try:
                    if not was_invoked[0]:
                        finally_action()
                        was_invoked[0] = True
                except Exception as err:  # pylint: disable=broad-except
                    observer.on_error(err)

            def on_error(exception: Exception):
                observer.on_error(exception)
                try:
                    if not was_invoked[0]:
                        finally_action()
                        was_invoked[0] = True
                except Exception as err:  # pylint: disable=broad-except
                    observer.on_error(err)

            composite_disposable = CompositeDisposable()
            composite_disposable.add(OnDispose(was_invoked))
            subscription = source.subscribe(observer.on_next,
                                            on_error,
                                            on_completed,
                                            scheduler=scheduler)
            composite_disposable.add(subscription)

            return composite_disposable
Example #25
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            inner_subscription = SerialDisposable()
            has_latest = [False]
            is_stopped = [False]
            latest = [0]

            def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None:
                nonlocal source

                d = SingleAssignmentDisposable()
                with source.lock:
                    latest[0] += 1
                    _id = latest[0]
                has_latest[0] = True
                inner_subscription.disposable = d

                # Check if Future or Observable
                if isinstance(inner_source, Future):
                    obs = from_future(inner_source)
                else:
                    obs = inner_source

                def on_next(x: Any) -> None:
                    if latest[0] == _id:
                        observer.on_next(x)

                def on_error(e: Exception) -> None:
                    if latest[0] == _id:
                        observer.on_error(e)

                def on_completed() -> None:
                    if latest[0] == _id:
                        has_latest[0] = False
                        if is_stopped[0]:
                            observer.on_completed()

                d.disposable = obs.subscribe(
                    on_next, on_error, on_completed, scheduler=scheduler
                )

            def on_completed() -> None:
                is_stopped[0] = True
                if not has_latest[0]:
                    observer.on_completed()

            subscription = source.subscribe(
                on_next, observer.on_error, on_completed, scheduler=scheduler
            )
            return CompositeDisposable(subscription, inner_subscription)
Example #26
0
    def subscribe(
            observer: abc.ObserverBase[Any],
            scheduler: Optional[abc.SchedulerBase] = None
    ) -> CompositeDisposable:

        n = len(sources)
        has_value = [False] * n
        has_value_all = [False]
        is_done = [False] * n
        values = [None] * n

        def _next(i: Any) -> None:
            has_value[i] = True

            if has_value_all[0] or all(has_value):
                res = tuple(values)
                observer.on_next(res)

            elif all([x for j, x in enumerate(is_done) if j != i]):
                observer.on_completed()

            has_value_all[0] = all(has_value)

        def done(i: Any) -> None:
            is_done[i] = True
            if all(is_done):
                observer.on_completed()

        subscriptions: List[Optional[SingleAssignmentDisposable]] = [None] * n

        def func(i: int) -> None:
            subscriptions[i] = SingleAssignmentDisposable()

            def on_next(x: Any) -> None:
                with parent.lock:
                    values[i] = x
                    _next(i)

            def on_completed() -> None:
                with parent.lock:
                    done(i)

            subscription = subscriptions[i]
            assert subscription
            subscription.disposable = sources[i].subscribe(on_next,
                                                           observer.on_error,
                                                           on_completed,
                                                           scheduler=scheduler)

        for idx in range(n):
            func(idx)
        return CompositeDisposable(subscriptions)
Example #27
0
            def subscribe(
                observer: abc.ObserverBase[_TResult],
                scheduler: Optional[abc.SchedulerBase] = None,
            ) -> abc.DisposableBase:
                assert subject_factory
                connectable = source.pipe(
                    ops.multicast(subject=subject_factory(scheduler)))
                assert mapper
                subscription = mapper(connectable).subscribe(
                    observer, scheduler=scheduler)

                return CompositeDisposable(subscription,
                                           connectable.connect(scheduler))
Example #28
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            def on_completed(_: _T) -> None:
                observer.on_completed()

            return CompositeDisposable(
                source.subscribe(observer, scheduler=scheduler),
                obs.subscribe(
                    on_completed, observer.on_error, noop, scheduler=scheduler
                ),
            )
Example #29
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()

            def action(scheduler: abc.SchedulerBase, state: Any = None):
                observer.on_completed()

            disp = _scheduler.schedule_relative(duration, action)
            return CompositeDisposable(
                disp, source.subscribe(observer, scheduler=scheduler_)
            )
Example #30
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )
            cancelable = SerialDisposable()
            has_value = [False]
            value: List[_T] = [cast(_T, None)]
            _id: List[int] = [0]

            def on_next(x: _T) -> None:
                has_value[0] = True
                value[0] = x
                _id[0] += 1
                current_id = _id[0]
                d = SingleAssignmentDisposable()
                cancelable.disposable = d

                def action(scheduler: abc.SchedulerBase,
                           state: Any = None) -> None:
                    if has_value[0] and _id[0] == current_id:
                        observer.on_next(value[0])
                    has_value[0] = False

                d.disposable = _scheduler.schedule_relative(duetime, action)

            def on_error(exception: Exception) -> None:
                cancelable.dispose()
                observer.on_error(exception)
                has_value[0] = False
                _id[0] += 1

            def on_completed() -> None:
                cancelable.dispose()
                if has_value[0]:
                    observer.on_next(value[0])

                observer.on_completed()
                has_value[0] = False
                _id[0] += 1

            subscription = source.subscribe(on_next,
                                            on_error,
                                            on_completed,
                                            scheduler=scheduler_)
            return CompositeDisposable(subscription, cancelable)