def test_currentthread_schedule(self):
        scheduler = CurrentThreadScheduler()
        ran = False

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

        scheduler.schedule(action)
        assert ran is True
    def test_currentthread_schedule_error(self):
        scheduler = CurrentThreadScheduler()

        class MyException(Exception):
            pass

        def action(scheduler, state=None):
            raise MyException()

        with pytest.raises(MyException):
            scheduler.schedule(action)
    def test_currentthread_schedule_block(self):
        scheduler = CurrentThreadScheduler()
        ran = False

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

        t = scheduler.now
        scheduler.schedule_relative(0.2, action)
        t = scheduler.now - t
        assert ran is True
        assert t >= timedelta(seconds=0.2)
    def test_currentthread_schedule_nested(self):
        scheduler = CurrentThreadScheduler()
        ran = False

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

            return scheduler.schedule(inner_action)

        scheduler.schedule(action)

        assert ran is True
        def outer(scheduler, state=None):
            def action1(scheduler, state=None):
                tests.append(1)

                def action2(scheduler, state=None):
                    tests.append(2)

                CurrentThreadScheduler().schedule(action2)

            CurrentThreadScheduler().schedule(action1)

            def action3(scheduler, state=None):
                tests.append(3)

            CurrentThreadScheduler().schedule(action3)
Exemple #6
0
 def test_currentthread_now_units(self):
     scheduler = CurrentThreadScheduler()
     diff = scheduler.now
     sleep(1.1)
     diff = scheduler.now - diff
     assert timedelta(milliseconds=1000) < diff < timedelta(
         milliseconds=1300)
Exemple #7
0
    def subscribe(
            observer: typing.Observer,
            scheduler_: Optional[typing.Scheduler] = None
    ) -> typing.Disposable:
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )
        iterator = iter(iterable)
        disposed = False

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

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

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

        disp = Disposable(dispose)
        return CompositeDisposable(_scheduler.schedule(action), disp)
Exemple #8
0
    def subscribe(observer, scheduler=None):

        scheduler = scheduler or CurrentThreadScheduler.singleton()

        subscription = SerialDisposable()
        cancelable = SerialDisposable()

        def action(scheduler, state=None):
            try:
                source = next(sources_)
            except StopIteration:
                observer.on_completed()
                return

            # Allow source to be a factory method taking an error
            source = source(state) if callable(source) else source
            current = rx.from_future(source) if is_future(source) else source

            d = SingleAssignmentDisposable()
            subscription.disposable = d

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

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

        cancelable.disposable = scheduler.schedule(action)
        return CompositeDisposable(subscription, cancelable)
Exemple #9
0
    def subscribe(observer, scheduler=None):
        scheduler = scheduler or CurrentThreadScheduler.singleton()
        first = True
        state = initial_state
        mad = MultipleAssignmentDisposable()

        def action(scheduler, state1=None):
            nonlocal first
            nonlocal state

            has_result = False
            result = None

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

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

            except Exception as exception:  # pylint: disable=broad-except
                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
Exemple #10
0
    def test_currentthread_singleton(self):
        scheduler = [CurrentThreadScheduler(), CurrentThreadScheduler()]
        assert scheduler[0] is scheduler[1]

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

        def run(idx):
            scheduler[idx] = CurrentThreadScheduler()
            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 not scheduler[1]
Exemple #11
0
    def on_subscribe(observer, scheduler):
        nonlocal sink_observer
        nonlocal sink_scheduler
        sink_observer = observer
        sink_scheduler = scheduler or CurrentThreadScheduler()

        def dispose():
            nonlocal sink_observer
            sink_observer = None

        return dispose
    def test_currentthread_ensuretrampoline_nested(self):
        scheduler = CurrentThreadScheduler()
        ran1, ran2 = False, False

        def outer_action(scheduler, state):
            def inner_action1(scheduler, state):
                nonlocal ran1
                ran1 = True

            scheduler.schedule(inner_action1)

            def inner_action2(scheduler, state):
                nonlocal ran2
                ran2 = True

            return scheduler.schedule(inner_action2)

        scheduler.ensure_trampoline(outer_action)
        assert ran1 is True
        assert ran2 is True
    def test_currentthread_ensuretrampoline_and_cancel(self):
        scheduler = CurrentThreadScheduler()
        ran1, ran2 = False, False

        def outer_action(scheduler, state):
            def inner_action1(scheduler, state):
                nonlocal ran1
                ran1 = True

                def inner_action2(scheduler, state):
                    nonlocal ran2
                    ran2 = True

                d = scheduler.schedule(inner_action2)
                d.dispose()

            return scheduler.schedule(inner_action1)

        scheduler.ensure_trampoline(outer_action)
        assert ran1 is True
        assert ran2 is False
    def subscribe(
            observer: typing.Observer,
            scheduler_: Optional[typing.Scheduler] = None
    ) -> typing.Disposable:
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )

        def action(scheduler: typing.Scheduler, state: Any = None):
            observer.on_next(value)
            observer.on_completed()

        return _scheduler.schedule(action)
    def test_currentthread_extend(self):
        class MyScheduler(CurrentThreadScheduler):
            pass

        scheduler = [
            MyScheduler(),
            MyScheduler.singleton(),
            MyScheduler.singleton(),
            CurrentThreadScheduler.singleton(),
        ]
        assert scheduler[0] is not scheduler[1]
        assert scheduler[1] is scheduler[2]
        assert scheduler[1] is not scheduler[3]
    def test_currentthread_schedule_nested_order(self):
        scheduler = CurrentThreadScheduler()
        tests = []

        def outer(scheduler, state=None):
            def action1(scheduler, state=None):
                tests.append(1)

                def action2(scheduler, state=None):
                    tests.append(2)

                CurrentThreadScheduler().schedule(action2)

            CurrentThreadScheduler().schedule(action1)

            def action3(scheduler, state=None):
                tests.append(3)

            CurrentThreadScheduler().schedule(action3)

        scheduler.ensure_trampoline(outer)

        assert tests == [1, 2, 3]
    def subscribe(observer: typing.Observer,
                  scheduler_: typing.Scheduler = None):
        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )

        def action(_: Scheduler, __: Any = None):
            nonlocal observer

            try:
                observer.on_next(supplier())
                observer.on_completed()
            except Exception as e:  # pylint: disable=broad-except
                observer.on_error(e)

        return _scheduler.schedule(action)
Exemple #18
0
    def subscribe(observer, scheduler_: typing.Scheduler = None):
        nonlocal range_t

        _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton(
        )
        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
        def subscribe(observer, scheduler):
            scheduler = scheduler or CurrentThreadScheduler.singleton()

            def action(scheduler, state):
                self.task()

            def dispose() -> None:
                import traceback

                traceback.print_stack()
                print("--------> dispose called <----------------")
                # nonlocal disposed
                # disposed = True

            # scheduler.schedule(action)
            return CompositeDisposable(scheduler.schedule(action),
                                       Disposable(dispose))
Exemple #20
0
    def test_route_error(self):
        actual_sequence = []

        def on_chain_item(i):
            nonlocal actual_sequence
            actual_sequence.append(i)

        sink, route_error = make_error_router()

        origin = rx.from_([rx.just(1), rx.throw(-1)]).pipe(
            route_error(error_map=lambda e: e.args[0] * 100), )

        result = rx.merge(origin, sink)
        disposable = result.subscribe(on_chain_item,
                                      scheduler=CurrentThreadScheduler())
        disposable.dispose()

        expected_sequence = [1, -100]
        self.assertEqual(actual_sequence, expected_sequence)
    def subscribe(observer: ObserverType,
                  scheduler: Optional[SchedulerType] = None) -> DisposableType:
        # _scheduler = scheduler or scheduler_ or CurrentThreadScheduler.singleton()
        scheduler = scheduler or CurrentThreadScheduler.singleton()
        # iterator = iter(iterable)
        disposed = False

        def action(_: SchedulerType, __: Any = None) -> None:
            nonlocal disposed

            print("logoutTask/subscribe", threading.currentThread())
            print("a")
            observer.on_next("Started")
            print("b")
            observer.on_next("Started 2")
            print("c")
            print("calling on_next")
            time.sleep(0.2)
            if disposed:
                pass

            print("d")
            observer.on_next("Logging out...")
            time.sleep(1)
            print("e")
            observer.on_next("Almost done")
            time.sleep(1)

            # raise Exception("Gnit happened")

            observer.on_completed()

        def dispose() -> None:
            import traceback

            traceback.print_stack()
            print("--------> dispose called <----------------")
            nonlocal disposed
            disposed = True

        disp = Disposable(dispose)
        return CompositeDisposable(scheduler.schedule(action), disp)
    def __init__(self,
                 buffer_size: int = None,
                 window: typing.RelativeTime = None,
                 scheduler: Optional[typing.Scheduler] = None
                 ) -> None:
        """Initializes a new instance of the ReplaySubject class with
        the specified buffer size, window and scheduler.

        Args:
            buffer_size: [Optional] Maximum element count of the replay
                buffer.
            window [Optional]: Maximum time length of the replay buffer.
            scheduler: [Optional] Scheduler the observers are invoked on.
        """

        super().__init__()
        self.buffer_size = sys.maxsize if buffer_size is None else buffer_size
        self.scheduler = scheduler or CurrentThreadScheduler.singleton()
        self.window = timedelta.max if window is None else self.scheduler.to_timedelta(window)
        self.queue: List[QueueItem] = []
Exemple #23
0
    def subscribe(observer, scheduler_=None):
        _scheduler = scheduler_ or CurrentThreadScheduler.singleton()

        subscription = SerialDisposable()
        cancelable = SerialDisposable()
        last_exception = None
        is_disposed = False

        def action(action1, state=None):
            def on_error(exn):
                nonlocal last_exception
                last_exception = exn
                cancelable.disposable = _scheduler.schedule(action)

            if is_disposed:
                return

            try:
                current = next(sources_)
            except StopIteration:
                if last_exception:
                    observer.on_error(last_exception)
                else:
                    observer.on_completed()
            except Exception as ex:  # pylint: disable=broad-except
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe_(observer.on_next, on_error,
                                                  observer.on_completed,
                                                  scheduler_)

        cancelable.disposable = _scheduler.schedule(action)

        def dispose():
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(subscription, cancelable,
                                   Disposable(dispose))
Exemple #24
0
    def on_subscribe(observer, scheduler_):
        disposed = False
        _scheduler = scheduler_ or CurrentThreadScheduler.singleton()

        def _action(_, __):
            nonlocal disposed

            def read_data(f):
                nonlocal disposed

                if size is None:
                    data = f.read(size)
                    observer.on_next(data)
                else:
                    data = f.read(size)
                    while not disposed and len(data) > 0:
                        observer.on_next(data)
                        data = f.read(size)

            try:
                if type(file) is str:
                    with open(file, mode, encoding=encoding) as f:
                        read_data(f)
                else:
                    read_data(file)

                observer.on_completed()

            except Exception as e:
                observer.on_error(e)

        def _dispose():
            nonlocal disposed
            disposed = True

        disp = Disposable(_dispose)
        return CompositeDisposable(_scheduler.schedule(_action), disp)
 def run(idx):
     scheduler[idx] = CurrentThreadScheduler.singleton()
     gate[idx].release()
Exemple #26
0
    def subscribe_(
            self,
            on_next: Optional[typing.OnNext] = None,
            on_error: Optional[typing.OnError] = None,
            on_completed: Optional[typing.OnCompleted] = None,
            scheduler: Optional[typing.Scheduler] = None) -> typing.Disposable:
        """Subscribe callbacks to the observable sequence.

        Examples:
            >>> source.subscribe_(on_next)
            >>> source.subscribe_(on_next, on_error)
            >>> source.subscribe_(on_next, on_error, on_completed)

        Args:
            on_next: [Optional] Action to invoke for each element in the
                observable sequence.
            on_error: [Optional] Action to invoke upon exceptional termination
                of the observable sequence.
            on_completed: [Optional] Action to invoke upon graceful termination
                of the observable sequence.
            scheduler: [Optional] The scheduler to use for this subscription.

        Returns:
            Disposable object representing an observer's subscription to
            the observable sequence.
        """

        auto_detach_observer = AutoDetachObserver(on_next, on_error,
                                                  on_completed)

        def fix_subscriber(subscriber):
            """Fixes subscriber to make sure it returns a Disposable instead
            of None or a dispose function"""
            if not hasattr(subscriber, 'dispose'):
                subscriber = Disposable(subscriber)

            return subscriber

        def set_disposable(_: abc.Scheduler = None, __: Any = None):
            try:
                subscriber = self._subscribe_core(auto_detach_observer,
                                                  scheduler)
            except Exception as ex:  # By design. pylint: disable=W0703
                if not auto_detach_observer.fail(ex):
                    raise
            else:
                auto_detach_observer.subscription = fix_subscriber(subscriber)

        # Subscribe needs to set up the trampoline before for subscribing.
        # Actually, the first call to Subscribe creates the trampoline so
        # that it may assign its disposable before any observer executes
        # OnNext over the CurrentThreadScheduler. This enables single-
        # threaded cancellation
        # https://social.msdn.microsoft.com/Forums/en-US/eb82f593-9684-4e27-
        # 97b9-8b8886da5c33/whats-the-rationale-behind-how-currentthreadsche
        # dulerschedulerequired-behaves?forum=rx
        current_thread_scheduler = CurrentThreadScheduler.singleton()
        if current_thread_scheduler.schedule_required():
            current_thread_scheduler.schedule(set_disposable)
        else:
            set_disposable()

        # Hide the identity of the auto detach observer
        return Disposable(auto_detach_observer.dispose)
 def test_currentthread_now(self):
     scheduler = CurrentThreadScheduler()
     diff = scheduler.now - default_now()
     assert abs(diff) < timedelta(milliseconds=1)