def send_right(value: _TRight) -> None: with left.lock: _id = right_id[0] right_id[0] += 1 right_map[_id] = value md = SingleAssignmentDisposable() group.add(md) def expire(): del right_map[_id] group.remove(md) try: duration = right_duration_mapper(value) except Exception as e: for left_value in left_map.values(): left_value.on_error(e) observer.on_error(e) return def on_error(error: Exception): with left.lock: for left_value in left_map.values(): left_value.on_error(error) observer.on_error(error) md.disposable = duration.pipe(ops.take(1)).subscribe( nothing, on_error, expire, scheduler=scheduler) with left.lock: for left_value in left_map.values(): left_value.on_next(value)
def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None: nonlocal source d = SingleAssignmentDisposable() with source.lock: latest[0] += 1 _id = latest[0] has_latest[0] = True inner_subscription.disposable = d # Check if Future or Observable if isinstance(inner_source, Future): obs = from_future(inner_source) else: obs = inner_source def on_next(x: Any) -> None: if latest[0] == _id: observer.on_next(x) def on_error(e: Exception) -> None: if latest[0] == _id: observer.on_error(e) def on_completed() -> None: if latest[0] == _id: has_latest[0] = False if is_stopped[0]: observer.on_completed() d.disposable = obs.subscribe( on_next, on_error, on_completed, scheduler=scheduler )
def subscribe( observer: abc.ObserverBase[_T], scheduler: Optional[abc.SchedulerBase] = None, ): is_open = [False] def on_next(left: _T) -> None: if is_open[0]: observer.on_next(left) def on_completed() -> None: if is_open[0]: observer.on_completed() subs = source.subscribe( on_next, observer.on_error, on_completed, scheduler=scheduler ) subscriptions = CompositeDisposable(subs) right_subscription = SingleAssignmentDisposable() subscriptions.add(right_subscription) def on_next2(x: Any) -> None: is_open[0] = True right_subscription.dispose() def on_completed2(): right_subscription.dispose() right_subscription.disposable = obs.subscribe( on_next2, observer.on_error, on_completed2, scheduler=scheduler ) return subscriptions
def action(scheduler: abc.SchedulerBase, state: Any = None) -> None: def on_error(exn: Exception) -> None: 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=scheduler_, )
def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None: if not has_current[0]: has_current[0] = True inner_source = ( reactivex.from_future(inner_source) if isinstance(inner_source, Future) else inner_source ) inner_subscription = SingleAssignmentDisposable() g.add(inner_subscription) def on_completed_inner(): g.remove(inner_subscription) has_current[0] = False if is_stopped[0] and len(g) == 1: observer.on_completed() inner_subscription.disposable = inner_source.subscribe( observer.on_next, observer.on_error, on_completed_inner, scheduler=scheduler, )
def on_next(x: _T) -> None: try: assert mapper delay = mapper(x) except Exception as error: # pylint: disable=broad-except observer.on_error(error) return d = SingleAssignmentDisposable() delays.add(d) def on_next(_: Any) -> None: observer.on_next(x) delays.remove(d) done() def on_completed() -> None: observer.on_next(x) delays.remove(d) done() d.disposable = delay.subscribe(on_next, observer.on_error, on_completed, scheduler=scheduler)
def subscribe( observer: abc.ObserverBase[_T], scheduler: Optional[abc.SchedulerBase] = None ) -> abc.DisposableBase: d1 = SingleAssignmentDisposable() subscription = SerialDisposable() subscription.disposable = d1 def on_error(exception: Exception) -> None: try: result = handler(exception, source) except Exception as ex: # By design. pylint: disable=W0703 observer.on_error(ex) return result = (reactivex.from_future(result) if isinstance( result, Future) else result) d = SingleAssignmentDisposable() subscription.disposable = d d.disposable = result.subscribe(observer, scheduler=scheduler) d1.disposable = source.subscribe(observer.on_next, on_error, observer.on_completed, scheduler=scheduler) return subscription
def set_timer(timeout: Observable[Any]) -> None: my_id = _id[0] def timer_wins(): return _id[0] == my_id d = SingleAssignmentDisposable() timer.disposable = d def on_next(x: Any) -> None: if timer_wins(): subscription.disposable = other_.subscribe( observer, scheduler=scheduler) d.dispose() def on_error(e: Exception) -> None: if timer_wins(): observer.on_error(e) def on_completed() -> None: if timer_wins(): subscription.disposable = other_.subscribe(observer) d.disposable = timeout.subscribe(on_next, on_error, on_completed, scheduler=scheduler)
def on_next_right(value: _T2): nonlocal right_id duration = None current_id = right_id right_id += 1 md = SingleAssignmentDisposable() right_map[current_id] = value group.add(md) def expire(): if current_id in right_map: del right_map[current_id] if not len(right_map) and right_done: observer.on_completed() group.remove(md) try: duration = right_duration_mapper(value) except Exception as exception: observer.on_error(exception) return md.disposable = duration.pipe(take(1)).subscribe( noop, observer.on_error, lambda: expire(), scheduler=scheduler) for val in left_map.values(): result = (val, value) observer.on_next(result)
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)
class AutoDetachObserver(abc.ObserverBase[_T_in]): def __init__( self, on_next: Optional[typing.OnNext[_T_in]] = None, on_error: Optional[typing.OnError] = None, on_completed: Optional[typing.OnCompleted] = None, ) -> None: self._on_next = on_next or noop self._on_error = on_error or default_error self._on_completed = on_completed or noop self._subscription = SingleAssignmentDisposable() self.is_stopped = False def on_next(self, value: _T_in) -> None: if self.is_stopped: return self._on_next(value) def on_error(self, error: Exception) -> None: if self.is_stopped: return self.is_stopped = True try: self._on_error(error) finally: self.dispose() def on_completed(self) -> None: if self.is_stopped: return self.is_stopped = True try: self._on_completed() finally: self.dispose() def set_disposable(self, value: abc.DisposableBase) -> None: self._subscription.disposable = value subscription = property(fset=set_disposable) def dispose(self) -> None: self.is_stopped = True self._subscription.dispose() def fail(self, exn: Exception) -> bool: if self.is_stopped: return False self.is_stopped = True self._on_error(exn) return True
def on_error(exception: Exception) -> None: try: result = handler(exception, source) except Exception as ex: # By design. pylint: disable=W0703 observer.on_error(ex) return result = (reactivex.from_future(result) if isinstance( result, Future) else result) d = SingleAssignmentDisposable() subscription.disposable = d d.disposable = result.subscribe(observer, scheduler=scheduler)
def __init__( self, on_next: Optional[typing.OnNext[_T_in]] = None, on_error: Optional[typing.OnError] = None, on_completed: Optional[typing.OnCompleted] = None, ) -> None: self._on_next = on_next or noop self._on_error = on_error or default_error self._on_completed = on_completed or noop self._subscription = SingleAssignmentDisposable() self.is_stopped = False
def subscribechild( i: int, child: Observable[Any] ) -> SingleAssignmentDisposable: subscription = SingleAssignmentDisposable() def on_next(value: Any) -> None: with parent.lock: values[i] = value subscription.disposable = child.subscribe( on_next, observer.on_error, scheduler=scheduler ) return subscription
def on_next_left(value: _TLeft) -> None: subject: Subject[_TRight] = Subject() with left.lock: _id = left_id[0] left_id[0] += 1 left_map[_id] = subject try: result = (value, add_ref(subject, rcd)) except Exception as e: log.error("*** Exception: %s" % e) for left_value in left_map.values(): left_value.on_error(e) observer.on_error(e) return observer.on_next(result) for right_value in right_map.values(): subject.on_next(right_value) md = SingleAssignmentDisposable() group.add(md) def expire(): if _id in left_map: del left_map[_id] subject.on_completed() group.remove(md) try: duration = left_duration_mapper(value) except Exception as e: for left_value in left_map.values(): left_value.on_error(e) observer.on_error(e) return def on_error(error: Exception) -> Any: for left_value in left_map.values(): left_value.on_error(error) observer.on_error(error) md.disposable = duration.pipe(ops.take(1)).subscribe( nothing, on_error, expire, scheduler=scheduler)
def subscribe( observer: abc.ObserverBase[_T], _: Optional[abc.SchedulerBase] = None ): m = SingleAssignmentDisposable() d = SerialDisposable() d.disposable = m def action(scheduler: abc.SchedulerBase, state: Optional[Any] = None): d.disposable = ScheduledDisposable( scheduler, source.subscribe(observer) ) m.disposable = scheduler.schedule(action) return d
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 _subscribe(i: int) -> None: subscriptions[i] = SingleAssignmentDisposable() def on_next(value: Any) -> None: with parent.lock: values[i] = value has_value[i] = True def on_completed() -> None: with parent.lock: done(i) subscriptions[i].disposable = sources[i].subscribe( on_next, observer.on_error, on_completed, scheduler=scheduler )
def schedule_relative( self, duetime: typing.RelativeTime, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None, ) -> abc.DisposableBase: """Schedules an action to be executed after duetime. Args: duetime: Relative time after which to execute the action. action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ msecs = max(0, int(self.to_seconds(duetime) * 1000.0)) sad = SingleAssignmentDisposable() is_disposed = False def invoke_action() -> None: if not is_disposed: sad.disposable = action(self, state) log.debug("relative timeout: %sms", msecs) # Use static method, let Qt C++ handle QTimer lifetime self._qtcore.QTimer.singleShot(msecs, invoke_action) def dispose() -> None: nonlocal is_disposed is_disposed = True return CompositeDisposable(sad, Disposable(dispose))
def schedule_relative( self, duetime: typing.RelativeTime, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None, ) -> abc.DisposableBase: """Schedules an action to be executed after duetime. Args: duetime: Relative time after which to execute the action. action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ seconds = max(0.0, self.to_seconds(duetime)) sad = SingleAssignmentDisposable() def interval() -> None: sad.disposable = action(self, state) log.debug("timeout: %s", seconds) timer = self._reactor.callLater(seconds, interval) def dispose() -> None: if not timer.called: timer.cancel() return CompositeDisposable(sad, Disposable(dispose))
def func(i: int) -> None: source: Observable[Any] = sources[i] if isinstance(source, Future): source = from_future(source) sad = SingleAssignmentDisposable() def on_next(x: Any) -> None: queues[i].append(x) next_(i) sad.disposable = source.subscribe(on_next, observer.on_error, lambda: completed(i), scheduler=scheduler) subscriptions[i] = sad
def schedule_relative( self, duetime: typing.RelativeTime, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None, ) -> abc.DisposableBase: """Schedules an action to be executed after duetime. Args: duetime: Relative time after which to execute the action. action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ seconds = self.to_seconds(duetime) if seconds <= 0.0: return self.schedule(action, state=state) sad = SingleAssignmentDisposable() def interval() -> None: sad.disposable = self.invoke_action(action, state=state) log.debug("timeout: %s", seconds) timer = self._loop.call_later(seconds, interval) def dispose() -> None: self._loop.remove_timeout(timer) self._loop.remove_timeout(timer) return CompositeDisposable(sad, Disposable(dispose))
def schedule(self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None) -> abc.DisposableBase: """Schedules an action to be executed. Args: action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ sad = SingleAssignmentDisposable() def interval() -> None: sad.disposable = self.invoke_action(action, state=state) timer = self._eventlet.spawn(interval) def dispose() -> None: timer.kill() return CompositeDisposable(sad, Disposable(dispose))
def schedule(self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None) -> abc.DisposableBase: """Schedules an action to be executed. Args: action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ sad = SingleAssignmentDisposable() is_disposed = False def invoke_action() -> None: if not is_disposed: sad.disposable = action(self, state) self._wx.CallAfter(invoke_action) def dispose() -> None: nonlocal is_disposed is_disposed = True return CompositeDisposable(sad, Disposable(dispose))
def schedule_relative( self, duetime: typing.RelativeTime, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None, ) -> abc.DisposableBase: """Schedules an action to be executed after duetime. Args: duetime: Relative time after which to execute the action. action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ sad = SingleAssignmentDisposable() def invoke_action() -> None: sad.disposable = self.invoke_action(action, state=state) msecs = max(0, int(self.to_seconds(duetime) * 1000.0)) timer = self._root.after(msecs, invoke_action) def dispose() -> None: self._root.after_cancel(timer) return CompositeDisposable(sad, Disposable(dispose))
def schedule(self, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None) -> abc.DisposableBase: """Schedules an action to be executed. Args: action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ sad = SingleAssignmentDisposable() def interval() -> None: sad.disposable = self.invoke_action(action, state=state) handle = self._loop.call_soon_threadsafe(interval) def dispose() -> None: if self._on_self_loop_or_not_running(): handle.cancel() return future: "Future[int]" = Future() def cancel_handle() -> None: handle.cancel() future.set_result(0) self._loop.call_soon_threadsafe(cancel_handle) future.result() return CompositeDisposable(sad, Disposable(dispose))
def subscribe( observer: abc.ObserverBase[_T], scheduler: Optional[abc.SchedulerBase] = None, ) -> abc.DisposableBase: has_current = [False] is_stopped = [False] m = SingleAssignmentDisposable() g = CompositeDisposable() g.add(m) def on_next(inner_source: Union[Observable[_T], "Future[_T]"]) -> None: if not has_current[0]: has_current[0] = True inner_source = ( reactivex.from_future(inner_source) if isinstance(inner_source, Future) else inner_source ) inner_subscription = SingleAssignmentDisposable() g.add(inner_subscription) def on_completed_inner(): g.remove(inner_subscription) has_current[0] = False if is_stopped[0] and len(g) == 1: observer.on_completed() inner_subscription.disposable = inner_source.subscribe( observer.on_next, observer.on_error, on_completed_inner, scheduler=scheduler, ) def on_completed() -> None: is_stopped[0] = True if not has_current[0] and len(g) == 1: observer.on_completed() m.disposable = source.subscribe( on_next, observer.on_error, on_completed, scheduler=scheduler ) return g
def create_window_on_completed(): try: window_close = closing_mapper() except Exception as exception: observer.on_error(exception) return def on_completed(): nonlocal window window.on_completed() window = Subject() observer.on_next(add_ref(window, r)) create_window_on_completed() m1 = SingleAssignmentDisposable() m.disposable = m1 m1.disposable = window_close.pipe(ops.take(1)).subscribe( noop, on_error, on_completed, scheduler=scheduler)
def schedule_relative( self, duetime: typing.RelativeTime, action: typing.ScheduledAction[_TState], state: Optional[_TState] = None, ) -> abc.DisposableBase: """Schedules an action to be executed after duetime. Args: duetime: Relative time after which to execute the action. action: Action to be executed. state: [Optional] state to be given to the action function. Returns: The disposable object used to cancel the scheduled action (best effort). """ seconds = self.to_seconds(duetime) if seconds <= 0: return self.schedule(action, state=state) sad = SingleAssignmentDisposable() def interval() -> None: sad.disposable = self.invoke_action(action, state=state) # the operations on the list used here are atomic, so there is no # need to protect its access with a lock handle: List[asyncio.Handle] = [] def stage2() -> None: handle.append(self._loop.call_later(seconds, interval)) handle.append(self._loop.call_soon_threadsafe(stage2)) def dispose() -> None: def do_cancel_handles() -> None: try: handle.pop().cancel() handle.pop().cancel() except Exception: pass if self._on_self_loop_or_not_running(): do_cancel_handles() return future: "Future[int]" = Future() def cancel_handle() -> None: do_cancel_handles() future.set_result(0) self._loop.call_soon_threadsafe(cancel_handle) future.result() return CompositeDisposable(sad, Disposable(dispose))
def subscribe( observer: abc.ObserverBase[Observable[_T]], scheduler: Optional[abc.SchedulerBase] = None, ): m = SingleAssignmentDisposable() refCountDisposable = RefCountDisposable(m) n = [0] q: List[Subject[_T]] = [] def create_window(): s: Subject[_T] = Subject() q.append(s) observer.on_next(add_ref(s, refCountDisposable)) create_window() def on_next(x: _T) -> None: for item in q: item.on_next(x) c = n[0] - count + 1 if c >= 0 and c % skip_ == 0: s = q.pop(0) s.on_completed() n[0] += 1 if (n[0] % skip_) == 0: create_window() def on_error(exception: Exception) -> None: while q: q.pop(0).on_error(exception) observer.on_error(exception) def on_completed() -> None: while q: q.pop(0).on_completed() observer.on_completed() m.disposable = source.subscribe(on_next, on_error, on_completed, scheduler=scheduler) return refCountDisposable