def subscribe(observer, scheduler_=None): _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, state): 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
def subscribe(observer, scheduler=None): scheduler = scheduler or timeout_scheduler 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] = state[0] time[0] = time_mapper(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
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 scheduler_ or timeout_scheduler nonlocal duetime if not isinstance(duetime, datetime): 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
def subscribe(observer, scheduler=None): scheduler = scheduler or current_thread_scheduler 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 = state[0] 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 on_next(notification): 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]: observer.on_error(exception[0]) else: mad = MultipleAssignmentDisposable() cancelable.disposable = mad def action(scheduler, state): if exception[0]: 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 = 0 if 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)
def subscribe(observer, scheduler_: typing.Scheduler = None): nonlocal range_t _scheduler = scheduler or 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
def schedule_periodic( self, period: typing.RelativeTime, action: typing.ScheduledPeriodicAction, state: Optional[typing.TState] = None) -> typing.Disposable: """Schedules a periodic piece of work. Args: period: Period in seconds or timedelta 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). """ disp = MultipleAssignmentDisposable() def invoke_periodic(scheduler: typing.Scheduler, _: typing.TState) -> Optional[Disposable]: nonlocal state if disp.is_disposed: return None if period: disp.disposable = self.schedule_relative( period, invoke_periodic, None) try: new_state = action(state) except Exception: disp.dispose() raise if state is not None: state = new_state return None disp.disposable = self.schedule_relative(period, invoke_periodic, None) return disp
def schedule_periodic(self, period: typing.RelativeTime, action: typing.ScheduledPeriodicAction, state: Optional[typing.TState] = None ) -> typing.Disposable: """Schedules a periodic piece of work. Args: period: Period in seconds or timedelta 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). """ disp = MultipleAssignmentDisposable() def invoke_periodic(scheduler: typing.Scheduler, _: typing.TState) -> Optional[Disposable]: if disp.is_disposed: return None if period: disp.disposable = scheduler.schedule_relative(period, invoke_periodic, None) nonlocal state try: new_state = action(state) except Exception: disp.dispose() raise if state is not None: state = new_state return None disp.disposable = self.schedule_relative(period, invoke_periodic, None) return disp
def subscribe(observer, scheduler=None): scheduler = scheduler or TimeoutScheduler.singleton() mad = MultipleAssignmentDisposable() state = initial_state has_result = False result = None first = True time = None def action(scheduler, _): 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: mad.disposable = scheduler.schedule_relative(time, action) else: observer.on_completed() mad.disposable = scheduler.schedule_relative(0, action) return mad