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 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 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 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 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 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 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 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 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)
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 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 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_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(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 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 test_futuredisposable_disposeafterset(): d = SingleAssignmentDisposable() disposed = [False] def action(): disposed[0] = True dd = Disposable(action) d.disposable = dd assert dd == d.disposable assert not disposed[0] d.dispose() assert disposed[0] d.dispose() assert disposed[0]
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 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 test_futuredisposable_disposebeforeset(): disposed = [False] def dispose(): disposed[0] = True d = SingleAssignmentDisposable() dd = Disposable(dispose) assert not disposed[0] d.dispose() assert not disposed[0] d.disposable = dd assert d.disposable == None assert disposed[0] d.dispose() assert disposed[0]
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 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
def create_timer(_id: int): nonlocal n, s, window_id m = SingleAssignmentDisposable() timer_d.disposable = m def action(scheduler: abc.SchedulerBase, state: Any = None): nonlocal n, s, window_id if _id != window_id: return n = 0 window_id += 1 new_id = window_id s.on_completed() s = Subject() observer.on_next(add_ref(s, ref_count_disposable)) create_timer(new_id) m.disposable = _scheduler.schedule_relative(timespan, action)
def subscribe( observer: abc.ObserverBase[_T], scheduler: Optional[abc.SchedulerBase] = None, ): group = CompositeDisposable() is_stopped = [False] m = SingleAssignmentDisposable() group.add(m) def on_next(inner_source: Union[Observable[_T], "Future[_T]"]): inner_subscription = SingleAssignmentDisposable() group.add(inner_subscription) inner_source = (from_future(inner_source) if isinstance( inner_source, Future) else inner_source) @synchronized(source.lock) def on_completed(): group.remove(inner_subscription) if is_stopped[0] and len(group) == 1: observer.on_completed() on_next: typing.OnNext[_T] = synchronized(source.lock)( observer.on_next) on_error = synchronized(source.lock)(observer.on_error) subscription = inner_source.subscribe(on_next, on_error, on_completed, scheduler=scheduler) inner_subscription.disposable = subscription def on_completed(): is_stopped[0] = True if len(group) == 1: observer.on_completed() m.disposable = source.subscribe(on_next, observer.on_error, on_completed, scheduler=scheduler) return group
def on_next(inner_source: Union[Observable[_T], "Future[_T]"]): inner_subscription = SingleAssignmentDisposable() group.add(inner_subscription) inner_source = (from_future(inner_source) if isinstance( inner_source, Future) else inner_source) @synchronized(source.lock) def on_completed(): group.remove(inner_subscription) if is_stopped[0] and len(group) == 1: observer.on_completed() on_next: typing.OnNext[_T] = synchronized(source.lock)( observer.on_next) on_error = synchronized(source.lock)(observer.on_error) subscription = inner_source.subscribe(on_next, on_error, on_completed, scheduler=scheduler) inner_subscription.disposable = subscription
def subscribe(xs: Observable[_T]): subscription = SingleAssignmentDisposable() group.add(subscription) @synchronized(source.lock) def on_completed(): group.remove(subscription) if queue: s = queue.pop(0) subscribe(s) else: active_count[0] -= 1 if is_stopped[0] and active_count[0] == 0: observer.on_completed() on_next = synchronized(source.lock)(observer.on_next) on_error = synchronized(source.lock)(observer.on_error) subscription.disposable = xs.subscribe(on_next, on_error, on_completed, scheduler=scheduler)
def action(scheduler: abc.SchedulerBase, state: Any = None): nonlocal is_acquired, active_count if queue: work = queue.pop(0) else: is_acquired = False return sad = SingleAssignmentDisposable() d.add(sad) def on_next(value: _T) -> None: nonlocal active_count observer.on_next(value) result = None try: result = mapper(value) except Exception as ex: observer.on_error(ex) return queue.append(result) active_count += 1 ensure_active() def on_complete() -> None: nonlocal active_count d.remove(sad) active_count -= 1 if active_count == 0: observer.on_completed() sad.disposable = work.subscribe(on_next, observer.on_error, on_complete, scheduler=scheduler) m.disposable = scheduler.schedule(action)
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 @synchronized(source.lock) def action(scheduler: abc.SchedulerBase, state: Any = None): s: Optional[Subject[_T]] = None if is_shift: s = Subject() queue.append(s) observer.on_next(add_ref(s, ref_count_disposable)) if is_span: s = queue.pop(0) s.on_completed() create_timer() m.disposable = _scheduler.schedule_relative(ts, action)
def action(scheduler: abc.SchedulerBase, state: Optional[Exception] = None) -> 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 = (reactivex.from_future(source) if isinstance( source, Future) else source) d = SingleAssignmentDisposable() subscription.disposable = d def on_resume(state: Optional[Exception] = None) -> None: scheduler.schedule(action, state) d.disposable = current.subscribe(observer.on_next, on_resume, on_resume, scheduler=scheduler)
def subscribeall( parent: Observable[Any], *children: Observable[Any] ) -> List[SingleAssignmentDisposable]: values = [NO_VALUE for _ in children] 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 parent_subscription = SingleAssignmentDisposable() def on_next(value: Any) -> None: with parent.lock: if NO_VALUE not in values: result = (value,) + tuple(values) observer.on_next(result) children_subscription = [ subscribechild(i, child) for i, child in enumerate(children) ] disp = parent.subscribe( on_next, observer.on_error, observer.on_completed, scheduler=scheduler ) parent_subscription.disposable = disp return [parent_subscription] + children_subscription