def push_on_next(self, elem, last_to_push: int = None): if self.upstream_is_complete or self.downstream_is_complete: return Stop() else: if last_to_push is None: with self.lock: to_push = self.items_to_push self.items_to_push += 1 else: to_push = last_to_push if self.back_pressured is None: if to_push < self.buffer_size: self.queue.put(item=elem) self.push_to_consumer(to_push) return continue_ack else: ack = Ack() with self.lock: self.back_pressured = ack self.queue.put(item=elem) self.push_to_consumer(to_push) return ack else: self.queue.put(item=elem) self.push_to_consumer(to_push) return self.back_pressured
def on_next(self, elem): if not self.is_connected: def __(v, _): if isinstance(v, Continue): ack = self.underlying.on_next(elem) if isinstance(ack, Continue): return rx.Observable.just(ack) elif isinstance(ack, Stop): raise NotImplementedError else: return ack else: return Stop() new_ack = Ack() self.connected_ack \ .observe_on(self.scheduler) \ .flat_map(__) \ .subscribe(new_ack) self.connected_ack = new_ack return self.connected_ack elif not self.was_canceled: ack = self.underlying.on_next(elem) return ack else: return Stop()
def __(v, _): if isinstance(v, Continue): ack = self.underlying.on_next(elem) if isinstance(ack, Continue): return rx.Observable.just(ack) elif isinstance(ack, Stop): raise NotImplementedError else: return ack else: return Stop()
def signal_child_on_complete(self, ack: Ack, is_stop: bool): with source.lock: current_state = state[0] state[0] = WaitOnNextChild(ack) if isinstance(current_state, WaitOnNextChild) or isinstance(current_state, Active): ack.subscribe(self.async_upstream_ack) elif isinstance(current_state, Cancelled): ack.on_next(Stop()) ack.on_completed() elif isinstance(current_state, WaitComplete): state_: WaitComplete = current_state if not is_stop: if state_.ex is None: self.send_on_complete() else: observer.on_error(state_.ex) else: scheduler.report_failure(state_.ex)
def on_stop_or_failure_ref(self, err=None): if err: scheduler.report_failure(err) self.signal_child_on_complete(Stop(), is_stop=True)
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
def on_next_right(right_val): right_elem[0] = right_val right_ack[0] = Ack() with lock: has_right_elem[0] = True if has_left_elem[0]: has_left = True else: has_left = False if has_left: left_val = left_elem[0] # print('left={}, right={}'.format(left_val, right_val)) if is_higher(left_val, right_val): # right is higher than left # complete inner observable, discard left and request new left; save right with lock: # avoids completing observer twice # discard left element has_left_elem[0] = False left_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() # complete inner observable publish_subject[0].on_completed() left_ack[0].on_next(continue_ack) left_ack[0].on_completed() return right_ack[0] if is_lower(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 ack = right_observer[0].on_next((False, right_val)) # discard right element has_right_elem[0] = False right_elem[0] = None return ack else: # left is equal to right, send right element, request new right # discard right element has_right_elem[0] = False right_elem[0] = None # send right element ack = publish_subject[0].on_next(right_val) ack2 = right_observer[0].on_next((True, right_val)) return ack.merge_ack(ack2) else: # no left element has been yet received; only possible in initial phase return right_ack[0]
def on_next_left(left): # left has been requested because of initial state, # or because right is higher than left left_elem[0] = left left_ack[0] = Ack() 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 = right_elem[0] if left_is_lower(left, right): # right is higher than left # request new left; don't discard right element # discard left element has_left_elem[0] = False left_elem[0] = None return continue_ack if left_is_higher(left, right): # 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.on_completed() observer.on_completed() return Stop() right_ack[0].on_next(continue_ack) right_ack[0].on_completed() 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.on_completed() observer.on_completed() return Stop() # send right element ack = observer.on_next(self.selector(left, right)) # request new right element ack.connect_ack(right_ack[0]) # # request new left element # return ack return left_ack[0]
def on_next_right(right): right_elem[0] = right right_ack[0] = Ack() with lock: has_right_elem[0] = True if has_left_elem[0]: has_left = True else: has_left = False if has_left: left = left_elem[0] if right_is_higher(left, right): # right is higher than left # complete inner observable, discard left and request new left; save right with lock: # avoids completing observer twice # discard left element has_left_elem[0] = False left_elem[0] = None if has_completed[0]: complete_observer = True else: complete_observer = False if complete_observer: observer.on_completed() return Stop() left_ack[0].on_next(continue_ack) left_ack[0].on_completed() return right_ack[0] if right_is_lower(left, right): # 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 # discard right element has_right_elem[0] = False right_elem[0] = None return continue_ack else: # left is equal to right, send right element, request new right # discard right element has_right_elem[0] = False right_elem[0] = None # send right element ack = observer.on_next(self.selector(left, right)) return ack else: # no left element has been yet received; only possible in initial phase return right_ack[0]