예제 #1
0
파일: concat.py 프로젝트: JohnWowUs/RxPY
    def subscribe(observer):
        subscription = SerialDisposable()
        cancelable = SerialDisposable()
        enum = iter(sources)
        is_disposed = []

        def action(action1, state=None):
            if is_disposed:
                return

            def on_completed():
                cancelable.disposable = scheduler.schedule(action)

            try:
                current = next(enum)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe(observer.on_next, observer.on_error, on_completed)

        cancelable.disposable = scheduler.schedule(action)

        def dispose():
            is_disposed.append(True)
        return CompositeDisposable(subscription, cancelable, Disposable.create(dispose))
예제 #2
0
def test_select_disposeinsideselector():
    scheduler = TestScheduler()
    xs = scheduler.create_hot_observable(on_next(100, 1), on_next(200, 2), on_next(500, 3), on_next(600, 4))
    results = scheduler.create_observer()
    d = SerialDisposable()
    invoked = 0
    
    def projection(x, *args, **kw):
        nonlocal invoked
        invoked += 1
        
        if scheduler.clock > 400:
            #print("*** Dispose ****")
            d.dispose()
        return x

    d.disposable = xs.select(projection).subscribe(results)

    def action(scheduler, state):
        return d.dispose()

    scheduler.schedule_absolute(ReactiveTest.disposed, action)
    scheduler.start()
    
    results.messages.assert_equal(on_next(100, 1), on_next(200, 2))
    xs.subscriptions.assert_equal(ReactiveTest.subscribe(0, 500))
    
    assert invoked == 3
예제 #3
0
    def test_map_with_index_dispose_inside_mapper(self):
        scheduler = TestScheduler()
        xs = scheduler.create_hot_observable(on_next(100, 4), on_next(200, 3),
                                             on_next(500, 2), on_next(600, 1))
        invoked = [0]
        results = scheduler.create_observer()
        d = SerialDisposable()

        def projection(x, index):
            invoked[0] += 1
            if scheduler.clock > 400:
                d.dispose()

            return x + index * 10

        d.disposable = xs.map(mapper_indexed=projection).subscribe(results)

        def action(scheduler, state):
            return d.dispose()

        scheduler.schedule_absolute(disposed, action)
        scheduler.start()
        assert results.messages == [on_next(100, 4), on_next(200, 13)]
        assert xs.subscriptions == [subscribe(0, 500)]
        assert invoked[0] == 3
예제 #4
0
    def test_map_disposeinsidemapper(self):
        scheduler = TestScheduler()
        xs = scheduler.create_hot_observable(on_next(100, 1), on_next(200, 2),
                                             on_next(500, 3), on_next(600, 4))
        results = scheduler.create_observer()
        d = SerialDisposable()
        invoked = [0]

        def projection(x, *args, **kw):
            invoked[0] += 1

            if scheduler.clock > 400:
                #print("*** Dispose ****")
                d.dispose()
            return x

        d.disposable = xs.map(projection).subscribe(results)

        def action(scheduler, state):
            return d.dispose()

        scheduler.schedule_absolute(ReactiveTest.disposed, action)
        scheduler.start()

        assert results.messages == [on_next(100, 1), on_next(200, 2)]
        assert xs.subscriptions == [ReactiveTest.subscribe(0, 500)]

        assert invoked[0] == 3
예제 #5
0
def test_mutabledisposable_replacebeforedispose():
    disp1 = False
    disp2 = False
    m = SerialDisposable()

    def action1():
        nonlocal disp1
        disp1 = True

    d1 = Disposable(action1)
    m.disposable = d1

    assert d1 == m.disposable
    assert not disp1

    def action2():
        nonlocal disp2
        disp2 = True

    d2 = Disposable(action2)
    m.disposable = d2

    assert d2 == m.disposable
    assert disp1
    assert not disp2
예제 #6
0
    def subscribe(observer):
        subscription = SerialDisposable()
        cancelable = SerialDisposable()

        def action(scheduler, state=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 = Observable.from_future(source)

            d = SingleAssignmentDisposable()
            subscription.disposable = d

            def on_resume(state=None):
                scheduler.schedule(action, state)

            d.disposable = current.subscribe(observer.on_next, on_resume, on_resume)

        cancelable.disposable = scheduler.schedule(action)
        return CompositeDisposable(subscription, cancelable)
예제 #7
0
 def test_select_disposeinsideselector(self):
     scheduler = TestScheduler()
     xs = scheduler.create_hot_observable(on_next(100, 1), on_next(200, 2), on_next(500, 3), on_next(600, 4))
     results = scheduler.create_observer()
     d = SerialDisposable()
     invoked = [0]
     
     def projection(x, *args, **kw):
         invoked[0] += 1
         
         if scheduler.clock > 400:
             #print("*** Dispose ****")
             d.dispose()
         return x
 
     d.disposable = xs.select(projection).subscribe(results)
 
     def action(scheduler, state):
         return d.dispose()
 
     scheduler.schedule_absolute(ReactiveTest.disposed, action)
     scheduler.start()
     
     results.messages.assert_equal(on_next(100, 1), on_next(200, 2))
     xs.subscriptions.assert_equal(ReactiveTest.subscribe(0, 500))
     
     assert invoked[0] == 3
예제 #8
0
    def subscribe(observer):
        subscription = SerialDisposable()
        cancelable = SerialDisposable()
        enum = iter(sources)
        is_disposed = []

        def action(action1, state=None):
            if is_disposed:
                return

            def on_completed():
                cancelable.disposable = scheduler.schedule(action)

            try:
                current = next(enum)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe(observer.on_next,
                                                 observer.on_error,
                                                 on_completed)

        cancelable.disposable = scheduler.schedule(action)

        def dispose():
            is_disposed.append(True)

        return CompositeDisposable(subscription, cancelable,
                                   Disposable.create(dispose))
예제 #9
0
파일: catch.py 프로젝트: indigos33k3r/RxPY
    def subscribe(observer, scheduler=None):
        d1 = SingleAssignmentDisposable()
        subscription = SerialDisposable()

        subscription.disposable = d1

        def on_error(exception):
            try:
                result = handler(exception)
            except Exception as ex:  # By design. pylint: disable=W0703
                observer.on_error(ex)
                return

            result = Observable.from_future(result) if is_future(result) else result
            d = SingleAssignmentDisposable()
            subscription.disposable = d
            d.disposable = result.subscribe(observer, scheduler)

        d1.disposable = source.subscribe_(
            observer.on_next,
            on_error,
            observer.on_completed,
            scheduler
        )
        return subscription
예제 #10
0
def test_select_with_index_dispose_inside_selector():
    scheduler = TestScheduler()
    xs = scheduler.create_hot_observable(on_next(100, 4), on_next(200, 3), on_next(500, 2), on_next(600, 1))
    invoked = 0
    results = scheduler.create_observer()
    d = SerialDisposable()
    
    def projection(x, index):
        nonlocal invoked
        invoked += 1
        if scheduler.clock > 400:
            d.dispose()
        
        return x + index * 10

    d.disposable = xs.select(projection).subscribe(results)

    def action(scheduler, state):
        return d.dispose()

    scheduler.schedule_absolute(disposed, action)
    scheduler.start()
    results.messages.assert_equal(on_next(100, 4), on_next(200, 13))
    xs.subscriptions.assert_equal(subscribe(0, 500))
    assert invoked == 3
예제 #11
0
 def __init__(self, scheduler, observer):
     super(ScheduledObserver, self).__init__()
     self.scheduler = scheduler
     self.observer = observer
     self.is_acquired = False
     self.has_faulted = False
     self.queue = []
     self.disposable = SerialDisposable()
예제 #12
0
    def subscribe(observer):
        m = SingleAssignmentDisposable()
        d = SerialDisposable()
        d.disposable = m

        def action(scheduler, state):
            d.disposable = ScheduledDisposable(scheduler, source.subscribe(observer))

        m.disposable = scheduler.schedule(action)
        return d
예제 #13
0
    def subscribe(observer, _=None):
        m = SingleAssignmentDisposable()
        d = SerialDisposable()
        d.disposable = m

        def action(scheduler, state):
            d.disposable = ScheduledDisposable(scheduler, source.subscribe(observer))

        m.disposable = scheduler.schedule(action)
        return d
예제 #14
0
    def __init__(self, scheduler, observer):
        super().__init__()

        self.scheduler = scheduler
        self.observer = observer

        self.lock = threading.RLock()
        self.is_acquired = False
        self.has_faulted = False
        self.queue = []
        self.disposable = SerialDisposable()
예제 #15
0
    def __init__(self, scheduler, observer):
        super(ScheduledObserver, self).__init__(self._next, self._error, self._completed)

        self.scheduler = scheduler
        self.observer = observer

        self.lock = Lock()
        self.is_acquired = False
        self.has_faulted = False
        self.queue = []
        self.disposable = SerialDisposable()
예제 #16
0
class ScheduledObserver(AbstractObserver):
    def __init__(self, scheduler, observer):
        super(ScheduledObserver, self).__init__()
        self.scheduler = scheduler
        self.observer = observer
        self.is_acquired = False
        self.has_faulted = False
        self.queue = []
        self.disposable = SerialDisposable()

    def next(self, value):
        def func():
            self.observer.on_next(value)
        self.queue.append(func)
    
    def error(self, exception):
        def func():
            self.observer.on_error(exception)    
        self.queue.append(func)
                
    def completed(self):
        def func():
            self.observer.on_completed()        
        self.queue.append(func)
            
    def ensure_active(self):
        is_owner, parent = False, self
        if not self.has_faulted and len(self.queue):
            is_owner = not self.is_acquired
            self.is_acquired = True
        
        if is_owner:
            def action(action1, state):
                work = None
                if len(parent.queue):
                    work = parent.queue.pop(0)
                else:
                    parent.is_acquired = False
                    return
                
                try:
                    work()
                except Exception as ex:
                    parent.queue = []
                    parent.has_faulted = True
                    raise ex
        
                action1()
            self.disposable.disposable = self.scheduler.schedule_recursive(action)
    
    def dispose(self):
        super(ScheduledObserver, self).dispose()
        self.disposable.dispose()
예제 #17
0
    def __init__(self, scheduler, period, action, state=None):
        """
        Keyword arguments:
        state -- Initial state passed to the action upon the first iteration.
        period -- Period for running the work periodically.
        action -- Action to be executed, potentially updating the state."""

        self._scheduler = scheduler
        self._state = state
        self._period = period
        self._action = action
        self._cancel = SerialDisposable()
예제 #18
0
        def subscribe(observer):
            delays = CompositeDisposable()
            at_end = False

            def done():
                if (at_end and delays.length == 0):
                    observer.on_completed()

            subscription = SerialDisposable()

            def start():
                def on_next(x):
                    try:
                        delay = selector(x)
                    except Exception as error:
                        observer.on_error(error)
                        return

                    d = SingleAssignmentDisposable()
                    delays.add(d)

                    def on_next(_):
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    def on_completed():
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    d.disposable = delay.subscribe(on_next, observer.on_error,
                                                   on_completed)

                def on_completed():
                    nonlocal at_end

                    at_end = True
                    subscription.dispose()
                    done()

                subscription.disposable = source.subscribe(
                    on_next, observer.on_error, on_completed)

            if not sub_delay:
                start()
            else:
                subscription.disposable(
                    sub_delay.subscribe(lambda _: start(), observer.on_error,
                                        lambda: start()))

            return CompositeDisposable(subscription, delays)
예제 #19
0
        def subscribe(observer):
            delays = CompositeDisposable()
            at_end = [False]

            def done():
                if (at_end[0] and delays.length == 0):
                    observer.on_completed()

            subscription = SerialDisposable()

            def start():
                def on_next(x):
                    try:
                        delay = selector(x)
                    except Exception as error:
                        observer.on_error(error)
                        return

                    d = SingleAssignmentDisposable()
                    delays.add(d)

                    def on_next(_):
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    def on_completed():
                        observer.on_next(x)
                        delays.remove(d)
                        done()

                    d.disposable = delay.subscribe(on_next, observer.on_error,
                                                   on_completed)

                def on_completed():
                    at_end[0] = True
                    subscription.dispose()
                    done()

                subscription.disposable = source.subscribe(on_next,
                                                           observer.on_error,
                                                           on_completed)

            if not sub_delay:
                start()
            else:
                subscription.disposable(sub_delay.subscribe(
                    lambda _: start(),
                    observer.on_error,
                    start))

            return CompositeDisposable(subscription, delays)
예제 #20
0
        def subscribe(observer):
            switched = False
            _id = 0

            original = SingleAssignmentDisposable()
            subscription = SerialDisposable()
            timer = SerialDisposable()
            subscription.disposable = original

            def create_timer():
                my_id = _id

                def action(scheduler, state=None):
                    nonlocal switched

                    switched = (_id == my_id)
                    timer_wins = switched
                    if timer_wins:
                        subscription.disposable = other.subscribe(observer)

                timer.disposable = scheduler_method(duetime, action)

            create_timer()

            def on_next(x):
                nonlocal _id

                on_next_wins = not switched
                if on_next_wins:
                    _id += 1
                    observer.on_next(x)
                    create_timer()

            def on_error(e):
                nonlocal _id

                on_error_wins = not switched
                if on_error_wins:
                    _id += 1
                    observer.on_error(e)

            def on_completed():
                nonlocal _id

                on_completed_wins = not switched
                if on_completed_wins:
                    _id += 1
                    observer.on_completed()

            original.disposable = source.subscribe(on_next, on_error,
                                                   on_completed)
            return CompositeDisposable(subscription, timer)
예제 #21
0
파일: timeout.py 프로젝트: xyicheng/RxPY
    def subscribe(observer, scheduler=None):
        scheduler = scheduler or timeout_scheduler

        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 = other.subscribe(
                        observer, 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)
예제 #22
0
        def subscribe(observer):
            switched = False
            _id = 0
            
            original = SingleAssignmentDisposable()
            subscription = SerialDisposable()
            timer = SerialDisposable()
            subscription.disposable = original

            def create_timer():
                my_id = _id

                def action(scheduler, state=None):
                    nonlocal switched

                    switched = (_id == my_id)
                    timer_wins = switched
                    if timer_wins:
                        subscription.disposable = other.subscribe(observer)
                    
                timer.disposable = scheduler_method(duetime, action)

            create_timer()
            def on_next(x):
                nonlocal _id

                on_next_wins = not switched
                if on_next_wins:
                    _id += 1
                    observer.on_next(x)
                    create_timer()

            def on_error(e):
                nonlocal _id

                on_error_wins = not switched
                if on_error_wins:
                    _id += 1
                    observer.on_error(e)

            def on_completed():
                nonlocal _id
                
                on_completed_wins = not switched
                if on_completed_wins:
                    _id += 1
                    observer.on_completed()
            
            original.disposable = source.subscribe(on_next, on_error, on_completed)
            return CompositeDisposable(subscription, timer)
예제 #23
0
    def subscribe(observer, scheduler=None):
        delays = CompositeDisposable()
        at_end = [False]

        def done():
            if (at_end[0] and delays.length == 0):
                observer.on_completed()

        subscription = SerialDisposable()

        def start():
            def on_next(x):
                try:
                    delay = mapper(x)
                except Exception as error:
                    observer.on_error(error)
                    return

                d = SingleAssignmentDisposable()
                delays.add(d)

                def on_next(_):
                    observer.on_next(x)
                    delays.remove(d)
                    done()

                def on_completed():
                    observer.on_next(x)
                    delays.remove(d)
                    done()

                d.disposable = delay.subscribe_(on_next, observer.on_error,
                                                on_completed, scheduler)

            def on_completed():
                at_end[0] = True
                subscription.dispose()
                done()

            subscription.disposable = source.subscribe_(
                on_next, observer.on_error, on_completed, scheduler)

        if not sub_delay:
            start()
        else:
            subscription.disposable(
                sub_delay.subscribe_(lambda _: start(), observer.on_error,
                                     start))

        return CompositeDisposable(subscription, delays)
예제 #24
0
def test_mutabledisposable_dispose():
    disp = [False]
    m = SerialDisposable()

    def action():
        disp[0] = True
    d = Disposable.create(action)
    m.disposable = d

    assert d == m.disposable
    assert not disp[0]
    m.dispose()
    assert disp[0]
    assert m.disposable == None
예제 #25
0
def test_mutabledisposable_dispose():
    disp = False
    m = SerialDisposable()
    
    def action():
        nonlocal disp
        disp = True
    d = Disposable(action)
    m.disposable = d

    assert d == m.disposable
    assert not disp
    m.dispose()
    assert disp
    assert m.disposable == None
예제 #26
0
def test_mutabledisposable_dispose():
    disp = [False]
    m = SerialDisposable()

    def action():
        disp[0] = True

    d = Disposable.create(action)
    m.disposable = d

    assert d == m.disposable
    assert not disp[0]
    m.dispose()
    assert disp[0]
    assert m.disposable == None
예제 #27
0
def test_mutabledisposable_dispose():
    disp = False
    m = SerialDisposable()

    def action():
        nonlocal disp
        disp = True

    d = Disposable(action)
    m.disposable = d

    assert d == m.disposable
    assert not disp
    m.dispose()
    assert disp
    assert m.disposable == None
예제 #28
0
파일: concat.py 프로젝트: vuchau/RxPY
    def subscribe(observer):
        enum = iter(sources)
        is_disposed = [False]
        subscription = SerialDisposable()

        def action(action1, state=None):
            if is_disposed[0]:
                return
            try:
                current = next(enum)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe(
                    observer.on_next,
                    observer.on_error,
                    lambda: action1()
                )

        cancelable = immediate_scheduler.schedule_recursive(action)

        def dispose():
            is_disposed[0] = True
        return CompositeDisposable(subscription, cancelable, Disposable.create(dispose))
예제 #29
0
        def subscribe(observer):
            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))
            return ref_count_disposable
예제 #30
0
 def __init__(self, scheduler, observer):
     super(ScheduledObserver, self).__init__()
     self.scheduler = scheduler
     self.observer = observer
     self.is_acquired = False
     self.has_faulted = False
     self.queue = []
     self.disposable = SerialDisposable()
        def subscribe(observer):
            d1 = SingleAssignmentDisposable()
            subscription = SerialDisposable()

            subscription.disposable = d1
            
            def on_error(exception):
                try:
                    result = handler(exception)
                except Exception as ex:
                    observer.on_error(ex)
                    return
                
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = result.subscribe(observer)
            
            d1.disposable = source.subscribe(observer.on_next, on_error, observer.on_completed)
            return subscription
예제 #32
0
    def subscribe(observer, scheduler=None):
        cancelable = SerialDisposable()
        has_value = [False]
        value = [None]
        _id = [0]

        def on_next(x):
            throttle = None
            try:
                throttle = throttle_duration_mapper(x)
            except Exception as e:
                observer.on_error(e)
                return

            has_value[0] = True
            value[0] = x
            _id[0] += 1
            current_id = _id[0]
            d = SingleAssignmentDisposable()
            cancelable.disposable = d

            def on_next(x):
                if has_value[0] and _id[0] == current_id:
                    observer.on_next(value[0])

                has_value[0] = False
                d.dispose()

            def on_completed():
                if has_value[0] and _id[0] == current_id:
                    observer.on_next(value[0])

                has_value[0] = False
                d.dispose()

            d.disposable = throttle.subscribe_(on_next, observer.on_error,
                                               on_completed, scheduler)

        def on_error(e):
            cancelable.dispose()
            observer.on_error(e)
            has_value[0] = False
            _id[0] += 1

        def on_completed():
            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)
        return CompositeDisposable(subscription, cancelable)
예제 #33
0
    def subscribe(observer, scheduler=None):
        scheduler = scheduler or immediate_scheduler

        queue = []
        m = SerialDisposable()
        d = CompositeDisposable(m)
        active_count = [0]
        is_acquired = [False]

        def ensure_active():
            is_owner = False
            if queue:
                is_owner = not is_acquired[0]
                is_acquired[0] = True

            def action(scheduler, state):
                if queue:
                    work = queue.pop(0)
                else:
                    is_acquired[0] = False
                    return

                sad = SingleAssignmentDisposable()
                d.add(sad)

                def on_next(value):
                    observer.on_next(value)
                    result = None
                    try:
                        result = mapper(value)
                    except Exception as ex:
                        observer.on_error(ex)
                        return

                    queue.append(result)
                    active_count[0] += 1
                    ensure_active()

                def on_complete():
                    d.remove(sad)
                    active_count[0] -= 1
                    if active_count[0] == 0:
                        observer.on_completed()

                sad.disposable = work.subscribe_(on_next, observer.on_error,
                                                 on_complete, scheduler)
                m.disposable = scheduler.schedule(action)

            if is_owner:
                m.disposable = scheduler.schedule(action)

        queue.append(source)
        active_count[0] += 1
        ensure_active()
        return d
        def subscribe(observer):
            d1 = SingleAssignmentDisposable()
            subscription = SerialDisposable()

            subscription.disposable = d1

            def on_error(exception):
                try:
                    result = handler(exception)
                except Exception as ex:
                    observer.on_error(ex)
                    return

                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = result.subscribe(observer)

            d1.disposable = source.subscribe(observer.on_next, on_error,
                                             observer.on_completed)
            return subscription
예제 #35
0
def test_mutabledisposable_replacebeforedispose():
    disp1 = [False]
    disp2 = [False]
    m = SerialDisposable()

    def action1():
        disp1[0] = True
    d1 = Disposable.create(action1)
    m.disposable = d1

    assert d1 == m.disposable
    assert not disp1[0]

    def action2():
        disp2[0] = True
    d2 = Disposable.create(action2)
    m.disposable = d2

    assert d2 == m.disposable
    assert disp1[0]
    assert not disp2[0]
예제 #36
0
def test_mutabledisposable_replaceafterdispose():
    disp1 = [False]
    disp2 = [False]
    m = SerialDisposable()
    m.dispose()

    def action1():
        disp1[0] = True
    d1 = Disposable.create(action1)
    m.disposable = d1

    assert m.disposable == None
    assert disp1[0]

    def action2():
        disp2[0] = True
    d2 = Disposable.create(action2)
    m.disposable = d2

    assert m.disposable == None
    assert disp2[0]
예제 #37
0
    def __init__(self, scheduler, period, action, state=None):
        """
        Keyword arguments:
        state -- Initial state passed to the action upon the first iteration.
        period -- Period for running the work periodically.
        action -- Action to be executed, potentially updating the state."""

        self._scheduler = scheduler
        self._state = state
        self._period = period
        self._action = action
        self._cancel = SerialDisposable()
예제 #38
0
    def subscribe(observer):
        q = []
        m = SerialDisposable()
        d = CompositeDisposable(m)
        active_count = [0]
        is_acquired = [False]

        def ensure_active():
            is_owner = False
            if len(q) > 0:
                is_owner = not is_acquired[0]
                is_acquired[0] = True

            if is_owner:

                def action(this, state):
                    if len(q) > 0:
                        work = q.pop(0)
                    else:
                        is_acquired[0] = False
                        return

                    m1 = SingleAssignmentDisposable()
                    d.add(m1)

                    def on_next(x):
                        observer.on_next(x)
                        result = None
                        try:
                            result = selector(x)
                        except Exception as ex:
                            observer.on_error(ex)

                        q.append(result)
                        active_count[0] += 1
                        ensure_active()

                    def on_complete():
                        d.remove(m1)
                        active_count[0] -= 1
                        if active_count[0] == 0:
                            observer.on_completed()

                    m1.disposable = work.subscribe(on_next, observer.on_error,
                                                   on_complete)
                    this()

                m.disposable = scheduler.schedule_recursive(action)

        q.append(source)
        active_count[0] += 1
        ensure_active()
        return d
예제 #39
0
def test_mutabledisposable_replaceafterdispose():
    disp1 = False
    disp2 = False
    m = SerialDisposable()
    m.dispose()

    def action1():
        nonlocal disp1
        disp1 = True

    d1 = Disposable(action1)
    m.disposable = d1

    assert m.disposable == None
    assert disp1

    def action2():
        nonlocal disp2
        disp2 = True

    d2 = Disposable(action2)
    m.disposable = d2

    m.disposable == None
    assert disp2
예제 #40
0
def test_mutabledisposable_replacebeforedispose():
    disp1 = False
    disp2 = False
    m = SerialDisposable()

    def action1():
        nonlocal disp1
        disp1 = True
    d1 = Disposable(action1)
    m.disposable = d1

    assert d1 == m.disposable
    assert not disp1

    def action2():
        nonlocal disp2
        disp2 = True
    d2 = Disposable(action2)
    m.disposable = d2

    assert d2 == m.disposable
    assert disp1
    assert not disp2
예제 #41
0
def test_mutabledisposable_replacebeforedispose():
    disp1 = [False]
    disp2 = [False]
    m = SerialDisposable()

    def action1():
        disp1[0] = True

    d1 = Disposable.create(action1)
    m.disposable = d1

    assert d1 == m.disposable
    assert not disp1[0]

    def action2():
        disp2[0] = True

    d2 = Disposable.create(action2)
    m.disposable = d2

    assert d2 == m.disposable
    assert disp1[0]
    assert not disp2[0]
예제 #42
0
def test_mutabledisposable_replaceafterdispose():
    disp1 = False
    disp2 = False
    m = SerialDisposable()
    m.dispose()

    def action1():
        nonlocal disp1
        disp1 = True
    d1 = Disposable(action1)
    m.disposable = d1

    assert m.disposable == None
    assert disp1

    def action2():
        nonlocal disp2
        disp2 = True
    d2 = Disposable(action2)
    m.disposable = d2

    m.disposable == None
    assert disp2
예제 #43
0
class SchedulePeriodic(object):
    """Scheduler with support for running periodic tasks. This type of
    scheduler can be used to run timers more efficiently instead of using
    recursive scheduling."""
    def __init__(self, scheduler, period, action, state=None):
        """
        Keyword arguments:
        state -- Initial state passed to the action upon the first iteration.
        period -- Period for running the work periodically.
        action -- Action to be executed, potentially updating the state."""

        self._scheduler = scheduler
        self._state = state
        self._period = period
        self._action = action
        self._cancel = SerialDisposable()

    def tick(self, scheduler, command):
        self._cancel.disposable = self._scheduler.schedule_relative(
            self._period, self.tick, 0)
        try:
            new_state = self._action(self._state)
        except Exception:
            self._cancel.dispose()
            raise
        else:
            if new_state is not None:  # Update state if other than None
                self._state = new_state

    def start(self):
        """Returns the disposable object used to cancel the scheduled recurring
        action (best effort).
        """

        self._cancel.disposable = self._scheduler.schedule_relative(
            self._period, self.tick, 0)
        return self._cancel
예제 #44
0
class SchedulePeriodic(object):
    """Scheduler with support for running periodic tasks. This type of
    scheduler can be used to run timers more efficiently instead of using
    recursive scheduling."""

    def __init__(self, scheduler, period, action, state=None):
        """
        Keyword arguments:
        state -- Initial state passed to the action upon the first iteration.
        period -- Period for running the work periodically.
        action -- Action to be executed, potentially updating the state."""

        self._scheduler = scheduler
        self._state = state
        self._period = period
        self._action = action
        self._cancel = SerialDisposable()

    def tick(self, scheduler, command):
        self._cancel.disposable = self._scheduler.schedule_relative(self._period, self.tick, 0)
        try:
            new_state = self._action(self._state)
        except Exception:
            self._cancel.dispose()
            raise
        else:
            if new_state is not None:  # Update state if other than None
                self._state = new_state

    def start(self):
        """Returns the disposable object used to cancel the scheduled recurring
        action (best effort).
        """

        self._cancel.disposable = self._scheduler.schedule_relative(self._period, self.tick, 0)
        return self._cancel
예제 #45
0
파일: concat.py 프로젝트: xyicheng/RxPY
    def subscribe(observer, scheduler=None):
        scheduler = scheduler or current_thread_scheduler

        subscription = SerialDisposable()
        cancelable = SerialDisposable()
        is_disposed = False

        def action(action1, state=None):
            nonlocal is_disposed
            if is_disposed:
                return

            def on_completed():
                cancelable.disposable = scheduler.schedule(action)

            try:
                current = next(sources)
            except StopIteration:
                observer.on_completed()
            except Exception as ex:
                observer.on_error(ex)
            else:
                d = SingleAssignmentDisposable()
                subscription.disposable = d
                d.disposable = current.subscribe_(observer.on_next,
                                                  observer.on_error,
                                                  on_completed, scheduler)

        cancelable.disposable = scheduler.schedule(action)

        def dispose():
            nonlocal is_disposed
            is_disposed = True

        return CompositeDisposable(subscription, cancelable,
                                   Disposable.create(dispose))
예제 #46
0
        def subscribe(observer):
            subscription = SerialDisposable()
            timer = SerialDisposable()
            original = SingleAssignmentDisposable()

            subscription.disposable = original

            switched = False
            _id = [0]

            def set_timer(timeout):
                my_id = _id[0]

                def timer_wins():
                    return _id[0] == my_id

                d = SingleAssignmentDisposable()
                timer.disposable = d

                def on_next(x):
                    if timer_wins():
                        subscription.disposable = other.subscribe(observer)

                    d.dispose()

                def on_error(e):
                    if timer_wins():
                        observer.on_error(e)

                def on_completed():
                    if timer_wins():
                        subscription.disposable = other.subscribe(observer)

                d.disposable = timeout.subscribe(on_next, on_error, on_completed)

            set_timer(first_timeout)

            def observer_wins():
                res = not switched
                if res:
                    _id[0] += 1

                return res

            def on_next(x):
                if observer_wins():
                    observer.on_next(x)
                    timeout = None
                    try:
                        timeout = timeout_duration_selector(x)
                    except Exception as e:
                        observer.on_error(e)
                        return

                    set_timer(timeout)

            def on_error(e):
                if observer_wins():
                    observer.on_error(e)

            def on_completed():
                if observer_wins():
                    observer.on_completed()

            original.disposable = source.subscribe(on_next, on_error, on_completed)
            return CompositeDisposable(subscription, timer)
예제 #47
0
class ScheduledObserver(AbstractObserver):
    def __init__(self, scheduler, observer):
        super(ScheduledObserver, self).__init__(self._next, self._error, self._completed)

        self.scheduler = scheduler
        self.observer = observer

        self.lock = Lock()
        self.is_acquired = False
        self.has_faulted = False
        self.queue = []
        self.disposable = SerialDisposable()

        # Note to self: list append is thread safe
        # http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm

    def _next(self, value):
        def action():
            self.observer.on_next(value)
        self.queue.append(action)

    def _error(self, exception):
        def action():
            self.observer.on_error(exception)
        self.queue.append(action)

    def _completed(self):
        def action():
            self.observer.on_completed()
        self.queue.append(action)

    def ensure_active(self):
        is_owner = False

        with self.lock:
            if not self.has_faulted and len(self.queue):
                is_owner = not self.is_acquired
                self.is_acquired = True

        if is_owner:
            self.disposable.disposable = self.scheduler.schedule_recursive(self.run)

    def run(self, recurse, state):
        parent = self

        with self.lock:
            if len(parent.queue):
                work = parent.queue.pop(0)
            else:
                parent.is_acquired = False
                return

        try:
            work()
        except Exception:
            with self.lock:
                parent.queue = []
                parent.has_faulted = True
            raise

        recurse()

    def dispose(self):
        super(ScheduledObserver, self).dispose()
        self.disposable.dispose()