示例#1
0
    def test_timeout_schedule_action(self):
        scheduler = TimeoutScheduler()
        ran = False

        def action(scheduler, state):
            nonlocal ran
            ran = True

        scheduler.schedule(action)

        sleep(0.1)
        assert ran is True
示例#2
0
    def test_timeout_schedule_action_cancel(self):
        ran = False
        scheduler = TimeoutScheduler()

        def action(scheduler, state):
            nonlocal ran
            ran = True

        d = scheduler.schedule_relative(timedelta(milliseconds=300), action)
        d.dispose()

        sleep(0.1)
        assert ran is False
示例#3
0
    def test_timeout_schedule_action_due(self):
        scheduler = TimeoutScheduler()
        starttime = default_now()
        endtime = None

        def action(scheduler, state):
            nonlocal endtime
            endtime = default_now()

        scheduler.schedule_relative(timedelta(milliseconds=200), action)

        sleep(0.4)
        assert endtime is not None
        diff = endtime - starttime
        assert diff > timedelta(milliseconds=180)
示例#4
0
 def test_timeout_now_units(self):
     scheduler = TimeoutScheduler()
     diff = scheduler.now
     sleep(1.1)
     diff = scheduler.now - diff
     assert timedelta(milliseconds=1000) < diff < timedelta(
         milliseconds=1300)
示例#5
0
文件: timer.py 项目: lizh06/RxPY
    def subscribe(
            observer: abc.ObserverBase[int],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
        nonlocal duetime

        if not isinstance(duetime, datetime):
            duetime = _scheduler.now + _scheduler.to_timedelta(duetime)

        p = max(0.0, _scheduler.to_seconds(period))
        mad = MultipleAssignmentDisposable()
        dt = duetime
        count = 0

        def action(scheduler: abc.SchedulerBase, state: Any) -> None:
            nonlocal dt
            nonlocal count

            if p > 0.0:
                now = scheduler.now
                dt = dt + scheduler.to_timedelta(p)
                if dt <= now:
                    dt = now + scheduler.to_timedelta(p)

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

        mad.disposable = _scheduler.schedule_absolute(dt, action)
        return mad
示例#6
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            duration = _scheduler.to_timedelta(window_duration or 0.0)
            if duration <= _scheduler.to_timedelta(0):
                raise ValueError(
                    "window_duration cannot be less or equal zero.")
            last_on_next: Optional[datetime] = None

            def on_next(x: _T) -> None:
                nonlocal last_on_next
                emit = False
                now = _scheduler.now

                with source.lock:
                    if not last_on_next or now - last_on_next >= duration:
                        last_on_next = now
                        emit = True
                if emit:
                    observer.on_next(x)

            return source.subscribe(on_next,
                                    observer.on_error,
                                    observer.on_completed,
                                    scheduler=_scheduler)
示例#7
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            nonlocal duration

            _scheduler: abc.SchedulerBase = (scheduler or scheduler_
                                             or TimeoutScheduler.singleton())
            duration = _scheduler.to_timedelta(duration)
            q: List[Dict[str, Any]] = []

            def on_next(x: _T) -> None:
                now = _scheduler.now
                q.append({"interval": now, "value": x})
                while q and now - q[0]["interval"] >= duration:
                    observer.on_next(q.pop(0)["value"])

            def on_completed() -> None:
                now = _scheduler.now
                while q and now - q[0]["interval"] >= duration:
                    observer.on_next(q.pop(0)["value"])

                observer.on_completed()

            return source.subscribe(on_next,
                                    observer.on_error,
                                    on_completed,
                                    scheduler=_scheduler)
示例#8
0
文件: _timestamp.py 项目: lizh06/RxPY
        def factory(scheduler_: Optional[abc.SchedulerBase] = None):
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            def mapper(value: _T) -> Timestamp[_T]:
                return Timestamp(value=value, timestamp=_scheduler.now)

            return source.pipe(operators.map(mapper))
示例#9
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            switched = [False]
            _id = [0]

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

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

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

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

            create_timer()

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

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

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

            original.disposable = source.subscribe(on_next,
                                                   on_error,
                                                   on_completed,
                                                   scheduler=scheduler_)
            return CompositeDisposable(subscription, timer)
示例#10
0
    def test_timeout_singleton(self):
        scheduler = [TimeoutScheduler(), TimeoutScheduler.singleton()]
        assert scheduler[0] is scheduler[1]

        gate = [threading.Semaphore(0), threading.Semaphore(0)]
        scheduler = [None, None]

        def run(idx):
            scheduler[idx] = TimeoutScheduler()
            gate[idx].release()

        for idx in (0, 1):
            threading.Thread(target=run, args=(idx, )).start()
            gate[idx].acquire()

        assert scheduler[0] is not None
        assert scheduler[1] is not None
        assert scheduler[0] is scheduler[1]
示例#11
0
    def test_timeout_extend(self):
        class MyScheduler(TimeoutScheduler):
            pass

        scheduler = [
            MyScheduler(),
            MyScheduler.singleton(),
            TimeoutScheduler.singleton(),
        ]
        assert scheduler[0] is scheduler[1]
        assert scheduler[0] is not scheduler[2]
示例#12
0
文件: timer.py 项目: lizh06/RxPY
    def subscribe(
            observer: abc.ObserverBase[int],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler: abc.SchedulerBase = (scheduler or scheduler_
                                         or TimeoutScheduler.singleton())

        def action(scheduler: abc.SchedulerBase, state: Any) -> None:
            observer.on_next(0)
            observer.on_completed()

        return _scheduler.schedule_absolute(duetime, action)
示例#13
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()

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

            disp = _scheduler.schedule_relative(duration, action)
            return CompositeDisposable(
                disp, source.subscribe(observer, scheduler=scheduler_)
            )
示例#14
0
文件: timer.py 项目: lizh06/RxPY
    def subscribe(
            observer: abc.ObserverBase[int],
            scheduler_: Optional[abc.SchedulerBase] = None
    ) -> abc.DisposableBase:
        _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
        d = _scheduler.to_seconds(duetime)

        def action(scheduler: abc.SchedulerBase, state: Any) -> None:
            observer.on_next(0)
            observer.on_completed()

        if d <= 0.0:
            return _scheduler.schedule(action)
        return _scheduler.schedule_relative(d, action)
示例#15
0
文件: timer.py 项目: lizh06/RxPY
        def subscribe(
            observer: abc.ObserverBase[int],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler: abc.SchedulerBase = (scheduler or scheduler_
                                             or TimeoutScheduler.singleton())

            def action(count: Optional[int] = None) -> Optional[int]:
                if count is not None:
                    observer.on_next(count)
                    return count + 1
                return None

            if not isinstance(_scheduler, PeriodicScheduler):
                raise ValueError("Sceduler must be PeriodicScheduler")
            return _scheduler.schedule_periodic(period, action, state=0)
示例#16
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )
            cancelable = SerialDisposable()
            has_value = [False]
            value: List[_T] = [cast(_T, None)]
            _id: List[int] = [0]

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

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

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

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

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

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

            subscription = source.subscribe(on_next,
                                            on_error,
                                            on_completed,
                                            scheduler=scheduler_)
            return CompositeDisposable(subscription, cancelable)
示例#17
0
    def subscribe(
        observer: abc.ObserverBase[_TState],
        scheduler: Optional[abc.SchedulerBase] = None,
    ) -> abc.DisposableBase:
        scheduler = scheduler or TimeoutScheduler.singleton()
        mad = MultipleAssignmentDisposable()
        state = initial_state
        has_result = False
        result: _TState = cast(_TState, None)
        first = True
        time: Optional[RelativeTime] = None

        def action(scheduler: abc.SchedulerBase, _: Any) -> None:
            nonlocal state
            nonlocal has_result
            nonlocal result
            nonlocal first
            nonlocal time

            if has_result:
                observer.on_next(result)

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

                has_result = condition(state)

                if has_result:
                    result = state
                    time = time_mapper(state)

            except Exception as e:  # pylint: disable=broad-except
                observer.on_error(e)
                return

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

        mad.disposable = scheduler.schedule_relative(0, action)
        return mad
示例#18
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

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

            if isinstance(end_time, datetime):
                task = _scheduler.schedule_absolute(end_time, action)
            else:
                task = _scheduler.schedule_relative(end_time, action)

            return CompositeDisposable(
                task, source.subscribe(observer, scheduler=scheduler_))
示例#19
0
        def subscribe(
            observer: abc.ObserverBase[TimeInterval[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )
            last = _scheduler.now

            def mapper(value: _T) -> TimeInterval[_T]:
                nonlocal last

                now = _scheduler.now
                span = now - last
                last = now
                return TimeInterval(value=value, interval=span)

            return source.pipe(ops.map(mapper)).subscribe(observer,
                                                          scheduler=_scheduler)
示例#20
0
文件: toasync.py 项目: lizh06/RxPY
def to_async_(
    func: Callable[..., _T],
    scheduler: Optional[abc.SchedulerBase] = None
) -> Callable[..., Observable[_T]]:
    """Converts the function into an asynchronous function. Each
    invocation of the resulting asynchronous function causes an
    invocation of the original synchronous function on the specified
    scheduler.

    Examples:
        res = reactivex.to_async(lambda x, y: x + y)(4, 3)
        res = reactivex.to_async(lambda x, y: x + y, Scheduler.timeout)(4, 3)
        res = reactivex.to_async(lambda x: log.debug(x), Scheduler.timeout)('hello')

    Args:
        func: Function to convert to an asynchronous function.
        scheduler: [Optional] Scheduler to run the function on. If not
            specified, defaults to Scheduler.timeout.

    Returns:
        Aynchronous function.
    """

    _scheduler = scheduler or TimeoutScheduler.singleton()

    def wrapper(*args: Any) -> Observable[_T]:
        subject: AsyncSubject[_T] = AsyncSubject()

        def action(scheduler: abc.SchedulerBase, state: Any = None) -> None:
            try:
                result = func(*args)
            except Exception as ex:  # pylint: disable=broad-except
                subject.on_error(ex)
                return

            subject.on_next(result)
            subject.on_completed()

        _scheduler.schedule(action)
        return subject.pipe(ops.as_observable())

    return wrapper
示例#21
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ):
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()
            open = [False]

            def action(scheduler: abc.SchedulerBase, state: Any) -> None:
                open[0] = True

            t = _scheduler.schedule_relative(duration, action)

            def on_next(x: _T):
                if open[0]:
                    observer.on_next(x)

            d = source.subscribe(
                on_next, observer.on_error, observer.on_completed, scheduler=scheduler_
            )
            return CompositeDisposable(t, d)
示例#22
0
        def subscribe(
            observer: abc.ObserverBase[_T],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ):
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            open = [False]

            def on_next(x: _T) -> None:
                if open[0]:
                    observer.on_next(x)

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

            def action(scheduler: abc.SchedulerBase, state: Any):
                open[0] = True

            disp = getattr(_scheduler, scheduler_method)(start_time, action)
            return CompositeDisposable(disp, subscription)
示例#23
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            n: int = 0
            s: Subject[_T] = Subject()
            timer_d = SerialDisposable()
            window_id = 0
            group_disposable = CompositeDisposable(timer_d)
            ref_count_disposable = RefCountDisposable(group_disposable)

            def create_timer(_id: int):
                nonlocal n, s, window_id
                m = SingleAssignmentDisposable()
                timer_d.disposable = m

                def action(scheduler: abc.SchedulerBase, state: Any = None):
                    nonlocal n, s, window_id
                    if _id != window_id:
                        return

                    n = 0
                    window_id += 1
                    new_id = window_id
                    s.on_completed()
                    s = Subject()
                    observer.on_next(add_ref(s, ref_count_disposable))
                    create_timer(new_id)

                m.disposable = _scheduler.schedule_relative(timespan, action)

            observer.on_next(add_ref(s, ref_count_disposable))
            create_timer(0)

            def on_next(x: _T) -> None:
                nonlocal n, s, window_id
                new_window = False
                new_id = 0

                s.on_next(x)
                n += 1
                if n == count:
                    new_window = True
                    n = 0
                    window_id += 1
                    new_id = window_id
                    s.on_completed()
                    s = Subject()
                    observer.on_next(add_ref(s, ref_count_disposable))

                if new_window:
                    create_timer(new_id)

            def on_error(e: Exception) -> None:
                s.on_error(e)
                observer.on_error(e)

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

            group_disposable.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler_))
            return ref_count_disposable
示例#24
0
文件: _delay.py 项目: lizh06/RxPY
    def subscribe(observer: abc.ObserverBase[_T],
                  scheduler_: Optional[abc.SchedulerBase] = None):
        nonlocal duetime

        _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton()

        if isinstance(duetime, datetime):
            duetime_ = _scheduler.to_datetime(duetime) - _scheduler.now
        else:
            duetime_ = _scheduler.to_timedelta(duetime)

        cancelable = SerialDisposable()
        exception: Optional[Exception] = None
        active = [False]
        running = [False]
        queue: List[Timestamp[Notification[_T]]] = []

        def on_next(notification: Timestamp[Notification[_T]]) -> None:
            nonlocal exception
            should_run = False

            with source.lock:
                if isinstance(notification.value, OnError):
                    del queue[:]
                    queue.append(notification)
                    exception = 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:
                    observer.on_error(exception)
                else:
                    mad = MultipleAssignmentDisposable()
                    cancelable.disposable = mad

                    def action(scheduler: abc.SchedulerBase,
                               state: Any = None):
                        if exception:
                            return

                        with source.lock:
                            running[0] = True
                            while True:
                                result = None
                                if 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: typing.RelativeTime = 0
                            if queue:
                                should_continue = True
                                diff = queue[0].timestamp - scheduler.now
                                recurse_duetime = max(DELTA_ZERO, diff)
                            else:
                                active[0] = False

                            ex = exception
                            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)

        subscription = source.pipe(
            ops.materialize(),
            ops.timestamp(),
        ).subscribe(on_next, scheduler=_scheduler)

        return CompositeDisposable(subscription, cancelable)
示例#25
0
 def test_timeout_now(self):
     scheduler = TimeoutScheduler()
     diff = scheduler.now - default_now()
     assert abs(diff) < timedelta(milliseconds=1)
示例#26
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ):
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            timer_d = SerialDisposable()
            next_shift = [timeshift]
            next_span = [timespan]
            total_time = [DELTA_ZERO]
            queue: List[Subject[_T]] = []

            group_disposable = CompositeDisposable(timer_d)
            ref_count_disposable = RefCountDisposable(group_disposable)

            def create_timer():
                m = SingleAssignmentDisposable()
                timer_d.disposable = m
                is_span = False
                is_shift = False

                if next_span[0] == next_shift[0]:
                    is_span = True
                    is_shift = True
                elif next_span[0] < next_shift[0]:
                    is_span = True
                else:
                    is_shift = True

                new_total_time = next_span[0] if is_span else next_shift[0]

                ts = new_total_time - total_time[0]
                total_time[0] = new_total_time
                if is_span:
                    next_span[0] += timeshift

                if is_shift:
                    next_shift[0] += timeshift

                @synchronized(source.lock)
                def action(scheduler: abc.SchedulerBase, state: Any = None):
                    s: Optional[Subject[_T]] = None

                    if is_shift:
                        s = Subject()
                        queue.append(s)
                        observer.on_next(add_ref(s, ref_count_disposable))

                    if is_span:
                        s = queue.pop(0)
                        s.on_completed()

                    create_timer()

                m.disposable = _scheduler.schedule_relative(ts, action)

            queue.append(Subject())
            observer.on_next(add_ref(queue[0], ref_count_disposable))
            create_timer()

            def on_next(x: _T) -> None:
                with source.lock:
                    for s in queue:
                        s.on_next(x)

            @synchronized(source.lock)
            def on_error(e: Exception) -> None:
                for s in queue:
                    s.on_error(e)

                observer.on_error(e)

            @synchronized(source.lock)
            def on_completed() -> None:
                for s in queue:
                    s.on_completed()

                observer.on_completed()

            group_disposable.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler_))
            return ref_count_disposable
示例#27
0
 def run(idx):
     scheduler[idx] = TimeoutScheduler()
     gate[idx].release()