def subscribe(observer, scheduler_=None): _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 = [0] def on_next(x): emit = False now = _scheduler.now with source.lock: if not last_on_next[0] or now - last_on_next[0] >= duration: last_on_next[0] = now emit = True if emit: observer.on_next(x) return source.subscribe_(on_next, observer.on_error, observer.on_completed, scheduler=_scheduler)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() n = [0] s = [None] timer_d = SerialDisposable() window_id = [0] group_disposable = CompositeDisposable(timer_d) ref_count_disposable = RefCountDisposable(group_disposable) def create_timer(_id): m = SingleAssignmentDisposable() timer_d.disposable = m def action(scheduler, state): if _id != window_id[0]: return n[0] = 0 window_id[0] += 1 new_id = window_id[0] s[0].on_completed() s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) create_timer(new_id) m.disposable = _scheduler.schedule_relative(timespan, action) s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) create_timer(0) def on_next(x): new_window = False new_id = 0 s[0].on_next(x) n[0] += 1 if n[0] == count: new_window = True n[0] = 0 window_id[0] += 1 new_id = window_id[0] s[0].on_completed() s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) if new_window: create_timer(new_id) def on_error(e): s[0].on_error(e) observer.on_error(e) def on_completed(): s[0].on_completed() observer.on_completed() group_disposable.add(source.subscribe_(on_next, on_error, on_completed, scheduler_)) return ref_count_disposable
def subscribe(observer, scheduler_=None): nonlocal duration _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) duration = _scheduler.to_timedelta(duration) q = [] def on_next(x): now = _scheduler.now q.append({"interval": now, "value": x}) while q and now - q[0]["interval"] >= duration: q.pop(0) def on_completed(): now = _scheduler.now while q: _next = q.pop(0) if now - _next["interval"] <= duration: observer.on_next(_next["value"]) observer.on_completed() return source.subscribe_(on_next, observer.on_error, on_completed, scheduler_)
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 scheduler_ or TimeoutScheduler.singleton() def action(scheduler, state): observer.on_next(0) observer.on_completed() return _scheduler.schedule_absolute(duetime, action)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) def action(count): observer.on_next(count) return count + 1 return _scheduler.schedule_periodic(period, action, state=0)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) def action(scheduler, state): observer.on_completed() disp = _scheduler.schedule_relative(duration, action) return CompositeDisposable( disp, source.subscribe(observer, scheduler=scheduler_))
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]
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() d = _scheduler.to_seconds(duetime) def action(scheduler, state): observer.on_next(0) observer.on_completed() if d <= 0.0: return _scheduler.schedule(action) return _scheduler.schedule_relative(d, action)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) if isinstance(duetime, datetime): scheduler_method = _scheduler.schedule_absolute else: scheduler_method = _scheduler.schedule_relative switched = [False] _id = [0] original = SingleAssignmentDisposable() subscription = SerialDisposable() timer = SerialDisposable() subscription.disposable = original def create_timer(): my_id = _id[0] def action(scheduler, state=None): switched[0] = (_id[0] == my_id) timer_wins = switched[0] if timer_wins: subscription.disposable = obs.subscribe( observer, scheduler=scheduler) timer.disposable = scheduler_method(duetime, action) create_timer() def on_next(value): send_wins = not switched[0] if send_wins: _id[0] += 1 observer.on_next(value) create_timer() def on_error(error): on_error_wins = not switched[0] if on_error_wins: _id[0] += 1 observer.on_error(error) def on_completed(): 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_) return CompositeDisposable(subscription, timer)
def do_retry(source, tries, exception): if tries <= retries: logging.warning( 'retry_with_backoff(tries={}, retries={}, exception={}, description={})'.format( tries, retries, exception, description )) return of(None).pipe( delay(backoff(tries), TimeoutScheduler.singleton()), flat_map(source), catch(handler=lambda e, src: do_retry(src, tries + 1, e)) ) else: return throw(exception)
def subscribe(observer, scheduler_): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) last = _scheduler.now def mapper(value): 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_)
def subscribe(observer, scheduler_=None) -> Disposable: _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) cancelable = SerialDisposable() button_state = [None] press_time: List[float] = [0.] def set_state(state): button_state[0] = state observer.on_next(button_state[0]) set_state(ROOM['notPressed']) def on_next(x: Any) -> None: now = time.time() if button_state[0] == ROOM['notPressed']: set_state(ROOM['pressed']) press_time[0] = now elif button_state[0] == ROOM['pressed']: if now > press_time[0] + min_hold_sec: set_state(ROOM['held']) # should be pressed AND held elif button_state[0] == ROOM['held']: pass else: raise NotImplementedError(f'button_state={button_state}') d = SingleAssignmentDisposable() cancelable.disposable = d def action(scheduler, state=None) -> None: if button_state[0] != ROOM['notPressed']: set_state(ROOM['notPressed']) d.disposable = _scheduler.schedule_relative( release_after_sec, action) def on_error(exception: Exception) -> None: cancelable.dispose() observer.on_error(exception) def on_completed() -> None: raise NotImplementedError subscription = source.subscribe_(on_next, on_error, on_completed, scheduler=scheduler_) return CompositeDisposable(subscription, cancelable)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) if isinstance(end_time, datetime): scheduler_method = _scheduler.schedule_absolute else: scheduler_method = _scheduler.schedule_relative def action(scheduler, state): observer.on_completed() task = scheduler_method(end_time, action) return CompositeDisposable( task, source.subscribe(observer, scheduler=scheduler_))
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) open = [False] def action(scheduler, state): open[0] = True t = _scheduler.schedule_relative(duration, action) def on_next(x): if open[0]: observer.on_next(x) d = source.subscribe_(on_next, observer.on_error, observer.on_completed, scheduler_) return CompositeDisposable(t, d)
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]
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) open = [False] def on_next(x): if open[0]: observer.on_next(x) subscription = source.subscribe_(on_next, observer.on_error, observer.on_completed, scheduler_) def action(scheduler, state): open[0] = True disp = getattr(_scheduler, scheduler_method)(start_time, action) return CompositeDisposable(disp, subscription)
def subscribe(observer, scheduler_=None) -> Disposable: _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) cancelable = SerialDisposable() has_value = [False] value = [None] _id = [0] def on_next(x: Any) -> None: has_value[0] = True value[0] = x _id[0] += 1 current_id = _id[0] d = SingleAssignmentDisposable() cancelable.disposable = d def action(scheduler, state=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)
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
def _to_async(func: Callable, scheduler: Optional[Scheduler] = None) -> Callable: """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 = rx.to_async(lambda x, y: x + y)(4, 3) res = rx.to_async(lambda x, y: x + y, Scheduler.timeout)(4, 3) res = rx.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) -> Observable: subject = AsyncSubject() def action(scheduler, state): 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
def schedule(): return rx.interval(period, TimeoutScheduler.singleton()).pipe( do_action(lambda _: ee.InitializeThread(credentials)), )
def factory(scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() mapper = operators.map(lambda value: Timestamp(value=value, timestamp=_scheduler.now)) return source.pipe(mapper)
def subscribe(observer, scheduler_=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 = [None] active = [False] running = [False] queue = [] 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 = DELTA_ZERO 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) subscription = source.pipe(ops.materialize(), ops.timestamp()).subscribe_( on_next, scheduler=scheduler_) return CompositeDisposable(subscription, cancelable)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton( ) timer_d = SerialDisposable() next_shift = [timeshift] next_span = [timespan] total_time = [DELTA_ZERO] q = [] 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 def action(scheduler, state=None): s = None if is_shift: s = Subject() q.append(s) observer.on_next(add_ref(s, ref_count_disposable)) if is_span: s = q.pop(0) s.on_completed() create_timer() m.disposable = _scheduler.schedule_relative(ts, action) q.append(Subject()) observer.on_next(add_ref(q[0], ref_count_disposable)) create_timer() def on_next(x): for s in q: s.on_next(x) def on_error(e): for s in q: s.on_error(e) observer.on_error(e) def on_completed(): for s in q: s.on_completed() observer.on_completed() group_disposable.add( source.subscribe_(on_next, on_error, on_completed, scheduler_)) return ref_count_disposable