Пример #1
0
def _if_then(condition: Callable[[], bool], then_source: Observable,
             else_source: Observable = None) -> Observable:
    """Determines whether an observable collection contains values.

    Example:
    1 - res = rx.if_then(condition, obs1)
    2 - res = rx.if_then(condition, obs1, obs2)

    Args:
        condition: The condition which determines if the then_source or
            else_source will be run.
        then_source: The observable sequence or Promise that
            will be run if the condition function returns true.
        else_source: [Optional] The observable sequence or
            Promise that will be run if the condition function returns
            False. If this is not provided, it defaults to
            rx.empty

    Returns:
        An observable sequence which is either the then_source or
        else_source.
    """

    else_source = else_source or rx.empty()

    then_source = rx.from_future(then_source) if is_future(then_source) else then_source
    else_source = rx.from_future(else_source) if is_future(else_source) else else_source

    def factory(_: abc.Scheduler):
        return then_source if condition() else else_source

    return rx.defer(factory)
Пример #2
0
            def on_next(inner_source: Union[Observable, Future]):
                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 is_future(inner_source):
                    obs = from_future(cast(Future, inner_source))
                else:
                    obs = cast(Observable, 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)
Пример #3
0
        def on_next(inner_source):
            nonlocal sources

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

            # Check if Future or Observable
            inner_source = Observable.from_future(inner_source) if is_future(
                inner_source) else inner_source

            def on_next(x):
                if latest[0] == _id:
                    observer.on_next(x)

            def on_error(e):
                if latest[0] == _id:
                    observer.on_error(e)

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

            d.disposable = inner_source.subscribe_(on_next, on_error,
                                                   on_completed)
Пример #4
0
            def on_next(inner_source: Observable):
                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
                inner_source = from_future(inner_source) if is_future(inner_source) else 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 = inner_source.subscribe_(on_next, on_error, on_completed, scheduler=scheduler)
Пример #5
0
def from_future(cls, future):
    """Converts a Future to an Observable sequence

    Keyword Arguments:
    future -- {Future} A Python 3 compatible future.
        https://docs.python.org/3/library/asyncio-task.html#future
        http://www.tornadoweb.org/en/stable/concurrent.html#tornado.concurrent.Future

    Returns {Observable} An Observable sequence which wraps the existing
    future success and failure.
    """
    def subscribe(observer):
        def done(future):
            try:
                value = future.result()
            except Exception as ex:
                observer.on_error(ex)
            else:
                observer.on_next(value)
                observer.on_completed()

        future.add_done_callback(done)

        def dispose():
            if future and future.cancel:
                future.cancel()

        return dispose

    return AnonymousObservable(subscribe) if is_future(future) else future
Пример #6
0
    def from_future(future):
        """Converts a Future to an Observable sequence

        Keyword Arguments:
        future -- {Future} A Python 3 compatible future.
            https://docs.python.org/3/library/asyncio-task.html#future
            http://www.tornadoweb.org/en/stable/concurrent.html#tornado.concurrent.Future

        Returns {Observable} An Observable sequence which wraps the existing
        future success and failure."""

        def subscribe(observer):
            def done(future):
                try:
                    value = future.result()
                except Exception as ex:
                    observer.on_error(ex)
                else:
                    observer.on_next(value)
                    observer.on_completed()

            future.add_done_callback(done)

            def dispose():
                if future and future.cancel:
                  future.cancel()
            return dispose

        return AnonymousObservable(subscribe) if is_future(future) else future
Пример #7
0
def _take_until(other: Observable) -> Callable[[Observable], Observable]:
    other = from_future(other) if is_future(other) else other

    def take_until(source: Observable) -> Observable:
        """Returns the values from the source observable sequence until
        the other observable sequence produces a value.

        Args:
            source: The source observable sequence.

        Returns:
            An observable sequence containing the elements of the source
            sequence up to the point the other sequence interrupted
            further propagation.
        """
        def subscribe(observer, scheduler=None):
            def on_completed(_):
                observer.on_completed()

            return CompositeDisposable(
                source.subscribe(observer),
                other.subscribe_(on_completed, observer.on_error, noop,
                                 scheduler))

        return Observable(subscribe)

    return take_until
Пример #8
0
 def projection(x, i):
     mapper_result = mapper(x) if mapper else mapper_indexed(x, i)
     if isinstance(mapper_result, collections.Iterable):
         result = Observable.from_(mapper_result)
     else:
         result = Observable.from_future(mapper_result) if is_future(mapper_result) else mapper_result
     return result
Пример #9
0
def _take_until(other: Observable) -> Callable[[Observable], Observable]:
    other = from_future(other) if is_future(other) else other

    def take_until(source: Observable) -> Observable:
        """Returns the values from the source observable sequence until
        the other observable sequence produces a value.

        Args:
            source: The source observable sequence.

        Returns:
            An observable sequence containing the elements of the source
            sequence up to the point the other sequence interrupted
            further propagation.
        """

        def subscribe(observer, scheduler=None):

            def on_completed(_):
                observer.on_completed()

            return CompositeDisposable(
                source.subscribe(observer),
                other.subscribe_(on_completed, observer.on_error, noop, scheduler)
            )
        return Observable(subscribe)
    return take_until
Пример #10
0
def take_until(source: ObservableBase,
               other: ObservableBase) -> ObservableBase:
    """Returns the values from the source observable sequence until the
    other observable sequence produces a value.

    Keyword arguments:
    other -- Observable sequence that terminates propagation of elements
        of the source sequence.

    Returns an observable sequence containing the elements of the source
    sequence up to the point the other sequence interrupted further
    propagation.
    """

    other = Observable.from_future(other) if is_future(other) else other

    def subscribe(observer, scheduler=None):
        def on_completed(_):
            observer.on_completed()

        return CompositeDisposable(
            source.subscribe(observer),
            other.subscribe_(on_completed, observer.on_error, noop, scheduler))

    return AnonymousObservable(subscribe)
Пример #11
0
    def subscribe(observer, scheduler=None):
        try:
            result = observable_factory(scheduler)
        except Exception as ex:
            return Observable.throw(ex).subscribe(observer)

        result = Observable.from_future(result) if is_future(result) else result
        return result.subscribe(observer, scheduler)
Пример #12
0
 def projection(x, i):
     mapper_result = mapper(x) if mapper else mapper_indexed(x, i)
     if isinstance(mapper_result, collections.abc.Iterable):
         result = from_(mapper_result)
     else:
         result = from_future(mapper_result) if is_future(
             mapper_result) else mapper_result
     return result
Пример #13
0
    def subscribe(observer, scheduler=None):
        try:
            result = factory(scheduler)
        except Exception as ex:  # By design. pylint: disable=W0703
            return throw(ex).subscribe(observer)

        result = from_future(result) if is_future(result) else result
        return result.subscribe(observer, scheduler=scheduler)
Пример #14
0
 def accumulate():
     has_accumulator_value = accumulator_value[0] is not NotSet
     if has_accumulator_value:
         acc_source = accumulator(accumulator_value[0], value)
         return from_future(acc_source) if is_future(
             acc_source) else acc_source
     else:
         return of(value)
Пример #15
0
    def subscribe(observer, scheduler=None):
        try:
            result = observable_factory(scheduler)
        except Exception as ex:  # By design. pylint: disable=W0703
            return throw(ex).subscribe(observer)

        result = from_future(result) if is_future(result) else result
        return result.subscribe(observer, scheduler=scheduler)
Пример #16
0
    def factory(_) -> Observable:
        try:
            result = sources[mapper()]
        except KeyError:
            result = default_source

        result = from_future(result) if is_future(result) else result

        return result
Пример #17
0
    def factory(_) -> Observable:
        try:
            result = sources[mapper()]
        except KeyError:
            result = default_source

        result = from_future(result) if is_future(result) else result

        return result
Пример #18
0
            def projection(x: Any, idx: int) -> Any:
                mapper_result = mapper(x)
                if isinstance(mapper_result, collections.abc.Iterable):
                    result = Observable.from_(mapper_result)
                else:
                    result = Observable.from_future(
                        mapper_result) if is_future(
                            mapper_result) else mapper_result

                return result.map(lambda y: result_mapper(x, y))
Пример #19
0
        def on_error(exception):
            try:
                result = handler(exception)
            except Exception as ex:
                observer.on_error(ex)
                return

            result = Observable.from_future(result) if is_future(result) else result
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer, scheduler)
Пример #20
0
        def func(i):
            source = sources[i]
            sad = SingleAssignmentDisposable()
            source = from_future(source) if is_future(source) else source

            def on_next(x):
                queues[i].append(x)
                next(i)

            sad.disposable = source.subscribe_(on_next, observer.on_error, lambda: completed(i), scheduler)
            subscriptions[i] = sad
Пример #21
0
        def projection(x: Any, idx: int) -> Any:
            mapper_result = mapper(x) if mapper else mapper_indexed(x, idx)
            if isinstance(mapper_result, collections.Iterable):
                result = Observable.from_(mapper_result)
            else:
                result = Observable.from_future(mapper_result) if is_future(mapper_result) else mapper_result

            if result_mapper:
                return result.map(lambda y: result_mapper(x, y))
            else:
                return result.map(mapper_indexed=lambda y, i: result_mapper_indexed(x, y, i))
Пример #22
0
        def on_error(exception):
            try:
                result = handler(exception, source)
            except Exception as ex:  # By design. pylint: disable=W0703
                observer.on_error(ex)
                return

            result = rx.from_future(result) if is_future(result) else result
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer, scheduler=scheduler)
Пример #23
0
        def on_error(exception):
            try:
                result = handler(exception, source)
            except Exception as ex:  # By design. pylint: disable=W0703
                observer.on_error(ex)
                return

            result = rx.from_future(result) if is_future(result) else result
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer, scheduler=scheduler)
Пример #24
0
        def func(i):
            source = sources[i]
            sad = SingleAssignmentDisposable()
            source = from_future(source) if is_future(source) else source

            def on_next(x):
                queues[i].append(x)
                next(i)

            sad.disposable = source.subscribe_(on_next, observer.on_error, lambda: done(i), scheduler)
            subscriptions[i] = sad
Пример #25
0
        def on_next(inner_source):
            inner_subscription = SingleAssignmentDisposable()
            group.add(inner_subscription)

            inner_source = Observable.from_future(inner_source) if is_future(inner_source) else inner_source

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

            disposable = inner_source.subscribe_(observer.on_next, observer.on_error, on_completed, scheduler)
            inner_subscription.disposable = disposable
Пример #26
0
    def while_do(source: Observable) -> Observable:
        """Repeats source as long as condition holds emulating a while
        loop.

        Args:
            source: The observable sequence that will be run if the
                condition function returns true.

        Returns:
            An observable sequence which is repeated as long as the
            condition holds.
        """
        source = rx.from_future(source) if is_future(source) else source
        return rx.concat_with_iterable(itertools.takewhile(condition, (source for x in infinite())))
Пример #27
0
def _skip_until(other: Observable) -> Callable[[Observable], Observable]:
    """Returns the values from the source observable sequence only after
    the other observable sequence produces a value.

    Args:
        other: The observable sequence that triggers propagation of
            elements of the source sequence.

    Returns:
        An observable sequence containing the elements of the source
    sequence starting from the point the other sequence triggered
    propagation.
    """

    other = rx.from_future(other) if is_future(other) else other

    def skip_until(source: Observable) -> Observable:
        def subscribe(observer, scheduler=None):
            is_open = [False]

            def on_next(left):
                if is_open[0]:
                    observer.on_next(left)

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

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

            right_subscription = SingleAssignmentDisposable()
            subscriptions.add(right_subscription)

            def on_next2(x):
                is_open[0] = True
                right_subscription.dispose()

            def on_completed2():
                right_subscription.dispose()

            right_subscription.disposable = other.subscribe_(
                on_next2, observer.on_error, on_completed2, scheduler)

            return subscriptions

        return Observable(subscribe)

    return skip_until
Пример #28
0
    def while_do(source: Observable) -> Observable:
        """Repeats source as long as condition holds emulating a while
        loop.

        Args:
            source: The observable sequence that will be run if the
                condition function returns true.

        Returns:
            An observable sequence which is repeated as long as the
            condition holds.
        """
        source = rx.from_future(source) if is_future(source) else source
        return rx.concat(
            itertools.takewhile(condition, (source for x in infinite())))
Пример #29
0
            def on_next(inner_source):
                inner_subscription = SingleAssignmentDisposable()
                group.add(inner_subscription)

                inner_source = from_future(inner_source) if is_future(inner_source) 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 = 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)
                inner_subscription.disposable = subscription
Пример #30
0
def while_do(condition, source: ObservableBase) -> ObservableBase:
    """Repeats source as long as condition holds emulating a while loop.

    Keyword arguments:
    condition -- The condition which determines if the source will be
        repeated.
    source -- The observable sequence that will be run if the condition
        function returns true.

    Returns an observable sequence which is repeated as long as the
    condition holds.
    """

    source = Observable.from_future(source) if is_future(source) else source
    from .concat import concat
    return concat(Iterable.while_do(condition, source))
Пример #31
0
def _skip_until(other: Observable) -> Callable[[Observable], Observable]:
    """Returns the values from the source observable sequence only after
    the other observable sequence produces a value.

    Args:
        other: The observable sequence that triggers propagation of
            elements of the source sequence.

    Returns:
        An observable sequence containing the elements of the source
    sequence starting from the point the other sequence triggered
    propagation.
    """

    other = rx.from_future(other) if is_future(other) else other


    def skip_until(source: Observable) -> Observable:
        def subscribe(observer, scheduler=None):
            is_open = [False]

            def on_next(left):
                if is_open[0]:
                    observer.on_next(left)

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

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

            right_subscription = SingleAssignmentDisposable()
            subscriptions.add(right_subscription)

            def on_next2(x):
                is_open[0] = True
                right_subscription.dispose()

            def on_completed2():
                right_subscription.dispose()

            right_subscription.disposable = other.subscribe_(on_next2, observer.on_error, on_completed2, scheduler)

            return subscriptions
        return Observable(subscribe)
    return skip_until
Пример #32
0
    def while_do(source: Union[Observable, Future]) -> Observable:
        """Repeats source as long as condition holds emulating a while
        loop.

        Args:
            source: The observable sequence that will be run if the
                condition function returns true.

        Returns:
            An observable sequence which is repeated as long as the
            condition holds.
        """
        if is_future(source):
            obs = rx.from_future(cast(Future, source))
        else:
            obs = cast(Observable, source)
        it = itertools.takewhile(condition, (obs for _ in infinite()))
        return rx.concat_with_iterable(it)
Пример #33
0
            def on_next(inner_source):
                inner_subscription = SingleAssignmentDisposable()
                group.add(inner_subscription)

                inner_source = from_future(inner_source) if is_future(
                    inner_source) 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 = 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)
                inner_subscription.disposable = subscription
Пример #34
0
        def action(scheduler, state=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 = rx.from_future(source) if is_future(source) else source

            d = SingleAssignmentDisposable()
            subscription.disposable = d

            def on_resume(state=None):
                scheduler.schedule(action, state)

            d.disposable = current.subscribe_(observer.on_next, on_resume, on_resume, scheduler)
Пример #35
0
        def action(scheduler, state=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 = rx.from_future(source) if is_future(source) else source

            d = SingleAssignmentDisposable()
            subscription.disposable = d

            def on_resume(state=None):
                scheduler.schedule(action, state)

            d.disposable = current.subscribe_(observer.on_next, on_resume,
                                              on_resume, scheduler)
Пример #36
0
            def on_next(inner_source):
                if not has_current[0]:
                    has_current[0] = True

                    inner_source = rx.from_future(inner_source) if is_future(
                        inner_source) 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)
Пример #37
0
            def on_next(inner_source):
                if not has_current[0]:
                    has_current[0] = True

                    inner_source = rx.from_future(inner_source) if is_future(inner_source) 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
                    )
Пример #38
0
def _amb(left_source, right_source):
    """Propagates the observable sequence that reacts first.

    right_source Second observable sequence.

    returns an observable sequence that surfaces either of the given
    sequences, whichever reacted first.
    """

    right_source = Observable.from_future(right_source) if is_future(right_source) else right_source

    def subscribe(observer, scheduler=None):
        choice = [None]
        left_choice = 'L'
        right_choice = 'R',
        left_subscription = SingleAssignmentDisposable()
        right_subscription = SingleAssignmentDisposable()

        def choice_left():
            if not choice[0]:
                choice[0] = left_choice
                right_subscription.dispose()

        def choice_right():
            if not choice[0]:
                choice[0] = right_choice
                left_subscription.dispose()

        def on_next_left(value):
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_next(value)

        def on_error_left(err):
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_error(err)

        def on_completed_left():
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_completed()

        lelf_d = left_source.subscribe_(on_next_left, on_error_left, on_completed_left, scheduler)
        left_subscription.disposable = lelf_d

        def send_right(value):
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_next(value)

        def on_error_right(err):
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_error(err)

        def on_completed_right():
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_completed()

        right_d = right_source.subscribe_(send_right, on_error_right, on_completed_right, scheduler)
        right_subscription.disposable = right_d
        return CompositeDisposable(left_subscription, right_subscription)
    return AnonymousObservable(subscribe)
Пример #39
0
def _timeout(duetime: typing.AbsoluteTime, other: Optional[Observable] = None, scheduler: Optional[typing.Scheduler] = None
             ) -> Callable[[Observable], Observable]:

    other = other or throw(Exception("Timeout"))
    other = from_future(other) if is_future(other) else other

    def timeout(source: Observable) -> Observable:
        """Returns the source observable sequence or the other observable
        sequence if duetime elapses.

        Examples:
            >>> res = timeout(source)

        Args:
            source: Source observable to timeout

        Returns:
            An obserable sequence switching to the other sequence in
            case of a timeout.
        """
        def subscribe(observer, scheduler_=None):
            _scheduler = scheduler or scheduler_ or timeout_scheduler

            if isinstance(duetime, datetime):
                scheduler_method = _scheduler.schedule_absolute
            else:
                scheduler_method = _scheduler.schedule_relative

            switched = [False]
            _id = [0]

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

            def create_timer():
                my_id = _id[0]

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

                timer.disposable = scheduler_method(duetime, action)

            create_timer()

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

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

            def on_completed():
                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_)
            return CompositeDisposable(subscription, timer)
        return Observable(subscribe)
    return timeout
Пример #40
0
def _amb(left_source, right_source):
    right_source = Observable.from_future(right_source) if is_future(
        right_source) else right_source

    def subscribe(observer, scheduler=None):
        choice = [None]
        left_choice = 'L'
        right_choice = 'R'
        left_subscription = SingleAssignmentDisposable()
        right_subscription = SingleAssignmentDisposable()

        def choice_left():
            if not choice[0]:
                choice[0] = left_choice
                right_subscription.dispose()

        def choice_right():
            if not choice[0]:
                choice[0] = right_choice
                left_subscription.dispose()

        def on_next_left(value):
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_next(value)

        def on_error_left(err):
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_error(err)

        def on_completed_left():
            with left_source.lock:
                choice_left()
            if choice[0] == left_choice:
                observer.on_completed()

        lelf_d = left_source.subscribe_(on_next_left, on_error_left,
                                        on_completed_left, scheduler)
        left_subscription.disposable = lelf_d

        def send_right(value):
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_next(value)

        def on_error_right(err):
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_error(err)

        def on_completed_right():
            with left_source.lock:
                choice_right()
            if choice[0] == right_choice:
                observer.on_completed()

        right_d = right_source.subscribe_(send_right, on_error_right,
                                          on_completed_right, scheduler)
        right_subscription.disposable = right_d
        return CompositeDisposable(left_subscription, right_subscription)

    return AnonymousObservable(subscribe)
Пример #41
0
def _amb(right_source: Observable):

    if is_future(right_source):
        obs = from_future(cast(Future, right_source))
    else:
        obs = cast(Observable, right_source)

    def amb(left_source: Observable):
        def subscribe(observer: typing.Observer, scheduler: typing.Scheduler = None) -> typing.Disposable:
            choice = [None]
            left_choice = 'L'
            right_choice = 'R'
            left_subscription = SingleAssignmentDisposable()
            right_subscription = SingleAssignmentDisposable()

            def choice_left():
                if not choice[0]:
                    choice[0] = left_choice
                    right_subscription.dispose()

            def choice_right():
                if not choice[0]:
                    choice[0] = right_choice
                    left_subscription.dispose()

            def on_next_left(value):
                with left_source.lock:
                    choice_left()
                if choice[0] == left_choice:
                    observer.on_next(value)

            def on_error_left(err):
                with left_source.lock:
                    choice_left()
                if choice[0] == left_choice:
                    observer.on_error(err)

            def on_completed_left():
                with left_source.lock:
                    choice_left()
                if choice[0] == left_choice:
                    observer.on_completed()

            left_d = left_source.subscribe_(on_next_left, on_error_left, on_completed_left, scheduler)
            left_subscription.disposable = left_d

            def send_right(value: Any) -> None:
                with left_source.lock:
                    choice_right()
                if choice[0] == right_choice:
                    observer.on_next(value)

            def on_error_right(err: Exception) -> None:
                with left_source.lock:
                    choice_right()
                if choice[0] == right_choice:
                    observer.on_error(err)

            def on_completed_right() -> None:
                with left_source.lock:
                    choice_right()
                if choice[0] == right_choice:
                    observer.on_completed()

            right_d = obs.subscribe_(send_right, on_error_right, on_completed_right, scheduler)
            right_subscription.disposable = right_d
            return CompositeDisposable(left_subscription, right_subscription)
        return Observable(subscribe)
    return amb
Пример #42
0
def timeout(source: ObservableBase,
            duetime: Union[int, datetime],
            other: ObservableBase = None) -> ObservableBase:
    """Returns the source observable sequence or the other observable
    sequence if duetime elapses.

    1 - res = source.timeout(5000); # 5 seconds
    # As a date and timeout observable
    2 - res = source.timeout(datetime(), Observable.return_value(42))
    # 5 seconds and timeout observable
    3 - res = source.timeout(5000, Observable.return_value(42))
    # As a date and timeout observable

    Keyword arguments:
    duetime -- Absolute (specified as a datetime object) or relative
        time (specified as an integer denoting milliseconds) when a
        timeout occurs.
    other -- Sequence to return in case of a timeout. If not
        specified, a timeout error throwing sequence will be used.

    Returns the source sequence switching to the other sequence in case
        of a timeout.
    """

    other = other or Observable.throw(Exception("Timeout"))
    other = Observable.from_future(other) if is_future(other) else other

    def subscribe(observer, scheduler=None):
        scheduler = scheduler or timeout_scheduler

        if isinstance(duetime, datetime):
            scheduler_method = scheduler.schedule_absolute
        else:
            scheduler_method = scheduler.schedule_relative

        switched = [False]
        _id = [0]

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

        def create_timer():
            my_id = _id[0]

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

            timer.disposable = scheduler_method(duetime, action)

        create_timer()

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

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

        def on_completed():
            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)
        return CompositeDisposable(subscription, timer)

    return AnonymousObservable(subscribe)
Пример #43
0
def _timeout(duetime: typing.AbsoluteTime, other: Optional[Observable] = None, scheduler: Optional[typing.Scheduler] = None
             ) -> Callable[[Observable], Observable]:

    other = other or throw(Exception("Timeout"))
    other = from_future(other) if is_future(other) else other

    def timeout(source: Observable) -> Observable:
        """Returns the source observable sequence or the other observable
        sequence if duetime elapses.

        Examples:
            >>> res = timeout(source)

        Args:
            source: Source observable to timeout

        Returns:
            An obserable sequence switching to the other sequence in
            case of a timeout.
        """
        def subscribe(observer, scheduler_=None):
            _scheduler = scheduler or scheduler_ or timeout_scheduler

            if isinstance(duetime, datetime):
                scheduler_method = _scheduler.schedule_absolute
            else:
                scheduler_method = _scheduler.schedule_relative

            switched = [False]
            _id = [0]

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

            def create_timer():
                my_id = _id[0]

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

                timer.disposable = scheduler_method(duetime, action)

            create_timer()

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

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

            def on_completed():
                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_)
            return CompositeDisposable(subscription, timer)
        return Observable(subscribe)
    return timeout