def test_range_double_subscribe(self): scheduler = TestScheduler() obs = rx.range(1, 4) results = scheduler.start(lambda: obs.pipe(ops.concat(obs))) assert results.messages == [on_next(200, 1), on_next(200, 2), on_next(200, 3), on_next(200, 1), on_next(200, 2), on_next(200, 3), on_completed(200)]
def enqueue(self, observable: Observable, group: str = 'default-group', retries: int = 0, description: str = None) -> Observable: def log_status(status): logging.debug( str({ 'WorkQueue': str(self), 'group': group, status: description })) log_status('ENQUEUED') output = Subject() errors = Subject() output_finalized = Subject() def handle_error(e, _): log_status('FAILED') errors.on_next(e) return empty() def set_output_finalized(): output_finalized.on_next(True) work = of(True).pipe( do_action(lambda _: log_status('STARTED')), take_until(output_finalized), flat_map(lambda _: observable.pipe( map(lambda value: of({ 'value': value, 'output': output })), retry_with_backoff( retries=retries, description='{}.enqueue(group={}, description={})'.format( self, group, description)), catch(handler=handle_error), take_until(output_finalized), take_until_disposed())), concat(of(of({ 'completed': True, 'output': output }))), finally_action(lambda: log_status('COMPLETED'))) self._queue.on_next({'work': work, 'group': group}) return output.pipe(observe_on(self.request_scheduler), throw_when(errors), take_while(lambda r: not r.get('completed')), map(lambda r: r.get('value')), finally_action(set_output_finalized))
def test_concat_forward_none_scheduler(self): subscribe_schedulers = {'e1': 'unknown', 'e2': 'unknown'} def subscribe_e1(observer, scheduler='not_set'): subscribe_schedulers['e1'] = scheduler observer.on_completed() def subscribe_e2(observer, scheduler='not_set'): subscribe_schedulers['e2'] = scheduler observer.on_completed() e1 = rx.create(subscribe_e1) e2 = rx.create(subscribe_e2) stream = e1.pipe(ops.concat(e2)) stream.subscribe() assert subscribe_schedulers['e1'] is None assert subscribe_schedulers['e2'] is None
def test_concat_forward_scheduler(self): scheduler = TestScheduler() subscribe_schedulers = {'e1': 'unknown', 'e2': 'unknown'} def subscribe_e1(observer, scheduler='not_set'): subscribe_schedulers['e1'] = scheduler observer.on_completed() def subscribe_e2(observer, scheduler='not_set'): subscribe_schedulers['e2'] = scheduler observer.on_completed() e1 = rx.create(subscribe_e1) e2 = rx.create(subscribe_e2) stream = e1.pipe(ops.concat(e2)) stream.subscribe(scheduler=scheduler) scheduler.advance_to(1000) assert subscribe_schedulers['e1'] is scheduler assert subscribe_schedulers['e2'] is scheduler
def create(): return e1.pipe(ops.concat(e2))
def create(): return e2.pipe(ops.concat(e1))
def do_while(source: Observable) -> Observable: return source.pipe(ops.concat(source.pipe(ops.while_do(condition))))
def enqueue(self, observable: Observable, group: str = 'default-group', retries: int = 0, description: str = None): description = description or str(Observable) key = '{}({})'.format(description, random.random()) def log_status(status): logging.debug( str({ 'WorkQueue': str(self), 'group': group, 'key': key, status: description })) log_status('ENQUEUED') error: Optional[Exception] = None def handle_error(e): log_status('FAILED') nonlocal error error = e return of({'key': key, 'error': e}) def throw_if_error(r): if error: return throw(error) else: return of(r) request_disposed = Subject() def dispose_request(): request_disposed.on_next(True) request = of(True).pipe( do_action(lambda _: log_status('STARTED')), flat_map( lambda _: observable.pipe( map(lambda value: { 'key': key, 'value': value }), retry_with_backoff(retries=retries, description= '{}.enqueue(group={}, description={})'. format(self, group, description)), catch(handler=lambda e, o: handle_error(e)), take_until(request_disposed), take_until_disposed(), ), ), concat( of({ 'key': key, 'complete': True }).pipe(do_action(lambda _: log_status('COMPLETED')))), ) result_stream = self._output.pipe( observe_on(self.request_scheduler), filter(lambda r: r['key'] == key), flat_map(lambda r: throw_if_error(r)), take_while(lambda r: not r.get('complete')), flat_map(lambda r: of(r.get('value'))), finally_action(dispose_request)) self._requests.on_next({ 'request': request, 'concurrency_group': group }) return result_stream
def mapper(ys, i): def proj(y): return "%s %s" % (i, y) return ys.pipe(ops.map(proj), ops.concat(rx.return_value('%s end' % i)))
rx.never() # 완료 상태에 도달할 수 없는 observable 을 생성한다. rx.throw() rx.interval() rx.from_() rx.interval() rx.just() rx.range() rx.repeat_value() rx.start() rx.timer() """Mathematical""" op.average() op.concat() op.count() op.max() op.min() op.reduce() op.sum() """Transformation""" op.buffer() op.group_by() op.map() op.scan() # ... """Filtering""" op.debounce()
import rx import rx.operators as ops numbers1 = rx.from_([1, 2, 3, 4]) numbers2 = rx.from_([11, 12]) numbers1.pipe(ops.concat(numbers2)).subscribe( on_next=lambda i: print("on_next {}".format(i)), on_error=lambda e: print("on_error: {}".format(e)), on_completed=lambda: print("on_completed"))
def enqueue(self, observable: Observable, group: str = None, retries: int = 0, description: str = None): # Provide a function returning a callable? description = description or str(Observable) key = '{}({})'.format(description, random.random()) def log_status(status): logging.debug( str({ 'WorkQueue': str(self), 'group': group, 'key': key, status: description })) log_status('ENQUEUED') error: Optional[Exception] = None def handle_error(e): log_status('FAILED') nonlocal error error = e return of({'key': key, 'error': e}) def throw_if_error(request): if error: return throw(error) else: return of(request) def extract_value(value): if type(value) == Observable: return value else: return of(value) request = of(True).pipe( do_action(lambda _: log_status('STARTED')), flat_map(lambda _: observable.pipe( flat_map(extract_value), map(lambda value: { 'key': key, 'value': value }), retry_with_backoff( retries=retries, description='{}.enqueue(group={}, description={})'.format( self, group, description)), catch(handler=lambda e, o: handle_error(e)), )), concat( of({ 'key': key, 'complete': True }).pipe(do_action(lambda _: log_status('COMPLETED'))))) result_stream = self._output.pipe( filter(lambda request: request['key'] == key), flat_map(lambda request: throw_if_error(request)), take_while(lambda request: not request.get('complete')), flat_map(lambda request: of(request.get('value')))) self._requests.on_next({ 'request': request, 'concurrency_group': group }) return result_stream
"""this operator will take in two or more observables and give a single observable with all the values in the sequence. :parameter Observables: list of observables to be concatenated. :return An observable is returned with a single value merged from the values of the source observable. """ my_ob_1 = of(2, 4, 6, 8, 10, 12) my_ob_2 = of(3, 6, 9, 12, 15) my_ob_3 = of("my", "body", "is") my_ob_1.pipe(op.concat(my_ob_2), op.concat(my_ob_3)).subscribe( lambda x: print("final value is {}".format(x))) # result # final value is 2 # final value is 4 # final value is 6 # final value is 8 # final value is 10 # final value is 12 # final value is 3 # final value is 6 # final value is 9 # final value is 12 # final value is 15 # final value is my