コード例 #1
0
ファイル: delay.py プロジェクト: JohnWowUs/RxPY
        def on_next(notification):
            log.debug("observable_delay_timespan:subscribe:on_next()")
            should_run = False

            with source.lock:
                if notification.value.kind == 'E':
                    del queue[:]
                    queue.append(notification)
                    exception[0] = notification.value.exception
                    should_run = not running[0]
                else:
                    queue.append(Timestamp(value=notification.value, timestamp=notification.timestamp + duetime))
                    should_run = not active[0]
                    active[0] = True

            if should_run:
                if exception[0]:
                    log.error("*** Exception: %s", exception[0])
                    observer.on_error(exception[0])
                else:
                    mad = MultipleAssignmentDisposable()
                    cancelable.disposable = mad

                    def action(scheduler, state):
                        if exception[0]:
                            log.error("observable_delay_timespan:subscribe:on_next:action(), exception: %s", exception[0])
                            return

                        with source.lock:
                            running[0] = True
                            while True:
                                result = None
                                if len(queue) and queue[0].timestamp <= scheduler.now:
                                    result = queue.pop(0).value

                                if result:
                                    result.accept(observer)

                                if not result:
                                    break

                            should_continue = False
                            recurse_duetime = 0
                            if len(queue):
                                should_continue = True
                                diff = queue[0].timestamp - scheduler.now
                                zero = timedelta(0) if isinstance(diff, timedelta) else 0
                                recurse_duetime = max(zero, diff)
                            else:
                                active[0] = False

                            ex = exception[0]
                            running[0] = False

                        if ex:
                            observer.on_error(ex)
                        elif should_continue:
                            mad.disposable = scheduler.schedule_relative(recurse_duetime, action)

                    mad.disposable = scheduler.schedule_relative(duetime, action)
コード例 #2
0
ファイル: schedulerbase.py プロジェクト: JohnWowUs/RxPY
    def schedule_periodic(self, period, action, state=None):
        """Schedules a periodic piece of work to be executed in the tkinter
        mainloop.

        Keyword arguments:
        period -- Period in milliseconds for running the work periodically.
        action -- Action to be executed.
        state -- [Optional] Initial state passed to the action upon the first
            iteration.

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

        disposable = MultipleAssignmentDisposable()
        state = [state]

        def invoke_action(scheduler, _):
            if disposable.is_disposed:
                return

            new_state = action(state[0])
            if new_state is not None:
                state[0] = new_state
            disposable.disposable = self.schedule_relative(period, invoke_action, state)

        disposable.disposable = self.schedule_relative(period, invoke_action, state)
        return disposable
コード例 #3
0
ファイル: generate.py プロジェクト: cobain/ipython
    def subscribe(observer):
        first = [True]
        state = [initial_state]
        mad = MultipleAssignmentDisposable()

        def action(scheduler, state1=None):
            has_result = False
            result = None

            try:
                if first[0]:
                    first[0] = False
                else:
                    state[0] = iterate(state[0])

                has_result = condition(state[0])
                if has_result:
                    result = result_selector(state[0])

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

            if has_result:
                observer.on_next(result)
                mad.disposable = scheduler.schedule(action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule(action)
        return mad
コード例 #4
0
ファイル: schedulerbase.py プロジェクト: xyicheng/RxPY
    def schedule_periodic(self, period, action, state=None):
        """Schedules a periodic piece of work to be executed in the tkinter
        mainloop.

        Keyword arguments:
        period -- Period in milliseconds for running the work periodically.
        action -- Action to be executed.
        state -- [Optional] Initial state passed to the action upon the first
            iteration.

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

        disposable = MultipleAssignmentDisposable()
        state = [state]

        def invoke_action(scheduler, _):
            if disposable.is_disposed:
                return

            new_state = action(state[0])
            if new_state is not None:
                state[0] = new_state
            disposable.disposable = self.schedule_relative(period, invoke_action, state)

        disposable.disposable = self.schedule_relative(period, invoke_action, state)
        return disposable
コード例 #5
0
    def subscribe(observer):
        first = [True]
        state = [initial_state]
        mad = MultipleAssignmentDisposable()

        def action(scheduler, state1=None):
            has_result = False
            result = None

            try:
                if first[0]:
                    first[0] = False
                else:
                    state[0] = iterate(state[0])

                has_result = condition(state[0])
                if has_result:
                    result = result_selector(state[0])

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

            if has_result:
                observer.on_next(result)
                mad.disposable = scheduler.schedule(action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule(action)
        return mad
コード例 #6
0
    def subscribe(observer):
        mad = MultipleAssignmentDisposable()
        state = [initial_state]
        has_result = [False]
        result = [None]
        first = [True]
        time = [None]

        def action(scheduler, _):
            if has_result[0]:
                observer.on_next(result[0])

            try:
                if first[0]:
                    first[0] = False
                else:
                    state[0] = iterate(state[0])

                has_result[0] = condition(state[0])
                if has_result[0]:
                    result[0] = result_selector(state[0])
                    time[0] = time_selector(state[0])

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

            if has_result[0]:
                mad.disposable = scheduler.schedule_relative(time[0], action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule_relative(0, action)
        return mad
コード例 #7
0
    def subscribe(observer):
        mad = MultipleAssignmentDisposable()
        state = [initial_state]
        has_result = [False]
        result = [None]
        first = [True]
        time = [None]

        def action(scheduler, _):
            if has_result[0]:
                observer.on_next(result[0])

            try:
                if first[0]:
                    first[0] = False
                else:
                    state[0] = iterate(state[0])

                has_result[0] = condition(state[0])
                if has_result[0]:
                    result[0] = result_selector(state[0])
                    time[0] = time_selector(state[0])

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

            if has_result[0]:
                mad.disposable = scheduler.schedule_relative(time[0], action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule_relative(0, action)
        return mad
コード例 #8
0
    def subscribe(observer):
        sd = MultipleAssignmentDisposable()

        def action(scheduler, n):
            if n < end:
                observer.on_next(n)
                sd.disposable = scheduler.schedule(action, n + 1)
            else:
                observer.on_completed()

        sd.disposable = scheduler.schedule(action, start)
        return sd
コード例 #9
0
ファイル: range.py プロジェクト: cobain/ipython
    def subscribe(observer):
        sd = MultipleAssignmentDisposable()

        def action(scheduler, n):
            if n < end:
                observer.on_next(n)
                sd.disposable = scheduler.schedule(action, n + 1)
            else:
                observer.on_completed()

        sd.disposable = scheduler.schedule(action, start)
        return sd
コード例 #10
0
ファイル: range.py プロジェクト: xyicheng/RxPY
    def subscribe(observer, scheduler=None):
        nonlocal range_t

        scheduler = scheduler or current_thread_scheduler
        sd = MultipleAssignmentDisposable()

        def action(scheduler, iterator):
            try:
                observer.on_next(next(iterator))
                sd.disposable = scheduler.schedule(action, state=iterator)
            except StopIteration:
                observer.on_completed()

        sd.disposable = scheduler.schedule(action, iter(range_t))
        return sd
コード例 #11
0
ファイル: range.py プロジェクト: zmyer/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
    sd = MultipleAssignmentDisposable()
    end = start + count

    def subscribe(observer):
        def action(scheduler, n):
            if n < end:
                observer.on_next(n)
                sd.disposable = scheduler.schedule(action, n + 1)
            else:
                observer.on_completed()

        sd.disposable = scheduler.schedule(action, start)
        return sd

    return AnonymousObservable(subscribe)
コード例 #12
0
ファイル: fromiterable.py プロジェクト: cobain/ipython
    def subscribe(observer):
        sd = MultipleAssignmentDisposable()
        iterator = iter(iterable)

        def action(scheduler, state=None):
            try:
                with lock:
                    item = next(iterator)

            except StopIteration:
                observer.on_completed()
            else:
                observer.on_next(item)
                sd.disposable = scheduler.schedule(action)

        sd.disposable = scheduler.schedule(action)
        return sd
コード例 #13
0
    def subscribe(observer):
        sd = MultipleAssignmentDisposable()
        iterator = iter(iterable)

        def action(scheduler, state=None):
            try:
                with lock:
                    item = next(iterator)

            except StopIteration:
                observer.on_completed()
            else:
                observer.on_next(item)
                sd.disposable = scheduler.schedule(action)

        sd.disposable = scheduler.schedule(action)
        return sd
コード例 #14
0
ファイル: timer.py プロジェクト: JohnWowUs/RxPY
    def subscribe(observer):
        mad = MultipleAssignmentDisposable()
        dt = [duetime]
        count = [0]

        def action(scheduler, state):
            if p > 0:
                now = scheduler.now
                dt[0] = dt[0] + scheduler.to_timedelta(p)
                if dt[0] <= now:
                    dt[0] = now + scheduler.to_timedelta(p)

            observer.on_next(count[0])
            count[0] += 1
            mad.disposable = scheduler.schedule_absolute(dt[0], action)
        mad.disposable = scheduler.schedule_absolute(dt[0], action)
        return mad
コード例 #15
0
    def subscribe(observer):
        mad = MultipleAssignmentDisposable()
        dt = [duetime]
        count = [0]

        def action(scheduler, state):
            if p > 0:
                now = scheduler.now
                dt[0] = dt[0] + scheduler.to_timedelta(p)
                if dt[0] <= now:
                    dt[0] = now + scheduler.to_timedelta(p)

            observer.on_next(count[0])
            count[0] += 1
            mad.disposable = scheduler.schedule_absolute(dt[0], action)

        mad.disposable = scheduler.schedule_absolute(dt[0], action)
        return mad
コード例 #16
0
    def subscribe(observer, scheduler=None):
        nonlocal duetime

        if isinstance(duetime, int):
            duetime = scheduler.now + scheduler.to_timedelta(duetime)

        p = scheduler.normalize(period)
        mad = MultipleAssignmentDisposable()
        dt = [duetime]
        count = [0]

        def action(scheduler, state):
            if p > 0:
                now = scheduler.now
                dt[0] = dt[0] + scheduler.to_timedelta(p)
                if dt[0] <= now:
                    dt[0] = now + scheduler.to_timedelta(p)

            observer.on_next(count[0])
            count[0] += 1
            mad.disposable = scheduler.schedule_absolute(dt[0], action)

        mad.disposable = scheduler.schedule_absolute(dt[0], action)
        return mad
コード例 #17
0
    def schedule_relative(self,
                          timedelta: Union[int, float],
                          action: Callable[[Scheduler, Any], None],
                          state=None):
        disposable = [MultipleAssignmentDisposable()]

        def _():
            def __():
                def func():
                    action(self, state)

                future = self.executor.submit(func)
                disposable[0] = Disposable.create(lambda: future.cancel())

            self.loop.call_later(timedelta, __)

        future = self.loop.call_soon_threadsafe(_)
        # super().schedule_relative(timedelta, __)
        return CompositeDisposable(disposable,
                                   Disposable.create(lambda: future.cancel()))
コード例 #18
0
ファイル: fromiterable.py プロジェクト: zmyer/RxPY
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
    sd = MultipleAssignmentDisposable()
    lock = config["concurrency"].RLock()

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

        def action(scheduler, state=None):
            try:
                with lock:
                    item = next(iterator)
            except StopIteration:
                observer.on_completed()
            else:
                observer.on_next(item)
                sd.disposable = scheduler.schedule(action)

        sd.disposable = scheduler.schedule(action)
        return sd

    return AnonymousObservable(subscribe)
コード例 #19
0
    def unsafe_subscribe(self, observer, scheduler, subscribe_scheduler):
        state = [self.WaitForLeftOrRight()]
        inner_left_completed = [0]
        right_completed = [False]
        inner_disposable = MultipleAssignmentDisposable()

        source = self

        def on_next_left(left_elem):
            ack = Ack()

            with self.lock:
                if isinstance(state[0], self.WaitForLeftOrRight):
                    new_state = self.WaitForRightOrInner(left_ack=ack)
                elif isinstance(state[0], self.WaitForLeft):
                    state_: source.WaitForLeft = state[0]
                    new_state = self.Active(left_ack=ack,
                                            right_elem=state_.right_elem,
                                            right_ack=state_.right_ack,
                                            upper_ack=Continue())
                elif isinstance(state[0], source.Completed):
                    return stop_ack
                else:
                    raise NotImplementedError
                state[0] = new_state

            class ChildObserver(Observer):
                def __init__(self, out: Observer, scheduler):
                    self.out = out
                    self.scheduler = scheduler

                def on_next(self, inner_left):
                    ack = Ack()
                    has_right_elem = False
                    right_elem = None

                    with source.lock:
                        if isinstance(state[0], source.WaitForRightOrInner):
                            # not much to do
                            state_typed: source.WaitForRightOrInner = state[0]
                            state[0] = source.WaitForRight(
                                inner_left_elem=inner_left,
                                left_ack=state_typed.left_ack,
                                inner_left_ack=ack,
                                left_elem=source.selector_left(left_elem))
                        elif isinstance(state[0], source.Active):
                            # send zipped item to observer
                            state_typed: source.Active = state[0]
                            has_right_elem = True
                            right_elem = state_typed.right_elem
                            state[0] = source.Active(
                                left_ack=state_typed.left_ack,
                                right_elem=state_typed.right_elem,
                                right_ack=state_typed.right_ack,
                                upper_ack=ack)
                        elif isinstance(state[0], source.Completed):
                            return stop_ack
                        else:
                            raise NotImplementedError

                    if has_right_elem:
                        # send triple to observer
                        zipped_elem = source.selector(
                            source.selector_left(left_elem), right_elem,
                            inner_left)
                        upper_ack = observer.on_next(zipped_elem)

                        # race condition with on_completed
                        if isinstance(state[0], source.Active):
                            typed_state: source.Active = state[0]
                            typed_state.upper_ack = upper_ack

                        if isinstance(upper_ack, Stop):
                            with source.lock:
                                state[0] = source.Completed()
                        else:

                            def _(v):
                                if isinstance(v, Stop):
                                    with source.lock:
                                        state[0] = source.Completed()

                            upper_ack.observe_on(scheduler).subscribe(_)
                        return upper_ack
                    else:
                        return ack

                def on_error(self, err):
                    with source.lock:
                        state[0] = source.Completed()
                        observer.on_error(err)

                def on_completed(self):
                    back_pressure_right = False
                    back_pressure_left = False
                    left_ack = None
                    right_ack = None
                    upper_ack = None
                    complete_observer = False

                    with source.lock:
                        if isinstance(state[0], source.Active):
                            # normal complete

                            if right_completed[0]:
                                state[0] = source.Completed()
                                complete_observer = True
                            else:
                                # request new left and new right
                                state_typed: source.Active = state[0]
                                back_pressure_right = True
                                back_pressure_left = True
                                left_ack = state_typed.left_ack
                                right_ack = state_typed.right_ack
                                upper_ack = state_typed.upper_ack
                                state[0] = source.WaitForLeftOrRight()
                        elif isinstance(state[0], source.WaitForRightOrInner):
                            # empty inner observable

                            state_typed: source.WaitForRight = state[0]
                            # count up number of inner completed (without right completed)
                            inner_left_completed[0] += 1
                            state[0] = source.WaitForLeftOrRight()
                            back_pressure_left = True
                            left_ack = state_typed.left_ack
                            upper_ack = Continue()

                    if complete_observer:
                        observer.on_completed()

                    if back_pressure_left or back_pressure_right:

                        def _(v):
                            if isinstance(v, Stop):
                                with source.lock:
                                    state[0] = source.Completed()

                        upper_ack.subscribe(_)

                    if back_pressure_left:
                        # upper_ack should not be Stop
                        if isinstance(upper_ack, Continue):
                            left_ack.on_next(upper_ack)
                            left_ack.on_completed()
                        else:
                            upper_ack.observe_on(scheduler).subscribe(left_ack)

                    if back_pressure_right:
                        if isinstance(upper_ack, Continue):
                            right_ack.on_next(upper_ack)
                            right_ack.on_completed()
                        else:
                            upper_ack.observe_on(scheduler).subscribe(
                                right_ack)

            child = self.selector_inner(left_elem)
            child_observer = ChildObserver(observer, scheduler)

            disposable = child.subscribe(child_observer, scheduler,
                                         CurrentThreadScheduler())
            inner_disposable.disposable = disposable

            return ack

        def on_next_right(right):
            ack = Ack()
            upper_ack = None
            has_inner_left_elem = False
            request_left_right = False
            request_right = False

            with self.lock:
                if 0 < inner_left_completed[0]:
                    inner_left_completed[0] -= 1
                    request_right = True
                    upper_ack = Continue()
                    # new_state = self.WaitForLeftOrRight()
                    new_state = state[0]
                elif isinstance(state[0], self.WaitForLeftOrRight):
                    new_state = self.WaitForLeft(right_elem=right,
                                                 right_ack=ack)
                elif isinstance(state[0], self.WaitForRightOrInner):
                    state_: FlatZipObservable.WaitForRightOrInner = state[0]
                    if inner_left_completed[0] == 0:
                        new_state = self.Active(left_ack=state_.left_ack,
                                                right_elem=right,
                                                right_ack=ack,
                                                upper_ack=Continue())
                    else:
                        inner_left_completed[0] -= 1
                        new_state = self.WaitForLeftOrRight()
                elif isinstance(state[0], self.WaitForRight):
                    state_: FlatZipObservable.WaitForRight = state[0]
                    has_inner_left_elem = True
                    left_elem = state_.left_elem
                    left_ack = state_.left_ack
                    inner_left_elem = state_.inner_left_elem
                    inner_left_ack = state_.inner_left_ack
                    new_state = state[0]
                elif isinstance(state[0], source.Completed):
                    return stop_ack
                else:
                    raise NotImplementedError
                state[0] = new_state

            if has_inner_left_elem:
                zipped_elem = self.selector(left_elem, right, inner_left_elem)
                upper_ack = observer.on_next(zipped_elem)

                if isinstance(upper_ack, Stop):
                    with self.lock:
                        state[0] = self.Completed
                        return upper_ack

                request_inner_elem = False
                with self.lock:
                    if 0 < inner_left_completed[0]:
                        # inner left completed, request new left and right
                        new_state = self.WaitForLeftOrRight()
                        request_left_right = True
                    else:
                        # state is the same, change state to active
                        new_state = self.Active(left_ack=left_ack,
                                                right_elem=right,
                                                right_ack=ack,
                                                upper_ack=upper_ack)
                        request_inner_elem = True
                    state[0] = new_state

                if request_inner_elem:
                    if isinstance(upper_ack, Continue) or isinstance(
                            upper_ack, Stop):
                        inner_left_ack.on_next(upper_ack)
                        inner_left_ack.on_completed()
                    else:
                        upper_ack.observe_on(scheduler).subscribe(
                            inner_left_ack)

                if request_left_right:
                    if isinstance(upper_ack, Continue):
                        left_ack.on_next(upper_ack)
                        left_ack.on_completed()
                    else:
                        upper_ack.observe_on(scheduler).subscribe(left_ack)

            if request_left_right or request_right:
                if isinstance(upper_ack, Continue):
                    ack.on_next(upper_ack)
                    ack.on_completed()
                else:
                    upper_ack.observe_on(scheduler).subscribe(ack)

            return ack

        def on_completed_left():
            with self.lock:
                if isinstance(state[0], self.Completed):
                    return

                if isinstance(state[0], self.WaitForLeftOrRight) or isinstance(
                        state[0], self.WaitForLeft):
                    new_state = self.Completed()
                else:
                    new_state = state[0]
                state[0] = new_state

            if isinstance(state[0], self.Completed):
                return observer.on_completed()

        def on_completed_right():
            with self.lock:
                if isinstance(state[0], self.Completed):
                    return

                if isinstance(state[0], self.WaitForLeftOrRight) or isinstance(state[0], self.WaitForRightOrInner) \
                        or isinstance(state[0], self.WaitForRightOrInner):
                    new_state = self.Completed()
                else:
                    new_state = state[0]
                    right_completed[0] = True
                state[0] = new_state

            if isinstance(state[0], self.Completed):
                return observer.on_completed()

        class LeftObserver(Observer):
            def on_next(self, v):
                return on_next_left(v)

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

            def on_completed(self):
                return on_completed_left()

        class RightObserver(Observer):
            def on_next(self, v):
                return on_next_right(v)

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

            def on_completed(self):
                return on_completed_right()

        left_observer = LeftObserver()
        d1 = self.left.unsafe_subscribe(left_observer, scheduler,
                                        subscribe_scheduler)

        right_observer = RightObserver()
        d2 = self.right.unsafe_subscribe(right_observer, scheduler,
                                         subscribe_scheduler)

        return CompositeDisposable(d1, d2, inner_disposable)
コード例 #20
0
ファイル: delay.py プロジェクト: Darwin939/macmeharder_back
        def on_next(notification):
            log.debug("observable_delay_timespan:subscribe:on_next()")
            should_run = False

            with source.lock:
                if notification.value.kind == 'E':
                    del queue[:]
                    queue.append(notification)
                    exception[0] = notification.value.exception
                    should_run = not running[0]
                else:
                    queue.append(
                        Timestamp(value=notification.value,
                                  timestamp=notification.timestamp + duetime))
                    should_run = not active[0]
                    active[0] = True

            if should_run:
                if exception[0]:
                    log.error("*** Exception: %s", exception[0])
                    observer.on_error(exception[0])
                else:
                    mad = MultipleAssignmentDisposable()
                    cancelable.disposable = mad

                    def action(scheduler, state):
                        if exception[0]:
                            log.error(
                                "observable_delay_timespan:subscribe:on_next:action(), exception: %s",
                                exception[0])
                            return

                        with source.lock:
                            running[0] = True
                            while True:
                                result = None
                                if len(queue) and queue[
                                        0].timestamp <= scheduler.now:
                                    result = queue.pop(0).value

                                if result:
                                    result.accept(observer)

                                if not result:
                                    break

                            should_continue = False
                            recurse_duetime = 0
                            if len(queue):
                                should_continue = True
                                diff = queue[0].timestamp - scheduler.now
                                zero = timedelta(0) if isinstance(
                                    diff, timedelta) else 0
                                recurse_duetime = max(zero, diff)
                            else:
                                active[0] = False

                            ex = exception[0]
                            running[0] = False

                        if ex:
                            observer.on_error(ex)
                        elif should_continue:
                            mad.disposable = scheduler.schedule_relative(
                                recurse_duetime, action)

                    mad.disposable = scheduler.schedule_relative(
                        duetime, action)
コード例 #21
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,
        lambda x: x < 10,
        lambda x: x + 1,
        lambda x: x)
    2 - res = rx.Observable.generate(0,
        lambda x: x < 10,
        lambda x: x + 1,
        lambda x: 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
    mad = MultipleAssignmentDisposable()

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

        def action(scheduler, state1=None):
            has_result = False
            result = None

            try:
                if first[0]:
                    first[0] = False
                else:
                    state[0] = iterate(state[0])

                has_result = condition(state[0])
                if has_result:
                    result = result_selector(state[0])

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

            if has_result:
                observer.on_next(result)
                mad.disposable = scheduler.schedule(action)
            else:
                observer.on_completed()

        mad.disposable = scheduler.schedule(action)
        return mad

    return AnonymousObservable(subscribe)