class LibraryFileWatcher(object): def __init__(self, main_path, callback): super(LibraryFileWatcher, self).__init__() self.main_path = os.path.normpath(main_path) self.callback = callback # Perform a preliminary loading to find all of the connected files... # TODO: modularity with open(os.path.abspath(self.main_path), 'r') as FID: loader = config.Loader(FID) try: tmpLib = loader.get_single_data() self.filenames = [os.path.normpath(lf) for lf in loader.filenames] finally: loader.dispose() self.eventHandler = MyEventHandler(self.filenames, self.callback) self.observer = Observer() self.observer.schedule(self.eventHandler, path=os.path.dirname(os.path.abspath(main_path))) self.observer.start() self.resume() def __del__(self): self.observer.stop() self.observer.join() def pause(self): self.eventHandler.paused = True def resume(self): self.eventHandler.paused = False
def start_file_monitor(path, callback): if os.path.exists(path): handler = FileHandler(callback) observer = Observer() observer.schedule(handler, path, recursive=True) observer.start() observers.add(observer) return observer
def watch(path, out, other_args): event_handler = KhepriMatchingEventHandler(path, out, other_args) observer = Observer() observer.schedule(event_handler, path, recursive=True) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
def start_watchdog(event_handler): observer = Observer() observer.schedule(event_handler, event_handler.src_path, recursive=True) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() except Exception: raise observer.join()
class LibraryFileWatcher(object): def __init__(self, filePath, callback): super(LibraryFileWatcher, self).__init__() self.filePath = os.path.normpath(filePath) self.callback = callback self.eventHandler = MyEventHandler(self.filePath, callback) self.observer = Observer() self.watch = self.observer.schedule(self.eventHandler, path=os.path.dirname(os.path.abspath(self.filePath))) self.observer.start() self.resume() def __del__(self): self.observer.stop() self.observer.join() def pause(self): self.eventHandler.paused = True def resume(self): self.eventHandler.paused = False
class StubConnection(Connection): r"""A stub connection. This connection uses two files to communicate: one for the incoming messages and the other for the outgoing messages. Each line contains an encoded envelope. The format of each line is the following: TO,SENDER,PROTOCOL_ID,ENCODED_MESSAGE e.g.: recipient_agent,sender_agent,default,{"type": "bytes", "content": "aGVsbG8="} The connection detects new messages by watchdogging the input file looking for new lines. To post a message on the input file, you can use e.g. echo "..." >> input_file or: #>>> fp = open(DEFAULT_INPUT_FILE_NAME, "ab+") #>>> fp.write(b"...\n") It is discouraged adding a message with a text editor since the outcome depends on the actual text editor used. """ def __init__( self, input_file_path: Union[str, Path], output_file_path: Union[str, Path], **kwargs ): """ Initialize a stub connection. :param input_file_path: the input file for the incoming messages. :param output_file_path: the output file for the outgoing messages. """ if kwargs.get("configuration") is None and kwargs.get("connection_id") is None: kwargs["connection_id"] = PUBLIC_ID super().__init__(**kwargs) input_file_path = Path(input_file_path) output_file_path = Path(output_file_path) if not input_file_path.exists(): input_file_path.touch() self.input_file = open(input_file_path, "rb+") self.output_file = open(output_file_path, "wb+") self.in_queue = None # type: Optional[asyncio.Queue] self._observer = Observer() directory = os.path.dirname(input_file_path.absolute()) self._event_handler = _ConnectionFileSystemEventHandler(self, input_file_path) self._observer.schedule(self._event_handler, directory) def read_envelopes(self) -> None: """Receive new envelopes, if any.""" envelopes = read_envelopes(self.input_file) self._put_envelopes(envelopes) def _put_envelopes(self, envelopes: List[Envelope]) -> None: """ Put the envelopes in the inqueue. :param envelopes: the list of envelopes """ assert self.in_queue is not None, "Input queue not initialized." assert self._loop is not None, "Loop not initialized." for envelope in envelopes: asyncio.run_coroutine_threadsafe(self.in_queue.put(envelope), self._loop) async def receive(self, *args, **kwargs) -> Optional["Envelope"]: """Receive an envelope.""" try: assert self.in_queue is not None, "Input queue not initialized." envelope = await self.in_queue.get() return envelope except Exception as e: logger.exception(e) return None async def connect(self) -> None: """Set up the connection.""" if self.connection_status.is_connected: return try: # initialize the queue here because the queue # must be initialized with the right event loop # which is known only at connection time. self.in_queue = asyncio.Queue() self._observer.start() except Exception as e: # pragma: no cover self._observer.stop() self._observer.join() raise e finally: self.connection_status.is_connected = False self.connection_status.is_connected = True # do a first processing of messages. # self.read_envelopes() async def disconnect(self) -> None: """ Disconnect from the channel. In this type of connection there's no channel to disconnect. """ if not self.connection_status.is_connected: return assert self.in_queue is not None, "Input queue not initialized." self._observer.stop() self._observer.join() self.in_queue.put_nowait(None) self.connection_status.is_connected = False async def send(self, envelope: Envelope): """ Send messages. :return: None """ write_envelope(envelope, self.output_file) @classmethod def from_config( cls, address: Address, configuration: ConnectionConfig ) -> "Connection": """ Get the stub connection from the connection configuration. :param address: the address of the agent. :param configuration: the connection configuration object. :return: the connection object """ input_file = configuration.config.get( INPUT_FILE_KEY, DEFAULT_INPUT_FILE_NAME ) # type: str output_file = configuration.config.get( OUTPUT_FILE_KEY, DEFAULT_OUTPUT_FILE_NAME ) # type: str return StubConnection( input_file, output_file, address=address, configuration=configuration, )