コード例 #1
0
    def test_should_work_with_asynchronous_subscribers(self):
        subject = PublishSubject()

        def gen_observers():
            for i in range(10):
                o1 = TestObserver()
                subject.subscribe(o1, self.scheduler)
                yield o1

        obs_list = list(gen_observers())

        for i in range(10):
            ack = subject.on_next(i)
            self.assertFalse(ack.has_value)

            for o in obs_list:
                o.ack.on_next(continue_ack)
                o.ack.on_completed()

            self.assertTrue(ack.has_value)
            # todo: e+1??
            self.assertEqual(sum(sum(o.received) for o in obs_list),
                             sum(e + 1 for e in range(i)) * 10)

        subject.on_completed()
        self.assertTrue(all(o.is_completed for o in obs_list))
コード例 #2
0
    def test_should_emit_from_the_point_of_subscription_forward(self):
        subject = PublishSubject()

        self.assertIsInstance(subject.on_next(1), Continue)
        self.assertIsInstance(subject.on_next(2), Continue)
        self.assertIsInstance(subject.on_next(3), Continue)

        o1 = TestObserver()
        o1.immediate_continue = 5

        subject.unsafe_subscribe(o1, self.scheduler, CurrentThreadScheduler())

        self.assertIsInstance(subject.on_next(4), Continue)
        self.assertIsInstance(subject.on_next(5), Continue)
        self.assertIsInstance(subject.on_next(6), Continue)
        subject.on_completed()

        self.assertEqual(sum(o1.received), 15)
        self.assertTrue(o1.is_completed)
コード例 #3
0
    def share(self):
        """ Converts this observable into a multicast observable that backpressures only after each subscribed
        observer backpressures. Note that this observable is subscribed when the multicast observable is subscribed for
        the first time. Therefore, this observable is never subscribed more than once.

        :return: multicast observable
        """

        observable = ConnectableObservable(
            source=self, subject=PublishSubject()).ref_count()
        return ObservableOp(observable)
コード例 #4
0
    def test_subscribe_after_complete_should_complete_immediately(self):
        subject = PublishSubject()
        subject.on_completed()

        o1 = TestObserver()
        subject.subscribe(o1, self.scheduler)
        self.assertTrue(o1.is_completed)
コード例 #5
0
    def test_unsubscribe_after_on_complete(self):
        subject = PublishSubject()
        o1 = TestObserver()
        d = subject.subscribe(o1, self.scheduler)

        subject.on_next(1)
        subject.on_completed()

        self.scheduler.advance_by(1)
        d.dispose()
        self.assertListEqual(o1.received, [1])
コード例 #6
0
    def test_on_error_should_terminate_current_and_future_subscribers(self):
        subject = PublishSubject()
        dummy = Exception('dummy')

        def gen_observers():
            for i in range(10):
                o1 = TestObserver()
                subject.subscribe(o1, self.scheduler)
                yield o1

        obs_list = list(gen_observers())

        subject.on_next(1)
        subject.on_error(dummy)

        o1 = TestObserver()
        subject.subscribe(o1, self.scheduler)

        for obs in obs_list:
            self.assertListEqual(obs.received, [1])
            self.assertEqual(obs.was_thrown, dummy)

        self.assertEqual(o1.was_thrown, dummy)
コード例 #7
0
    def test_should_work_synchronously_for_synchronous_subscribers(self):
        subject = PublishSubject()

        def gen_observers():
            for i in range(10):
                o1 = TestObserver()
                o1.immediate_continue = 5
                subject.subscribe(o1, self.scheduler)
                yield o1

        obs_list = list(gen_observers())

        self.assertIsInstance(subject.on_next(1), Continue)
        self.assertIsInstance(subject.on_next(2), Continue)
        self.assertIsInstance(subject.on_next(3), Continue)
        subject.on_completed()

        self.assertEqual(sum(sum(o.received) for o in obs_list), 60)
        self.assertTrue(all(o.is_completed for o in obs_list))
コード例 #8
0
ファイル: window.py プロジェクト: ilienert/rxbackpressure
        def on_next_left(left_val):
            # left has been requested because of initial state,
            # or because right is higher than left

            left_elem[0] = left_val
            left_ack[0] = Ack()
            publish_subject[0] = PublishSubject()

            # send next inner observable; subscribe needs to happen immediately
            outer_ack[0] = left_observer[0].on_next(
                (left_val, publish_subject[0]))  # todo: make this private

            with lock:
                has_left_elem[0] = True

                if has_right_elem[0]:
                    has_right = True
                else:
                    # race condition: left element is receieved first
                    has_right = False

            if has_right:
                right_val = right_elem[0]

                if left_is_lower(left_val, right_val):
                    # right is higher than left
                    # send (empty) inner observable and request new left; don't discard right element
                    # inner observable is empty, because left has just been received

                    # discard left element
                    has_left_elem[0] = False
                    left_elem[0] = None

                    # complete (empty) inner observable
                    publish_subject[0].on_completed()

                    # continue next left element after outer acknowledgment
                    return outer_ack[0]
                if left_is_higher(left_val, right_val):
                    # right is lower than left, discard right and request new right
                    # this is possible in initial phase or if is_lower and is_higher are not tight

                    assert right_ack[0] is not None, 'missing acknowledgment'

                    with lock:
                        # avoids completing observer twice

                        # discard right element
                        has_right_elem[0] = False
                        right_elem[0] = None

                        if has_completed[0]:
                            complete_observer = True
                        else:
                            complete_observer = False

                    if complete_observer:
                        left_observer[0].on_completed()
                        right_observer[0].on_completed()
                        return Stop()

                    ack = right_observer[0].on_next((False, right_val))

                    # request new right
                    ack.connect_ack(next_ack=right_ack[0])

                else:
                    # left is equal to right, send right element, request new right

                    with lock:
                        # avoids completing observer twice

                        # discard right element
                        has_right_elem[0] = False
                        right_elem[0] = None

                        if has_completed[0]:
                            complete_observer = True
                        else:
                            complete_observer = False

                    if complete_observer:
                        left_observer[0].on_completed()
                        right_observer[0].on_completed()
                        return Stop()

                    # send right element
                    ack = publish_subject[0].on_next(right_val)
                    ack2 = right_observer[0].on_next((True, right_val))

                    # request new right element
                    ack.connect_ack_2(ack2=ack2, next_ack=right_ack[0])

            return_ack = left_ack[0].merge_ack(outer_ack[0])

            # return left_ack[0]
            return return_ack
コード例 #9
0
 def __init__(self, source, subject=None):
     super().__init__()
     self.source = source
     self.subject = subject or PublishSubject()
     self.has_subscription = False
     self.subscription = None