Ejemplo n.º 1
0
def find_value(source, predicate, yield_index):
    def subscribe(observer):
        i = [0]

        def on_next(x):
            should_run = False
            try:
                should_run = predicate(x, i, source)
            except Exception as ex:
                observer.on_error(ex)
                return

            if should_run:
                observer.on_next(i[0] if yield_index else x)
                observer.on_completed()
            else:
                i[0] += 1

        def on_completed():
            observer.on_next(-1 if yield_index else None)
            observer.on_completed()

        return source.subscribe(on_next, observer.on_error, on_completed)

    return AnonymousObservable(subscribe)
Ejemplo n.º 2
0
def take_until(self, other):
    """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.
    """

    source = self
    other = Observable.from_future(other)

    def subscribe(observer):
        def on_completed(x):
            observer.on_completed()

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

    return AnonymousObservable(subscribe)
Ejemplo n.º 3
0
def transduce(self, transducer):
    """Execute a transducer to transform the observable sequence.

    Keyword arguments:
    :param Transducer transducer: A transducer to execute.

    :returns: An Observable sequence containing the results from the
        transducer.
    :rtype: Observable
    """
    source = self

    def subscribe(observer):
        xform = transducer(Observing(observer))

        def on_next(v):
            try:
                xform.step(observer, v)
            except Exception as e:
                observer.on_error(e)

        def on_completed():
            xform.complete(observer)

        return source.subscribe(on_next, observer.on_error, on_completed)

    return AnonymousObservable(subscribe)
Ejemplo n.º 4
0
Archivo: range.py Proyecto: r0k3/RxPY
def range(cls, start, count, scheduler=None):
    """Generates an observable sequence of integral numbers within a
    specified range, using the specified scheduler to send out observer
    messages.

    1 - res = Rx.Observable.range(0, 10)
    2 - res = Rx.Observable.range(0, 10, rx.Scheduler.timeout)

    Keyword arguments:
    start -- The value of the first integer in the sequence.
    count -- The number of sequential integers to generate.
    scheduler -- [Optional] Scheduler to run the generator loop on. If not
        specified, defaults to Scheduler.current_thread.

    Returns an observable sequence that contains a range of sequential
    integral numbers.
    """

    scheduler = scheduler or current_thread_scheduler

    def subscribe(observer):
        def action(scheduler, i):
            if i < count:
                observer.on_next(start + i)
                scheduler(i + 1)
            else:
                observer.on_completed()

        return scheduler.schedule_recursive(action, 0)

    return AnonymousObservable(subscribe)
Ejemplo n.º 5
0
    def sample_observable(self, sampler):
        source = self

        def subscribe(observer):
            at_end = None
            has_value = None
            value = None

            def sample_subscribe(x):
                nonlocal has_value

                if has_value:
                    has_value = False
                    observer.on_next(value)

                if at_end:
                    observer.on_completed()

            def on_next(new_value):
                nonlocal value, has_value

                has_value = True
                value = new_value

            def on_completed():
                nonlocal at_end

                at_end = True

            return CompositeDisposable(
                source.subscribe(on_next, observer.on_error, on_completed),
                sampler.subscribe(sample_subscribe, observer.on_error,
                                  sample_subscribe))

        return AnonymousObservable(subscribe)
Ejemplo n.º 6
0
def debounce(self, duetime, scheduler=None):
    """Ignores values from an observable sequence which are followed by
    another value before duetime.

    Example:
    1 - res = source.debounce(5000) # 5 seconds
    2 - res = source.debounce(5000, scheduler)

    Keyword arguments:
    duetime -- {Number} Duration of the throttle period for each value
        (specified as an integer denoting milliseconds).
    scheduler -- {Scheduler} [Optional]  Scheduler to run the throttle
        timers on. If not specified, the timeout scheduler is used.

    Returns {Observable} The debounced sequence.
    """

    scheduler = scheduler or timeout_scheduler
    source = self

    def subscribe(observer):
        cancelable = SerialDisposable()
        has_value = [False]
        value = [None]
        _id = [0]

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

            def action(scheduler, state=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):
            cancelable.dispose()
            observer.on_error(exception)
            has_value[0] = False
            _id[0] += 1

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

    return AnonymousObservable(subscribe)
Ejemplo n.º 7
0
    def using(cls, resource_factory, observable_factory):
        """Constructs an observable sequence that depends on a resource object,
        whose lifetime is tied to the resulting observable sequence's lifetime.
      
        1 - res = Rx.Observable.using(function () { return new AsyncSubject(); }, function (s) { return s; });
    
        Keyword arguments:
        resource_factory -- Factory function to obtain a resource object.
        observable_factory -- Factory function to obtain an observable sequence
            that depends on the obtained resource.
     
        Returns an observable sequence whose lifetime controls the lifetime of 
        the dependent resource object.
        """
        def subscribe(observer):
            disposable = Disposable.empty()
            try:
                resource = resource_factory()
                if resource:
                    disposable = resource

                source = observable_factory(resource)
            except Exception as exception:
                d = Observable.throw_exception(exception).subscribe(observer)
                return CompositeDisposable(d, disposable)

            return CompositeDisposable(source.subscribe(observer), disposable)

        return AnonymousObservable(subscribe)
    def zip_array(self, second, result_selector):
        first = self

        def subscribe(observer):
            length = len(second)
            index = 0

            def on_next(left):
                nonlocal index

                if index < length:
                    right = second[index]
                    index += 1
                    try:
                        result = result_selector(left, right)
                    except Exception as e:
                        observer.on_error(e)
                        return

                    observer.on_next(result)
                else:
                    observer.on_completed()

            return first.subscribe(on_next, observer.on_error,
                                   observer.on_completed)

        return AnonymousObservable(subscribe)
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def concat(sources):
    def subscribe(observer):
        e = iter(sources)
        is_disposed = False
        subscription = SerialDisposable()

        def action(action1, state=None):
            current = None

            if is_disposed:
                return
            try:
                current = next(e)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe(observer.on_next,
                                                 observer.on_error,
                                                 lambda: action1())

        cancelable = immediate_scheduler.schedule_recursive(action)

        def dispose():
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(subscription, cancelable,
                                   Disposable(dispose))

    return AnonymousObservable(subscribe)
Ejemplo n.º 11
0
    def throw_exception(cls, exception, scheduler=None):
        """Returns an observable sequence that terminates with an exception, 
        using the specified scheduler to send out the single OnError message.
    
        1 - res = rx.Observable.throw_exception(new Error('Error'));
        2 - res = rx.Observable.throw_exception(new Error('Error'), Rx.Scheduler.timeout);
     
        Keyword arguments:
        exception -- An object used for the sequence's termination.
        scheduler -- Scheduler to send the exceptional termination call on. If
            not specified, defaults to ImmediateScheduler.
    
        Returns the observable sequence that terminates exceptionally with the 
        specified exception object.
        """
        scheduler = scheduler or immediate_scheduler

        exception = Exception(
            exception) if type(exception) is Exception else exception

        def subscribe(observer):
            def action(scheduler, state):
                observer.on_error(exception)

            return scheduler.schedule(action)

        return AnonymousObservable(subscribe)
Ejemplo n.º 12
0
def materialize(self):
    """Materializes the implicit notifications of an observable sequence as
    explicit notification values.

    Returns an observable sequence containing the materialized notification
    values from the source sequence.
    """

    source = self

    def subscribe(observer):
        def on_next(value):
            observer.on_next(OnNext(value))

        def on_error(exception):
            observer.on_next(OnError(exception))
            observer.on_completed()

        def on_completed():
            observer.on_next(OnCompleted())
            observer.on_completed()

        return source.subscribe(on_next, on_error, on_completed)

    return AnonymousObservable(subscribe)
Ejemplo n.º 13
0
def return_value(cls, value, scheduler=None):
    """Returns an observable sequence that contains a single element,
    using the specified scheduler to send out observer messages.
    There is an alias called 'just'.

    example
    res = rx.Observable.return(42)
    res = rx.Observable.return(42, rx.Scheduler.timeout)

    Keyword arguments:
    value -- Single element in the resulting observable sequence.
    scheduler -- [Optional] Scheduler to send the single element on. If
        not specified, defaults to Scheduler.immediate.

    Returns an observable sequence containing the single specified
    element.
    """

    scheduler = scheduler or current_thread_scheduler

    def subscribe(observer):
        def action(scheduler, state=None):
            observer.on_next(value)
            observer.on_completed()

        return scheduler.schedule(action)
    return AnonymousObservable(subscribe)
Ejemplo n.º 14
0
def sample_observable(source, sampler):
    def subscribe(observer):
        at_end = [None]
        has_value = [None]
        value = [None]

        def sample_subscribe(x=None):
            if has_value[0]:
                has_value[0] = False
                observer.on_next(value[0])

            if at_end[0]:
                observer.on_completed()

        def on_next(new_value):
            has_value[0] = True
            value[0] = new_value

        def on_completed():
            at_end[0] = True

        return CompositeDisposable(
            source.subscribe(on_next, observer.on_error, on_completed),
            sampler.subscribe(sample_subscribe, observer.on_error,
                              sample_subscribe))

    return AnonymousObservable(subscribe)
Ejemplo n.º 15
0
def defer(cls, observable_factory):
    """Returns an observable sequence that invokes the specified factory
    function whenever a new observer subscribes.

    Example:
    1 - res = rx.Observable.defer(lambda: rx.Observable.from_([1,2,3]))

    Keyword arguments:
    :param types.FunctionType observable_factory: Observable factory function
        to invoke for each observer that subscribes to the resulting sequence.

    :returns: An observable sequence whose observers trigger an invocation
    of the given observable factory function.
    :rtype: Observable
    """
    def subscribe(observer):
        try:
            result = observable_factory()
        except Exception as ex:
            return Observable.throw_exception(ex).subscribe(observer)

        result = Observable.from_future(result)
        return result.subscribe(observer)

    return AnonymousObservable(subscribe)
Ejemplo n.º 16
0
    def function(*args):
        arguments = list(args)

        def subscribe(observer):
            def handler(*args):
                results = list(args)
                if selector:
                    try:
                        results = selector(args)
                    except Exception as err:
                        observer.on_error(err)
                        return

                    observer.on_next(results)
                else:
                    if isinstance(results, list) and len(results) <= 1:
                        observer.on_next(*results)
                    else:
                        observer.on_next(results)

                    observer.on_completed()

            arguments.append(handler)
            func(*arguments)

        return AnonymousObservable(subscribe)
Ejemplo n.º 17
0
    def from_array(cls, array, scheduler):
        """Converts an array to an observable sequence, using an optional 
        scheduler to enumerate the array.
    
        1 - res = rx.Observable.from_array([1,2,3])
        2 - res = rx.Observable.from_array([1,2,3], rx.Scheduler.timeout)
     
        Keyword arguments:
        scheduler -- [Optional] Scheduler to run the enumeration of the input sequence on.
     
        Returns the observable sequence whose elements are pulled from the 
        given enumerable sequence.
        """

        scheduler = scheduler or current_thread_scheduler

        def subscribe(observer):
            count = 0

            def action(action1, state=None):
                nonlocal count

                if count < len(array):
                    observer.on_next(array[count])
                    count += 1
                    action1(action)
                else:
                    observer.on_completed()

            return scheduler.schedule_recursive(action)

        return AnonymousObservable(subscribe)
def take_until_with_time(self, end_time, scheduler=None):
    """Takes elements for the specified duration until the specified end
    time, using the specified scheduler to run timers.

    Examples:
    1 - res = source.take_until_with_time(dt, [optional scheduler])
    2 - res = source.take_until_with_time(5000, [optional scheduler])

    Keyword Arguments:
    end_time -- {Number | Date} Time to stop taking elements from the source
        sequence. If this value is less than or equal to Date(), the
        result stream will complete immediately.
    scheduler -- {Scheduler} Scheduler to run the timer on.

    Returns an observable {Observable} sequence with the elements taken
    until the specified end time.
    """

    scheduler = scheduler or timeout_scheduler
    source = self

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

    def subscribe(observer):
        def action(scheduler, state):
            observer.on_completed()

        task = scheduler_method(end_time, action)
        return CompositeDisposable(task, source.subscribe(observer))

    return AnonymousObservable(subscribe)
Ejemplo n.º 19
0
def catch_handler(source, handler):
    def subscribe(observer):
        d1 = SingleAssignmentDisposable()
        subscription = SerialDisposable()

        subscription.disposable = d1

        def on_error(exception):
            try:
                result = handler(exception)
            except Exception as ex:
                observer.on_error(ex)
                return

            result = Observable.from_future(result)
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer)

        d1.disposable = source.subscribe(
            observer.on_next,
            on_error,
            observer.on_completed
        )
        return subscription
    return AnonymousObservable(subscribe)
Ejemplo n.º 20
0
def from_iterable(cls, iterable, scheduler=None):
    """Converts an array to an observable sequence, using an optional
    scheduler to enumerate the array.

    1 - res = rx.Observable.from_iterable([1,2,3])
    2 - res = rx.Observable.from_iterable([1,2,3], rx.Scheduler.timeout)

    Keyword arguments:
    :param Observable cls: Observable class
    :param Scheduler scheduler: [Optional] Scheduler to run the
        enumeration of the input sequence on.

    :returns: The observable sequence whose elements are pulled from the
        given enumerable sequence.
    :rtype: Observable
    """

    scheduler = scheduler or current_thread_scheduler

    def subscribe(observer):
        iterator = iter(iterable)

        def action(action1, state=None):
            try:
                item = next(iterator)
            except StopIteration:
                observer.on_completed()
            else:
                observer.on_next(item)
                action1(action)

        return scheduler.schedule_recursive(action)

    return AnonymousObservable(subscribe)
Ejemplo n.º 21
0
    def catch_exception(cls, *args):
        """Continues an observable sequence that is terminated by an
        exception with the next observable sequence.

        1 - res = Observable.catch_exception(xs, ys, zs)
        2 - res = Observable.catch_exception([xs, ys, zs])

        Returns an observable sequence containing elements from consecutive
        source sequences until a source sequence terminates successfully.
        """

        if isinstance(args[0], list) or isinstance(args[0], Enumerable):
            sources = args[0]
        else:
            sources = list(args)

        #return Enumerable.catch_exception(Enumerable.for_each(sources))

        def subscribe(observer):
            e = iter(sources)
            is_disposed = [False]
            last_exception = [None]
            subscription = SerialDisposable()

            def action(action1, state=None):
                current = None

                def on_error(exn):
                    last_exception[0] = exn
                    action1()

                if is_disposed[0]:
                    return
                try:
                    current = six.next(e)
                except StopIteration:
                    if last_exception[0]:
                        observer.on_error(last_exception[0])
                    else:
                        observer.on_completed()
                except Exception as ex:
                    observer.on_error(ex)
                else:
                    d = SingleAssignmentDisposable()
                    subscription.disposable = d

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

            cancelable = immediate_scheduler.schedule_recursive(action)

            def dispose():
                is_disposed[0] = True

            return CompositeDisposable(subscription, cancelable,
                                       Disposable(dispose))

        return AnonymousObservable(subscribe)
Ejemplo n.º 22
0
def zip_array(cls, *args):
    """Merges the specified observable sequences into one observable
    sequence by emitting a list with the elements of the observable
    sequences at corresponding indexes.

    Keyword arguments:
    args -- Observable sources.

    Returns an observable {Observable} sequence containing lists of elements
    at corresponding indexes.
    """

    sources = list(args)

    def subscribe(observer):
        n = len(sources)
        queues = [[] for _ in range(n)]
        is_done = [False] * n

        def next(i):
            if all([len(q) for q in queues]):
                res = [x.pop(0) for x in queues]
                observer.on_next(res)
            elif all([x for j, x in enumerate(is_done) if j != i]):
                observer.on_completed()
                return

        def done(i):
            is_done[i] = True
            if all(is_done):
                observer.on_completed()
                return

        subscriptions = [None] * n

        def func(i):
            subscriptions[i] = SingleAssignmentDisposable()

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

            subscriptions[i].disposable = sources[i].subscribe(
                on_next, observer.on_error, lambda: done(i))

        for idx in range(n):
            func(idx)

        composite_disposable = CompositeDisposable(subscriptions)

        def action():
            for _ in queues:
                queues[n] = []

        composite_disposable.add(Disposable.create(action))

        return composite_disposable

    return AnonymousObservable(subscribe)
Ejemplo n.º 23
0
    def generate(cls,
                 initial_state,
                 condition,
                 iterate,
                 result_selector,
                 scheduler=None):
        """Generates an observable sequence by running a state-driven loop 
        producing the sequence's elements, using the specified scheduler to 
        send out observer messages.
     
        1 - res = rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; });
        2 - res = rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout);
        
        Keyword arguments:
        initial_state -- Initial state.
        condition -- Condition to terminate generation (upon returning false).
        iterate -- Iteration step function.
        result_selector -- Selector function for results produced in the sequence.
        scheduler -- [Optional] Scheduler on which to run the generator loop. 
            If not provided, defaults to CurrentThreadScheduler.
    
        Returns the generated sequence.
        """

        scheduler = scheduler or current_thread_scheduler

        def subscribe(observer):
            first = True
            state = initial_state

            def action(action1, state1=None):
                nonlocal first, state
                has_result = False
                result = None

                try:
                    if first:
                        first = False
                    else:
                        state = iterate(state)

                    has_result = condition(state)
                    if has_result:
                        result = result_selector(state)

                except Exception as exception:
                    observer.on_error(exception)
                    return

                if has_result:
                    observer.on_next(result)
                    action1()
                else:
                    observer.on_completed()

            return scheduler.schedule_recursive(action)

        return AnonymousObservable(subscribe)
Ejemplo n.º 24
0
    def switch_latest(self):
        """Transforms an observable sequence of observable sequences into an 
        observable sequence producing values only from the most recent 
        observable sequence.
        
        Returns the observable sequence that at any point in time produces the 
        elements of the most recent inner observable sequence that has been received.  
        """

        sources = self

        def subscribe(observer):
            has_latest = False
            inner_subscription = SerialDisposable()
            is_stopped = False
            latest = 0

            def on_next(inner_source):
                nonlocal latest, has_latest

                d = SingleAssignmentDisposable()
                latest += 1
                _id = latest
                has_latest = True
                inner_subscription.disposable = d

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

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

                def on_completed():
                    nonlocal has_latest

                    if latest == _id:
                        has_latest = False
                        if is_stopped:
                            observer.on_completed()

                d.disposable = inner_source.subscribe(on_next, on_error,
                                                      on_completed)

            def on_completed():
                nonlocal is_stopped

                is_stopped = True
                if not has_latest:
                    observer.on_completed()

            subscription = sources.subscribe(on_next, observer.on_error,
                                             on_completed)
            return CompositeDisposable(subscription, inner_subscription)

        return AnonymousObservable(subscribe)
Ejemplo n.º 25
0
    def observable_timer_date(duetime, scheduler):
        def subscribe(observer):
            def action(scheduler, state):
                observer.on_next(0)
                observer.on_completed()

            return scheduler.schedule_absolute(duetime, action)

        return AnonymousObservable(subscribe)
Ejemplo n.º 26
0
def switch_latest(self):
    """Transforms an observable sequence of observable sequences into an
    observable sequence producing values only from the most recent
    observable sequence.

    :returns: The observable sequence that at any point in time produces the
    elements of the most recent inner observable sequence that has been
    received.
    :rtype: Observable
    """

    sources = self

    def subscribe(observer):
        has_latest = [False]
        inner_subscription = SerialDisposable()
        is_stopped = [False]
        latest = [0]

        def on_next(inner_source):
            d = SingleAssignmentDisposable()
            with self.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)

            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)

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

        subscription = sources.subscribe(on_next, observer.on_error,
                                         on_completed)
        return CompositeDisposable(subscription, inner_subscription)

    return AnonymousObservable(subscribe)
Ejemplo n.º 27
0
    def return_value(cls, value, scheduler=None):
        scheduler = scheduler or immediate_scheduler

        def subscribe(observer):
            def action(scheduler, state=None):
                observer.on_next(value)
                observer.on_completed()

            return scheduler.schedule(action)
        return AnonymousObservable(subscribe)
Ejemplo n.º 28
0
    def never(cls):
        """Returns a non-terminating observable sequence, which can be used to 
        denote an infinite duration (e.g. when using reactive joins).
     
        Returns an observable sequence whose observers will never get called.
        """
        def subscribe(observer):
            return Disposable.empty()

        return AnonymousObservable(subscribe)
Ejemplo n.º 29
0
    def observable_timer_timespan(duetime, scheduler):
        d = Scheduler.normalize(duetime)

        def subscribe(observer):
            def action(scheduler, state):
                observer.on_next(0)
                observer.on_completed()

            return scheduler.schedule_relative(d, action)

        return AnonymousObservable(subscribe)
Ejemplo n.º 30
0
    def throttle(self, duetime, scheduler):
        scheduler = scheduler or timeout_scheduler
        source = self

        def subscribe(observer):
            cancelable = SerialDisposable()
            has_value = False
            value = None
            _id = 0

            def on_next(x):
                nonlocal _id, value, has_value, cancelable

                has_value = True
                value = x
                _id += 1
                current_id = _id
                d = SingleAssignmentDisposable()
                cancelable.disposable = d

                def action(scheduler, state=None):
                    nonlocal has_value
                    if has_value and _id == current_id:
                        observer.on_next(value)
                    has_value = False

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

            def on_error(exception):
                nonlocal _id, has_value, cancelable

                cancelable.dispose()
                observer.on_error(exception)
                has_value = False
                _id += 1

            def on_completed():
                nonlocal cancelable, has_value, _id

                cancelable.dispose()
                if has_value:
                    observer.on_next(value)

                observer.on_completed()
                has_value = False
                _id += 1

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

        return AnonymousObservable(subscribe)