def onNext(self, value): s = Subject() resourceId = 0 with self.parent.gate: self.parent.leftID += 1 resourceId = self.parent.leftID self.parent.leftMap[resourceId] = s # AddRef was originally WindowObservable but this is just an alias for AddRef window = AddRef(s, self.parent.refCount) md = SingleAssignmentDisposable() self.parent.group.add(md) try: duration = self.parent.parent.leftDurationSelector(value) except Exception as e: self.onError(e) return else: md.disposable = duration.subscribeSafe(self.Delta(self, resourceId, s, md)) try: result = self.parent.parent.resultSelector(value, window) except Exception as e: self.onError(e) return else: with self.parent.gate: self.parent.observer.onNext(result) for rightValue in self.parent.rightMap.values(): s.onNext(rightValue)
def onNext(self, value): key = None try: key = self.parent.keySelector(value) except Exception as e: self.onError(e) return fireNewMapEntry = False writer = None try: if key == None: with self.nullGate: if self.null == None: self.null = Subject() fireNewMapEntry = True writer = self.null else: if key in self.map: writer = self.map[key] else: writer = Subject() self.map[key] = writer fireNewMapEntry = True except Exception as e: self.onError(e) return if fireNewMapEntry: group = GroupObservable(key, writer, self.parent.refCountDisposable) duration = None durationGroup = GroupObservable(key, writer) try: duration = self.parent.durationSelector(durationGroup) except Exception as e: self.onError(e) return with self.observerGate: self.observer.onNext(group) md = SingleAssignmentDisposable() self.parent.groupDisposable.add(md) md.disposable = duration.subscribeSafe(self.Delta(self, key, writer, md)) element = None try: element = self.parent.elementSelector(value) except Exception as e: self.onError(e) else: with self.writerGate: writer.onNext(element)
class PassReader: """Read a pass db and construct an in-memory version of it.""" entries: List[PassEntryCls] store: Store def __init__(self, path: str = None, password: str = None): """Constructor for PassReader :param path: optional password-store location. Default is '~/.password-store'. """ if path is None: self.path = os.path.expanduser("~/.password-store") else: self.path = os.path.abspath(os.path.expanduser(path)) self.store = Store(store_dir=self.path) self.entries = [] self.password = password self.event_stream = Subject() def get_pass_entries(self) -> List[str]: """Returns all store entries.""" return self._get_entries_at_path() def _get_entries_at_path(self, path: str = "/") -> List[str]: """Recursive scan of a store path. :param path: the path to scan, default at root :return: a list of entries name """ folders, entries = self.store.list_dir(self.path + path) if len(folders) > 0: for folder in folders: for entry in self._get_entries_at_path("/{}".format(folder)): entries.append(entry) return entries def parse_pass_entry(self, entry: str) -> PassEntryCls: """Return a parsed PassEntry.""" return PassEntry(reader=self, entry=entry) def parse_db(self): """Populate the entries list with all the data from the pass db.""" i = 0 for entry in self.get_pass_entries(): self.entries.append(self.parse_pass_entry(entry)) i = i + 1 self.event_stream.on_next(i)
class PlotSaveHandler(rx.core.Observer): def __init__(self, cfg: CfgNode, cfg_dir="."): super(PlotSaveHandler, self).__init__() self.base_path = utils.abs_or_offset_from(cfg.output.base_path, cfg_dir) os.makedirs(self.base_path, exist_ok=True) os.makedirs(os.path.join(self.base_path, "weights"), exist_ok=True) self.e = [] self.train_loss = [] self.val_loss = [] self.plot_sub = Subject() def on_next(self, value) -> None: e = value["epoch"] train_time = value["train_time"] val_time = value["valid_time"] train_loss = value["train_loss"] val_loss = value["valid_loss"] net: RamanAINetwork = value["net"] print(f"Epoch:{e}, train_loss={train_loss}, val_loss={val_loss}, train_time={train_time}, val_time={val_time}") self.e.append(e) self.train_loss.append(train_loss) self.val_loss.append(val_loss) # save torch.save(net, os.path.join(self.base_path, "weights", f"weights_{e}.pkl")) self.plot_sub.on_next({ "epoch": self.e, "train": self.train_loss, "valid": self.val_loss, "test_output": value["test_output"], }) def on_error(self, error: Exception) -> None: raise error def on_completed(self) -> None: print("Completed") with open(os.path.join(self.base_path, f"loss.csv"), "w", newline='') as f: writer = csv.writer(f) writer.writerow(["Epoch", "Train", "Valid"]) for e, t, v, in zip(self.e, self.train_loss, self.val_loss): writer.writerow([e, t, v]) self.plot_sub.on_completed()
class AttendancenStateContext: def __init__(self, userid: str, is_attending: bool, attend_notifier: Observable, absence_due_second: int = 3): self.userid = userid self.is_attending = is_attending self.schedule_obj = None if is_attending: self.detect_attendance(userid) self.absence_due_second = absence_due_second self.subject = Subject() attend_notifier.subscribe(self.detect_attendance) def __del__(self): self.clear_scheduler_if_running() def clear_scheduler_if_running(self): if self.schedule_obj is not None and not self.schedule_obj.is_disposed: self.schedule_obj.dispose() def update_scheduler(self): self.clear_scheduler_if_running() self.schedule_obj = NewThreadScheduler().schedule_relative( self.absence_due_second, self.detect_absence) def detect_attendance(self, userid: str): assert self.userid == userid self.update_scheduler() if not self.is_attending: self.subject.on_next({ "type": AttendanceType.Attend, "userid": userid }) self.is_attending = True def detect_absence(self, _, __): self.is_attending = False self.subject.on_next({ "type": AttendanceType.Leave, "userid": self.userid, "absence_due_second": self.absence_due_second }) def get_observable(self): return self.subject
def __init__(self, properties_str: str, inference: Callable[[str, object], Tuple[str, object]], tag_groups: List[str], thing_cls: List[str]): super().__init__(properties_str=properties_str, tag_groups=tag_groups, thing_cls=thing_cls) self.__frame_data_class = class_from_thing_input( self.dr, self.thing, 'VideoFrameData') self.__frame_subject = Subject() self.__listener = FrameListener(self.__frame_subject, self.__frame_data_class) self.__inference_fn = inference self.__frame_subject.pipe( ops.map(lambda s: self.__inference_fn(s[0], s[1]))).subscribe( self._write_inference)
def open(self): print("WebSocket opened") self.write_message("connection opened") def _send_response(x): print(x) self.write_message(json.dumps(x)) def _on_error(ex): print(ex) self.subject = Subject() self.subject.pipe(buffer(rx.interval(5.0)), last(), flat_map(self.get_data)).subscribe( on_next=_send_response, on_error=_on_error)
def __init__(self, pin_dt, pin_clk, key_left=None, key_right=None): self.pin_clk = pin_clk self.pin_dt = pin_dt self.key_left = key_left self.key_right = key_right self.left = Subject() self.right = Subject() self.pending = None if wiringpi: wiringpi.pinMode(pin_clk, 0) wiringpi.pullUpDnControl(pin_clk, 2) wiringpi.pinMode(pin_dt, 0) wiringpi.pullUpDnControl(pin_dt, 2) self.clk_last = 1 - wiringpi.digitalRead(self.pin_clk)
def schedule_emit_next_until(until: subject.Subject): stop_emitting = False def _action(sch: rx.typing.Scheduler, state=None): emit_next() def until_on_next(v): nonlocal stop_emitting stop_emitting = True until.pipe(operators.take_until(_stop)).subscribe(until_on_next, scheduler=sch) if not stop_emitting: sch.schedule(_action)
def __init__(self, current_player_game, login): ModelItem.__init__(self) self._current_player_game = current_player_game self.login = login self._add_obs("id", 0) self._add_obs("global_rating", (1500, 500)) self._add_obs("ladder_rating", (1500, 500)) self._add_obs("number_of_games", 0) self._add_obs("avatar") self._add_obs("country") self._add_obs("clan") self._add_obs("league") self.obs_game = Subject()
def __init__(self, page): super().__init__(page) self._freq = 88 self.clock = 0 self.subject = Subject() self.output = Output(self, 'output', self.subject) self.add_pin(self.output)
def test_multicast_hot_6(self): c = [None] d1 = [None] d2 = [None] ex = 'ex' scheduler = TestScheduler() xs = scheduler.create_hot_observable(on_next(40, 0), on_next(90, 1), on_next(150, 2), on_next(210, 3), on_next(240, 4), on_next(270, 5), on_next(330, 6), on_next(340, 7), on_completed(390)) s = Subject() o = scheduler.create_observer() def action0(scheduler, state): c[0] = xs.pipe(ops.multicast(s)) scheduler.schedule_absolute(50, action0) def action1(scheduler, state): d2[0] = c[0].connect(scheduler) scheduler.schedule_absolute(100, action1) def action2(scheduler, state): d1[0] = c[0].subscribe(o, scheduler) scheduler.schedule_absolute(400, action2) scheduler.start() assert o.messages == [on_completed(400)] assert xs.subscriptions == [subscribe(100, 390)]
def main(): root = Tk() root.title("Rx for Python rocks") scheduler = TkinterScheduler(root) mousemove = Subject() frame = Frame(root, width=600, height=600) frame.bind("<Motion>", mousemove.on_next) text = 'TIME FLIES LIKE AN ARROW' def on_next(info): label, ev, i = info label.place(x=ev.x + i * 12 + 15, y=ev.y) def handle_label(label, i): label.config(dict(borderwidth=0, padx=0, pady=0)) mapper = ops.map(lambda ev: (label, ev, i)) delayer = ops.delay(i * 0.1) return mousemove.pipe(delayer, mapper) labeler = ops.flat_map_indexed(handle_label) mapper = ops.map(lambda c: Label(frame, text=c)) rx.from_(text).pipe(mapper, labeler).subscribe(on_next, on_error=print, scheduler=scheduler) frame.pack() root.mainloop()
def test_set_io_ports(no_io): assert store.get('inports') is None assert store.get('outports') is None set_io_ports(Subject()) assert store.get('inports').ports == [] # Virtual port in outports assert len(store.get('outports').ports) == 1
def run(main_f, drivers): fake_sinks = {k: Subject() for k in drivers} sources = {k: drivers[k](fake_sinks[k]) for k in drivers} sinks = main_f(sources) for k in fake_sinks: if k in sinks: sinks[k].subscribe(fake_sinks[k], scheduler=AsyncIOScheduler(loop))
def __send_command_to(self, command_type: bytes, data: bytes, instance: InstanceReference, expect_reply: bool = False) -> Subject: # Returns when the command has been sent, or with the reply if expctant subject = Subject() # Handler for eventual opening of stream def on_connected(stream: EgressStream): # Do we expect a reply? if(expect_reply): # Subscribe to reply stream.reply.subscribe(subject.on_next) # Send command type and command stream.write(command_type + data) # Close the stream stream.close() # Do we expect a reply? if(not expect_reply): # No, let caller know we are done subject.on_completed() # Open stream with the peer self.__transport.initialise_stream(instance).subscribe(on_connected) # Return the subject return subject
def __send_command(self, command_type: bytes, data: bytes, expect_reply: bool = False, blacklist: Set[InstanceReference] = set()) -> Subject: # If we expect replies to this command, create a subject reply_subject = None if(expect_reply): reply_subject = Subject() count = 0 # Loop over each repeater for repeater in self.__repeaters: # Is this a blacklisted repeater? if(repeater in blacklist): # Yes, skip continue # Send command subject = self.__send_command_to(command_type, data, repeater, expect_reply) count += 1 # Do we expect a reply? if(expect_reply): # Yes, connect to subject subject.subscribe(reply_subject.on_next) Log.debug("Broadcasted a command to {} repeater/s".format(count)) # Return reply subject return reply_subject
def main(): key="z" subject_test = Subject() initKeyMonitoring(subject_test) subject_test.on_next(key) print("here") time.sleep(2) subject_test.on_next(key) print("here") time.sleep(2) subject_test.on_next(key) print("here") time.sleep(2) subject_test.on_completed()
def connect_socket(self, socket_type, options, address): self.log.info(f"connecting {socket_type} socket to {address} ...") socket = self.zmq_context.socket(socket_type) for k, v in options.items(): if type(v) == str: socket.setsockopt_string(k, v) else: socket.setsockopt(k, v) socket.connect(address) observable = Subject() socket_name = f"{socket_type}:{address}" send_queue = queue.Queue() self.zmq_sockets[socket_name] = pmap({ "socket": socket, "address": address, "type": socket_type, "options": options, "observable": observable, "send_queue": send_queue, "send": lambda x: send_queue.put(x), }) self.zmq_poller.register(socket, zmq.POLLIN) return self.zmq_sockets[socket_name]
def __init__(self, *args, **kwargs): self.base_url = "https://devrant.com/api" self.base_params = { 'app': 3, } self.rants = BehaviorSubject([]) self.error = Subject() self.me = BehaviorSubject(None) self.auth_token = BehaviorSubject(None) self.is_logged = BehaviorSubject(False) self._subscribe_to_auth_token() self._load_cache()
def _watch_ingestor_health(self): def to_ingestor_health(id_: str, has_heartbeat: bool): if has_heartbeat: return ttm.IngestorHealth( id_=id_, health_status=ttm.HealthStatus.HEALTHY) return ttm.IngestorHealth( id_=id_, health_status=ttm.HealthStatus.DEAD, health_message="heartbeat failed", ) def watch(id_: str, obs: Observable): ingestor_mode_health = obs.pipe( ops.map(lambda x: self._ingestor_mode_to_health(id_, x))) obs.pipe( heartbeat(self.LIVELINESS), ops.map(lambda x: to_ingestor_health(id_, x)), self._combine_most_critical(ingestor_mode_health), ).subscribe(self.rmf.ingestor_health.on_next, scheduler=self.scheduler) subjects = { x.guid: Subject() for x in self.rmf.current_ingestor_states.values() } for guid, subject in subjects.items(): watch(guid, subject) def on_state(state: IngestorState): if state.guid not in subjects: subjects[state.guid] = Subject() watch(state.guid, subjects[state.guid]) subjects[state.guid].on_next(state) self.rmf.ingestor_states.subscribe(on_state)
def on_next(i): nonlocal current_predicate nonlocal split_observable new_predicate = predicate(i) if current_predicate is None: current_predicate = new_predicate observer.on_next(split_observable) if new_predicate != current_predicate: current_predicate = new_predicate split_observable.on_completed() split_observable = Subject() observer.on_next(split_observable) split_observable.on_next(i)
def __init__(self, sport_center_business_hours, fetch_period_seces=5, write_to_storage_period_secs=60, error_delay_secs=3): self.io_loop = None self.data_fetcher = DataFetcher() sqlite_file_path = pathlib.Path(__file__).parent / 'data.sqlite' print('database path', sqlite_file_path) self.sql_connection = sqlite3.connect(str(sqlite_file_path)) self.fetch_period_secs = fetch_period_seces self.error_delay_secs = error_delay_secs self.write_to_storage_period_secs = timedelta(seconds=write_to_storage_period_secs) self.business_hours = sport_center_business_hours self.last_write_to_database_time = datetime.now() self.data_cache = None self.live_subject = Subject()
def test_set_level(self, mock_get_logger, mock_stream_handler): logger = MagicMock(spec=std_logging.Logger) stream_handler = MagicMock(spec=std_logging.Handler) mock_get_logger.return_value = logger mock_stream_handler.return_value = stream_handler driver = logging.make_driver() request = Subject() sink = logging.Sink(request=request) driver.call(sink) request.on_next(logging.SetLevel(logger='foo', level='DEBUG')) mock_get_logger.assert_called_with('foo') logger.setLevel.assert_called_with(std_logging.DEBUG) mock_stream_handler.assert_called_with() stream_handler.setLevel.assert_called_with(std_logging.DEBUG)
def publish(self, initialValue=None): assert isinstance(self, Observable) if initialValue == None: return self.multicast(Subject()) else: return self.multicast(BehaviorSubject(initialValue))
class Audio: device: int = 1 window: int = 1 subject_: Subject = Subject() def start_stream(self): run = True def stop_running(*args): run = False self.subject_.subscribe(on_error=stop_running, on_completed=stop_running) samplerate = sd.query_devices(self.device, 'input')['default_samplerate'] def callback(indata, frames, time, status): self.subject_.on_next(int(np.linalg.norm(indata)*10)) with sd.InputStream(device=self.device, channels=1, callback=callback, finished_callback=lambda: self.subject_.on_completed(), samplerate=samplerate): while run: sd.sleep(1000) @property def stream(self): return self.subject_.pipe( ops.window_with_time(self.window), ops.map(lambda x: x.pipe(ops.average(), ops.first())), ops.merge_all() )
def test_create_driver(self): driver = logging.make_driver() request = Subject() sink = logging.Sink(request=request) source = driver.call(sink) self.assertIsNone(source)
def subscribe(observer, scheduler_=None): _scheduler = scheduler or scheduler_ or TimeoutScheduler.singleton() n = [0] s = [None] timer_d = SerialDisposable() window_id = [0] group_disposable = CompositeDisposable(timer_d) ref_count_disposable = RefCountDisposable(group_disposable) def create_timer(_id): m = SingleAssignmentDisposable() timer_d.disposable = m def action(scheduler, state): if _id != window_id[0]: return n[0] = 0 window_id[0] += 1 new_id = window_id[0] s[0].on_completed() s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) create_timer(new_id) m.disposable = _scheduler.schedule_relative(timespan, action) s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) create_timer(0) def on_next(x): new_window = False new_id = 0 s[0].on_next(x) n[0] += 1 if n[0] == count: new_window = True n[0] = 0 window_id[0] += 1 new_id = window_id[0] s[0].on_completed() s[0] = Subject() observer.on_next(add_ref(s[0], ref_count_disposable)) if new_window: create_timer(new_id) def on_error(e): s[0].on_error(e) observer.on_error(e) def on_completed(): s[0].on_completed() observer.on_completed() group_disposable.add(source.subscribe_(on_next, on_error, on_completed, scheduler_)) return ref_count_disposable
class SaveImageSink(BaseSink): def __init__(self, name="save_image"): super().__init__(name, self.on_image) self.dir_path = os.path.join(self.config["data"]["base"], self.config["data"]["image"]) os.makedirs(self.dir_path, exist_ok=True) self.file_saved_subject = Subject() def on_image(self, x): assert isinstance(x, Image) path = os.path.join(self.dir_path, f"{x.time}.jpg") with open(path, "wb") as f: f.write(x.jpeg) self.file_saved_subject.on_next(path) self.logger.debug("Saving file:" + path)
def subscribe(observer, scheduler=None): window_subject = Subject() d = CompositeDisposable() r = RefCountDisposable(d) observer.on_next(add_ref(window_subject, r)) def on_next_window(x): window_subject.on_next(x) def on_error(err): window_subject.on_error(err) observer.on_error(err) def on_completed(): window_subject.on_completed() observer.on_completed() d.add( source.subscribe_(on_next_window, on_error, on_completed, scheduler)) def on_next_observer(w): nonlocal window_subject window_subject.on_completed() window_subject = Subject() observer.on_next(add_ref(window_subject, r)) d.add( boundaries.subscribe_(on_next_observer, on_error, on_completed, scheduler)) return r
def group_by_mux(key_mapper): outer_observer = Subject() def _group_by(source): def on_subscribe(observer, scheduler): state = None def on_next(i): nonlocal state if type(i) is rs.OnNextMux: key = i.key map_key = key_mapper(i.item) index = i.store.get_map(state, key, map_key) if index is rs.state.markers.STATE_NOTSET: index = i.store.add_map(state, key, map_key) observer.on_next( rs.OnCreateMux((index, i.key), store=i.store)) observer.on_next(i._replace(key=(index, i.key))) elif type(i) is rs.OnCreateMux: i.store.add_key(state, i.key) outer_observer.on_next(i) elif type(i) is rs.OnCompletedMux: for k in i.store.iterate_map(state, i.key): index = i.store.get_map(state, i.key, k) observer.on_next(i._replace(key=(index, i.key))) i.store.del_key(state, i.key) outer_observer.on_next(i) elif type(i) is rs.OnErrorMux: for k in i.store.iterate_map(state, i.key): index = i.store.get_map(state, i.key, k) observer.on_next(i._replace(key=(index, i.key))) i.store.del_map(state, i.key, k) i.store.del_key(state, i.key) outer_observer.on_next(i) elif type(i) is rs.state.ProbeStateTopology: state = i.topology.create_mapper(name="groupby") observer.on_next(i) outer_observer.on_next(i) else: if state is None: observer.on_error( ValueError( "No state configured in group_by operator. A state store operator is probably missing in the graph" )) observer.on_next(i) return source.subscribe(on_next=on_next, on_completed=observer.on_completed, on_error=observer.on_error, scheduler=scheduler) return rs.MuxObservable(on_subscribe) return _group_by, outer_observer
def client(sources): http_request = Subject() def request(method, url, **kwargs): def on_subscribe(observer, scheduler): response = sources.http_response.pipe( ops.filter(lambda i: i.id is response_observable), ops.take(1), ops.flat_map(lambda i: i.response), ) dispose = response.subscribe(observer) http_request.on_next( Request(id=response_observable, url=url, method=method, **kwargs)) return dispose response_observable = rx.create(on_subscribe) return response_observable return Client(sink=ClientSink(http_request=http_request, ), api=Api(request=request, ))
class SinkWithTimeSpan(rx.linq.sink.Sink): def __init__(self, parent, observer, cancel): super(Window.SinkWithTimeSpan, self).__init__(observer, cancel) self.parent = parent def run(self): self.gate = RLock() groupDisposable = CompositeDisposable() self.refCountDisposable = RefCountDisposable(groupDisposable) self.createWindow() groupDisposable.add(self.parent.scheduler.schedulePeriodic(self.parent.timeSpan, self.tick)) groupDisposable.add(self.parent.source.subscribeSafe(self)) return self.refCountDisposable def tick(self): with self.gate: self.subject.onCompleted() self.createWindow() def createWindow(self): self.subject = Subject() self.observer.onNext(AddRef(self.subject, self.refCountDisposable)) def onNext(self, value): with self.gate: self.list.append(value) def onError(self, exception): with self.gate: self.subject.onError(exception) self.observer.onError(exception) self.dispose() def onCompleted(self): with self.gate: self.subject.onCompleted() self.observer.onCompleted() self.dispose()
def onNext(self, value): key = None try: key = self.parent.keySelector(value) except Exception as e: self.onError(e) return fireNewMapEntry = False writer = None try: if key == None: if self.null == None: self.null = Subject() fireNewMapEntry = True writer = self.null else: if key in self.map: writer = self.map[key] else: writer = Subject() self.map[key] = writer fireNewMapEntry = True except Exception as e: self.onError(e) return if fireNewMapEntry: group = GroupObservable(key, writer, self.parent.refCountDisposable) self.observer.onNext(group) element = None try: element = self.parent.elementSelector(value) except Exception as e: self.onError(e) else: writer.onNext(element)
def run(self): self.gate = RLock() self.s = Subject() self.n = 0 self.windowId = 0 self.timerDisposable = SerialDisposable() groupDisposable = CompositeDisposable(self.timerDisposable) self.refCountDisposable = RefCountDisposable(groupDisposable) # AddRef was originally WindowObservable but this is just an alias for AddRef self.observer.onNext(AddRef(self.s, self.refCountDisposable)) self.createTimer(0) groupDisposable.add(self.parent.source.subscribeSafe(self)) return self.refCountDisposable
def onNext(self, value): newWindow = False newId = 0 with self.gate: self.s.onNext(value) self.n += 1 if self.n == self.parent.count: newWindow = True self.n = 0 self.windowId += 1 newId = self.windowId self.s.onCompleted() self.s = Subject() self.observer.onNext(AddRef(self.s, self.refCountDisposable)) if newWindow: self.createTimer(newId)
def tick(self, scheduler, wId): d = Disposable.empty() newId = 0 with self.gate: if wId != self.windowId: return d self.n = 0 self.windowId += 1 newId = self.windowId self.s.onCompleted() self.s = Subject() self.observer.onNext(AddRef(self.s, self.refCountDisposable)) self.createTimer(newId) return d
class Session(object): def __init__(self, parent): self.parent = parent self.removeHandler = None self.subject = Subject() self.count = 0 def connect(self, observer): # # We connect the given observer to the subject first, before performing any kind # of initialization which will register an event handler. This is done to ensure # we don't have a time gap between adding the handler and connecting the user's # subject, e.g. when the ImmediateScheduler is used. # # [OK] Use of unsafe Subscribe: called on a known subject implementation. # connection = self.subject.subscribe(observer) self.count += 1 if self.count == 1: try: self.initialize() except Exception as e: self.count -= 1 connection.dispose() observer.onError(e) return Disposable.empty() def dispose(): connection.dispose() with self.parent.gate: self.count -=1 if self.count == 0: self.parent.scheduler.schedule(self.removeHandler.dispose) self.parent.session = None return Disposable.create(dispose) def initialize(self): # # When the ref count goes to zero, no-one should be able to perform operations on # the session object anymore, because it gets nulled out. # assert self.removeHandler == None self.removeHandler = SingleAssignmentDisposable() # # Conversion code is supposed to be a pure function and shouldn't be run on the # scheduler, but the add handler call should. Notice the scheduler can be the # ImmediateScheduler, causing synchronous invocation. This is the default when # no SynchronizationContext is found (see QueryLanguage.Events.cs and search for # the GetSchedulerForCurrentContext method). # onNext = self.parent.getHandler(self.subject.onNext) self.parent.scheduler.scheduleWithState(onNext, self.addHandler) def addHandler(self, scheduler, onNext): try: removeHandler = self.parent.addHandler(onNext) except Exception as e: self.subject.onError(e) else: self.removeHandler.disposable = removeHandler # # We don't propagate the exception to the OnError channel upon Dispose. This is # not possible at this stage, because we've already auto-detached in the base # class Producer implementation. Even if we would switch the OnError and auto- # detach calls, it wouldn't work because the remove handler logic is scheduled # on the given scheduler, causing asynchrony. We can't block waiting for the # remove handler to run on the scheduler. # return Disposable.empty()
class Sink(rx.linq.sink.Sink): def __init__(self, parent, observer, cancel): super(GroupBy.Sink, self).__init__(observer, cancel) self.parent = parent self.map = {} self.null = None def onNext(self, value): key = None try: key = self.parent.keySelector(value) except Exception as e: self.onError(e) return fireNewMapEntry = False writer = None try: if key == None: if self.null == None: self.null = Subject() fireNewMapEntry = True writer = self.null else: if key in self.map: writer = self.map[key] else: writer = Subject() self.map[key] = writer fireNewMapEntry = True except Exception as e: self.onError(e) return if fireNewMapEntry: group = GroupObservable(key, writer, self.parent.refCountDisposable) self.observer.onNext(group) element = None try: element = self.parent.elementSelector(value) except Exception as e: self.onError(e) else: writer.onNext(element) def onError(self, exception): if self.null != None: self.null.onError(exception) for x in self.map.values(): x.onError(exception) self.observer.onError(exception) self.dispose() def onCompleted(self): if self.null != None: self.null.onCompleted() for x in self.map.values(): x.onCompleted() self.observer.onCompleted() self.dispose()
class SinkWithCountAndTimeSpan(rx.linq.sink.Sink): def __init__(self, parent, observer, cancel): super(Window.SinkWithCountAndTimeSpan, self).__init__(observer, cancel) self.parent = parent def run(self): self.gate = RLock() self.s = Subject() self.n = 0 self.windowId = 0 self.timerDisposable = SerialDisposable() groupDisposable = CompositeDisposable(self.timerDisposable) self.refCountDisposable = RefCountDisposable(groupDisposable) # AddRef was originally WindowObservable but this is just an alias for AddRef self.observer.onNext(AddRef(self.s, self.refCountDisposable)) self.createTimer(0) groupDisposable.add(self.parent.source.subscribeSafe(self)) return self.refCountDisposable def createTimer(self, wId): m = SingleAssignmentDisposable() self.timerDisposable.disposable = m m.disposable = self.parent.scheduler.scheduleWithRelativeAndState( wId, self.parent.timeSpan, self.tick ) def tick(self, scheduler, wId): d = Disposable.empty() newId = 0 with self.gate: if wId != self.windowId: return d self.n = 0 self.windowId += 1 newId = self.windowId self.s.onCompleted() self.s = Subject() self.observer.onNext(AddRef(self.s, self.refCountDisposable)) self.createTimer(newId) return d def onNext(self, value): newWindow = False newId = 0 with self.gate: self.s.onNext(value) self.n += 1 if self.n == self.parent.count: newWindow = True self.n = 0 self.windowId += 1 newId = self.windowId self.s.onCompleted() self.s = Subject() self.observer.onNext(AddRef(self.s, self.refCountDisposable)) if newWindow: self.createTimer(newId) def onError(self, exception): with self.gate: self.s.onError(exception) self.observer.onError(exception) self.dispose() def onCompleted(self): with self.gate: self.s.onCompleted() self.observer.onCompleted() self.dispose()
def __init__(self, parent): self.parent = parent self.removeHandler = None self.subject = Subject() self.count = 0
def createWindow(self): self.subject = Subject() self.observer.onNext(AddRef(self.subject, self.refCountDisposable))