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)
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
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)
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_singleton(self): scheduler = [ CurrentThreadScheduler(), CurrentThreadScheduler.singleton(), CurrentThreadScheduler.singleton() ] assert scheduler[0] is not scheduler[1] assert scheduler[1] is scheduler[2] gate = [threading.Semaphore(0), threading.Semaphore(0)] scheduler = [None, None] def run(idx): scheduler[idx] = CurrentThreadScheduler.singleton() 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]
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)
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))
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] = []
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))
def test_currentthread_singleton_schedule_nested_order(self): scheduler = CurrentThreadScheduler.singleton() tests = [] def outer(scheduler, state=None): def action1(scheduler, state=None): tests.append(1) def action2(scheduler, state=None): tests.append(2) scheduler.schedule(action2) scheduler.schedule(action1) def action3(scheduler, state=None): tests.append(3) scheduler.schedule(action3) scheduler.ensure_trampoline(outer) assert tests == [1, 3, 2]
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()
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)