Esempio n. 1
0
def merge(source, *args, max_concurrent=None):
    """Merges an observable sequence of observable sequences into an
    observable sequence, limiting the number of concurrent subscriptions
    to inner sequences. Or merges two observable sequences into a single
    observable sequence.

    1 - merged = sources.merge(max_concurrent=1)
    2 - merged = source.merge(other_source)

    Keyword arguments:
    max_concurrent -- [Optional] Maximum number of inner observable
        sequences being subscribed to concurrently or the second
        observable sequence.

    Returns the observable sequence that merges the elements of the
    inner sequences.
    """

    if max_concurrent is None:
        args = tuple([source]) + args
        return Observable.merge(*args)

    def subscribe(observer, scheduler=None):
        active_count = [0]
        group = CompositeDisposable()
        is_stopped = [False]
        queue = []

        def subscribe(xs):
            subscription = SingleAssignmentDisposable()
            group.add(subscription)

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

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

        def on_next(inner_source):
            if active_count[0] < max_concurrent:
                active_count[0] += 1
                subscribe(inner_source)
            else:
                queue.append(inner_source)

        def on_completed():
            is_stopped[0] = True
            if active_count[0] == 0:
                observer.on_completed()

        group.add(source.subscribe_(on_next, observer.on_error, on_completed, scheduler))
        return group
    return AnonymousObservable(subscribe)
Esempio n. 2
0
File: merge.py Progetto: zmyer/RxPY
def merge(self, *args, **kwargs):
    """Merges an observable sequence of observable sequences into an
    observable sequence, limiting the number of concurrent subscriptions
    to inner sequences. Or merges two observable sequences into a single
    observable sequence.

    1 - merged = sources.merge(1)
    2 - merged = source.merge(other_source)

    max_concurrent_or_other [Optional] Maximum number of inner observable
        sequences being subscribed to concurrently or the second
        observable sequence.

    Returns the observable sequence that merges the elements of the inner
    sequences.
    """

    if not isinstance(args[0], int):
        args = args + tuple([self])
        return Observable.merge(*args, **kwargs)

    max_concurrent = args[0]
    sources = self

    def subscribe(observer):
        active_count = [0]
        group = CompositeDisposable()
        is_stopped = [False]
        q = []

        def subscribe(xs):
            subscription = SingleAssignmentDisposable()
            group.add(subscription)

            def on_completed():
                group.remove(subscription)
                if len(q):
                    s = q.pop(0)
                    subscribe(s)
                else:
                    active_count[0] -= 1
                    if is_stopped[0] and active_count[0] == 0:
                        observer.on_completed()

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

        def on_next(inner_source):
            if active_count[0] < max_concurrent:
                active_count[0] += 1
                subscribe(inner_source)
            else:
                q.append(inner_source)

        def on_completed():
            is_stopped[0] = True
            if active_count[0] == 0:
                observer.on_completed()

        group.add(sources.subscribe(on_next, observer.on_error, on_completed))
        return group
    return AnonymousObservable(subscribe)