Esempio n. 1
0
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
Esempio n. 2
0
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()
Esempio n. 3
0
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()
Esempio n. 4
0
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
Esempio n. 5
0
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,
        )