Example #1
0
def test_refcountdisposable_primarydisposesfirst():
    d = BooleanDisposable()
    r = RefCountDisposable(d)
    assert not d.is_disposed
    d1 = r.disposable
    d2 = r.disposable
    assert not d.is_disposed
    d1.dispose()
    assert not d.is_disposed
    r.dispose()
    assert not d.is_disposed
    d2.dispose()
    assert d.is_disposed
Example #2
0
def test_refcountdisposable_refcounting():
    d = BooleanDisposable()
    r = RefCountDisposable(d)
    assert not d.is_disposed
    d1 = r.disposable
    d2 = r.disposable
    assert not d.is_disposed
    d1.dispose()
    assert not d.is_disposed
    d2.dispose()
    assert not d.is_disposed
    r.dispose()
    assert d.is_disposed
    d3 = r.disposable
    d3.dispose()
Example #3
0
def test_refcountdisposable_singlereference():
    d = BooleanDisposable()
    r = RefCountDisposable(d)

    assert not d.is_disposed
    r.dispose()
    assert d.is_disposed
    r.dispose()
    assert d.is_disposed
Example #4
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ):
            m = SerialDisposable()
            d = CompositeDisposable(m)
            r = RefCountDisposable(d)
            window: Subject[_T] = Subject()

            observer.on_next(add_ref(window, r))

            def on_next(value: _T) -> None:
                window.on_next(value)

            def on_error(error: Exception) -> None:
                window.on_error(error)
                observer.on_error(error)

            def on_completed() -> None:
                window.on_completed()
                observer.on_completed()

            d.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler))

            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)

            create_window_on_completed()
            return r
Example #5
0
        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
Example #6
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            window_subject: Subject[_T] = Subject()
            d = CompositeDisposable()
            r = RefCountDisposable(d)

            observer.on_next(add_ref(window_subject, r))

            def on_next_window(x: _T) -> None:
                window_subject.on_next(x)

            def on_error(err: Exception) -> None:
                window_subject.on_error(err)
                observer.on_error(err)

            def on_completed() -> None:
                window_subject.on_completed()
                observer.on_completed()

            d.add(
                source.subscribe(on_next_window,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler))

            def on_next_observer(w: Observable[_T]):
                nonlocal window_subject
                window_subject.on_completed()
                window_subject = Subject()
                observer.on_next(add_ref(window_subject, r))

            d.add(
                boundaries.subscribe(on_next_observer,
                                     on_error,
                                     on_completed,
                                     scheduler=scheduler))
            return r
Example #7
0
        def subscribe(
            observer: abc.ObserverBase[Tuple[_TLeft, Observable[_TRight]]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            group = CompositeDisposable()
            rcd = RefCountDisposable(group)
            left_map: OrderedDict[int, Subject[_TRight]] = OrderedDict()
            right_map: OrderedDict[int, _TRight] = OrderedDict()
            left_id = [0]
            right_id = [0]

            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 on_error_left(error: Exception) -> None:
                for left_value in left_map.values():
                    left_value.on_error(error)

                observer.on_error(error)

            group.add(
                left.subscribe(
                    on_next_left,
                    on_error_left,
                    observer.on_completed,
                    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 on_error_right(error: Exception) -> None:
                for left_value in left_map.values():
                    left_value.on_error(error)

                observer.on_error(error)

            group.add(
                right.subscribe(send_right,
                                on_error_right,
                                scheduler=scheduler))
            return rcd
Example #8
0
        def subscribe(
            observer: abc.ObserverBase[GroupedObservable[_TKey, _TValue]],
            scheduler: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            writers: OrderedDict[_TKey, Subject[_TValue]] = OrderedDict()
            group_disposable = CompositeDisposable()
            ref_count_disposable = RefCountDisposable(group_disposable)

            def on_next(x: _T) -> None:
                writer = None
                key = None

                try:
                    key = key_mapper(x)
                except Exception as e:
                    for wrt in writers.values():
                        wrt.on_error(e)

                    observer.on_error(e)
                    return

                fire_new_map_entry = False
                writer = writers.get(key)
                if not writer:
                    try:
                        writer = subject_mapper_()
                    except Exception as e:
                        for wrt in writers.values():
                            wrt.on_error(e)

                        observer.on_error(e)
                        return

                    writers[key] = writer
                    fire_new_map_entry = True

                if fire_new_map_entry:
                    group: GroupedObservable[_TKey,
                                             _TValue] = GroupedObservable(
                                                 key, writer,
                                                 ref_count_disposable)
                    duration_group: GroupedObservable[_TKey,
                                                      Any] = GroupedObservable(
                                                          key, writer)
                    try:
                        duration = duration_mapper(duration_group)
                    except Exception as e:
                        for wrt in writers.values():
                            wrt.on_error(e)

                        observer.on_error(e)
                        return

                    observer.on_next(group)
                    sad = SingleAssignmentDisposable()
                    group_disposable.add(sad)

                    def expire():
                        if writers[key]:
                            del writers[key]
                            writer.on_completed()

                        group_disposable.remove(sad)

                    def on_next(value: Any) -> None:
                        pass

                    def on_error(exn: Exception) -> None:
                        for wrt in writers.values():
                            wrt.on_error(exn)
                        observer.on_error(exn)

                    def on_completed():
                        expire()

                    sad.disposable = duration.pipe(ops.take(1)).subscribe(
                        on_next, on_error, on_completed, scheduler=scheduler)

                try:
                    element = element_mapper_(x)
                except Exception as error:
                    for wrt in writers.values():
                        wrt.on_error(error)

                    observer.on_error(error)
                    return

                writer.on_next(element)

            def on_error(ex: Exception) -> None:
                for wrt in writers.values():
                    wrt.on_error(ex)

                observer.on_error(ex)

            def on_completed() -> None:
                for wrt in writers.values():
                    wrt.on_completed()

                observer.on_completed()

            group_disposable.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler))
            return ref_count_disposable
Example #9
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ):
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            timer_d = SerialDisposable()
            next_shift = [timeshift]
            next_span = [timespan]
            total_time = [DELTA_ZERO]
            queue: List[Subject[_T]] = []

            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

                @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)

            queue.append(Subject())
            observer.on_next(add_ref(queue[0], ref_count_disposable))
            create_timer()

            def on_next(x: _T) -> None:
                with source.lock:
                    for s in queue:
                        s.on_next(x)

            @synchronized(source.lock)
            def on_error(e: Exception) -> None:
                for s in queue:
                    s.on_error(e)

                observer.on_error(e)

            @synchronized(source.lock)
            def on_completed() -> None:
                for s in queue:
                    s.on_completed()

                observer.on_completed()

            group_disposable.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler_))
            return ref_count_disposable
Example #10
0
        def subscribe(
            observer: abc.ObserverBase[Observable[_T]],
            scheduler_: Optional[abc.SchedulerBase] = None,
        ) -> abc.DisposableBase:
            _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton(
            )

            n: int = 0
            s: Subject[_T] = Subject()
            timer_d = SerialDisposable()
            window_id = 0
            group_disposable = CompositeDisposable(timer_d)
            ref_count_disposable = RefCountDisposable(group_disposable)

            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)

            observer.on_next(add_ref(s, ref_count_disposable))
            create_timer(0)

            def on_next(x: _T) -> None:
                nonlocal n, s, window_id
                new_window = False
                new_id = 0

                s.on_next(x)
                n += 1
                if n == count:
                    new_window = True
                    n = 0
                    window_id += 1
                    new_id = window_id
                    s.on_completed()
                    s = Subject()
                    observer.on_next(add_ref(s, ref_count_disposable))

                if new_window:
                    create_timer(new_id)

            def on_error(e: Exception) -> None:
                s.on_error(e)
                observer.on_error(e)

            def on_completed() -> None:
                s.on_completed()
                observer.on_completed()

            group_disposable.add(
                source.subscribe(on_next,
                                 on_error,
                                 on_completed,
                                 scheduler=scheduler_))
            return ref_count_disposable