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