Пример #1
0
    def __init__(self,
                 public_key: str,
                 oef_addr: str,
                 oef_port: int = 10000,
                 connection_id: str = "oef",
                 restricted_to_protocols: Optional[Set[str]] = None):
        """
        Initialize.

        :param public_key: the public key of the agent.
        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        :param connection_id: the identifier of the connection object.
        :param restricted_to_protocols: the only supported protocols for this connection.
        """
        super().__init__(connection_id=connection_id,
                         restricted_to_protocols=restricted_to_protocols)
        self._core = AsyncioCore(logger=logger)  # type: AsyncioCore
        self.in_queue = None  # type: Optional[asyncio.Queue]
        self.channel = OEFChannel(public_key,
                                  oef_addr,
                                  oef_port,
                                  core=self._core)

        self._connection_check_thread = None  # type: Optional[Thread]
Пример #2
0
    def __init__(
        self,
        address: Address,
        oef_addr: str,
        oef_port: int,
        logger: Logger = _default_logger,
    ):
        """
        Initialize.

        :param address: the address of the agent.
        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        """
        super().__init__(
            address,
            oef_addr=oef_addr,
            oef_port=oef_port,
            core=AsyncioCore(logger=logger),
            logger=lambda *x: None,
            logger_debug=lambda *x: None,
        )
        self.address = address
        self._in_queue = None  # type: Optional[asyncio.Queue]
        self._loop = None  # type: Optional[AbstractEventLoop]

        self.oef_search_dialogues = OefSearchDialogues()
        self.oef_msg_id = 0
        self.oef_msg_id_to_dialogue = {}  # type: Dict[int, OefSearchDialogue]

        self._threaded_pool = ThreadPoolExecutor(self.THREAD_POOL_SIZE)

        self.aea_logger = logger
Пример #3
0
    def __init__(self, oef_addr: str, oef_port: int = 10000, **kwargs):
        """
        Initialize.

        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        :param kwargs: the keyword arguments (check the parent constructor)
        """
        if kwargs.get("configuration") is None and kwargs.get("connection_id") is None:
            kwargs["connection_id"] = PublicId("fetchai", "oef", "0.1.0")
        super().__init__(**kwargs)
        self.oef_addr = oef_addr
        self.oef_port = oef_port
        self._core = AsyncioCore(logger=logger)  # type: AsyncioCore
        self.in_queue = None  # type: Optional[asyncio.Queue]
        self.channel = OEFChannel(self.address, self.oef_addr, self.oef_port, core=self._core)  # type: ignore
        self._connection_check_task = None  # type: Optional[asyncio.Future]
Пример #4
0
    def __init__(
        self, address: Address, oef_addr: str, oef_port: int = 10000, *args, **kwargs
    ):
        """
        Initialize.

        :param address: the address of the agent.
        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        :param connection_id: the identifier of the connection object.
        :param restricted_to_protocols: the only supported protocols for this connection.
        :param excluded_protocols: the excluded protocols for this connection.
        """
        if kwargs.get("connection_id") is None:
            kwargs["connection_id"] = PublicId("fetchai", "oef", "0.1.0")
        super().__init__(*args, **kwargs)
        self._core = AsyncioCore(logger=logger)  # type: AsyncioCore
        self.in_queue = None  # type: Optional[asyncio.Queue]
        self.channel = OEFChannel(
            address, oef_addr, oef_port, core=self._core,
        )  # type: ignore

        self._connection_check_thread = None  # type: Optional[Thread]
Пример #5
0
    def __init__(self, public_key: str, oef_addr: str, oef_port: int = 10000):
        """
        Initialize.

        :param public_key: the public key of the agent.
        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        """
        super().__init__()
        core = AsyncioCore(logger=logger)
        self._core = core  # type: AsyncioCore
        self.channel = OEFChannel(public_key,
                                  oef_addr,
                                  oef_port,
                                  core=core,
                                  in_queue=self.in_queue)

        self._stopped = True
        self._connected = False
        self.out_thread = None  # type: Optional[Thread]
Пример #6
0
    def on_message(self, msg_id: int, dialogue_id: int, origin: str,
                   content: bytes):
        """Extract and print data from incoming (simple) messages."""
        data = json.loads(content.decode("utf-8"))
        print("[{0}]: Received measurement from {1}: {2}".format(
            self.public_key, origin, pprint.pformat(data)))
        self.stop()


def logger(*args):
    print(">>", *args)


if __name__ == "__main__":
    core = AsyncioCore(logger=logger)
    core.run_threaded()

    # create and connect the agent
    agent = WeatherClient("weatherCLient",
                          oef_addr="127.0.0.1",
                          oef_port=10000,
                          core=core)
    agent.connect()

    # look for service agents registered as 'weather_station' that:
    # - provide measurements for temperature
    # - provide measurements for air pressure
    # - provide measurements for humidity
    query = Query([
        Constraint(TEMPERATURE_ATTR.name, Eq(True)),
Пример #7
0
class OEFConnection(Connection):
    """The OEFConnection connects the to the mailbox."""

    def __init__(self, oef_addr: str, oef_port: int = 10000, **kwargs):
        """
        Initialize.

        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        :param kwargs: the keyword arguments (check the parent constructor)
        """
        if kwargs.get("configuration") is None and kwargs.get("connection_id") is None:
            kwargs["connection_id"] = PublicId("fetchai", "oef", "0.1.0")
        super().__init__(**kwargs)
        self.oef_addr = oef_addr
        self.oef_port = oef_port
        self._core = AsyncioCore(logger=logger)  # type: AsyncioCore
        self.in_queue = None  # type: Optional[asyncio.Queue]
        self.channel = OEFChannel(self.address, self.oef_addr, self.oef_port, core=self._core)  # type: ignore
        self._connection_check_task = None  # type: Optional[asyncio.Future]

    async def connect(self) -> None:
        """
        Connect to the channel.

        :return: None
        :raises Exception if the connection to the OEF fails.
        """
        if self.connection_status.is_connected:
            return
        try:
            self.connection_status.is_connecting = True
            self._core.run_threaded()
            loop = asyncio.get_event_loop()
            self.in_queue = asyncio.Queue()
            await self._try_connect()
            self.connection_status.is_connecting = False
            self.connection_status.is_connected = True
            self.channel.loop = loop
            self.channel.in_queue = self.in_queue
            self._connection_check_task = asyncio.ensure_future(
                self._connection_check(), loop=self._loop
            )
        except (CancelledError, Exception) as e:  # pragma: no cover
            self._core.stop()
            self.connection_status.is_connected = False
            raise e

    async def _try_connect(self) -> None:
        """
        Try connect to the channel.

        :return: None
        :raises Exception if the connection to the OEF fails.
        """
        while not self.connection_status.is_connected:
            if not self.channel.connect():
                logger.warning("Cannot connect to OEFChannel. Retrying in 5 seconds...")
                await asyncio.sleep(5.0)
            else:
                break

    async def _connection_check(self) -> None:
        """
        Check for connection to the channel.

        Try to reconnect if connection is dropped.

        :return: None
        """
        while self.connection_status.is_connected:
            await asyncio.sleep(2.0)
            if not self.channel.get_state() == "connected":  # pragma: no cover
                self.connection_status.is_connected = False
                self.connection_status.is_connecting = True
                logger.warning(
                    "Lost connection to OEFChannel. Retrying to connect soon ..."
                )
                await self._try_connect()
                self.connection_status.is_connected = True
                logger.warning("Successfully re-established connection to OEFChannel.")

    async def disconnect(self) -> None:
        """
        Disconnect from the channel.

        :return: None
        """
        assert (
            self.connection_status.is_connected or self.connection_status.is_connecting
        ), "Call connect before disconnect."
        assert self.in_queue is not None
        self.connection_status.is_connected = False
        self.connection_status.is_connecting = False
        if self._connection_check_task is not None:
            self._connection_check_task.cancel()
            self._connection_check_task = None
        self.channel.disconnect()
        await self.in_queue.put(None)
        self._core.stop()

    async def receive(self, *args, **kwargs) -> Optional["Envelope"]:
        """
        Receive an envelope. Blocking.

        :return: the envelope received, or None.
        """
        try:
            assert self.in_queue is not None
            envelope = await self.in_queue.get()
            if envelope is None:
                logger.debug("Received None.")
                return None
            logger.debug("Received envelope: {}".format(envelope))
            return envelope
        except CancelledError:
            logger.debug("Receive cancelled.")
            return None
        except Exception as e:
            logger.exception(e)
            return None

    async def send(self, envelope: "Envelope") -> None:
        """
        Send an envelope.

        :param envelope: the envelope to send.
        :return: None
        """
        if self.connection_status.is_connected:
            self.channel.send(envelope)

    @classmethod
    def from_config(
        cls, address: Address, configuration: ConnectionConfig
    ) -> "Connection":
        """
        Get the OEF connection from the connection configuration.
        :param address: the address of the agent.
        :param configuration: the connection configuration object.
        :return: the connection object
        """
        oef_addr = cast(str, configuration.config.get("addr"))
        oef_port = cast(int, configuration.config.get("port"))
        return OEFConnection(
            oef_addr, oef_port, address=address, configuration=configuration
        )
Пример #8
0
class OEFConnection(Connection):
    """The OEFConnection connects the to the mailbox."""

    restricted_to_protocols = set()  # type: Set[str]

    def __init__(self,
                 public_key: str,
                 oef_addr: str,
                 oef_port: int = 10000,
                 connection_id: str = "oef",
                 restricted_to_protocols: Optional[Set[str]] = None):
        """
        Initialize.

        :param public_key: the public key of the agent.
        :param oef_addr: the OEF IP address.
        :param oef_port: the OEF port.
        :param connection_id: the identifier of the connection object.
        :param restricted_to_protocols: the only supported protocols for this connection.
        """
        super().__init__(connection_id=connection_id,
                         restricted_to_protocols=restricted_to_protocols)
        self._core = AsyncioCore(logger=logger)  # type: AsyncioCore
        self.in_queue = None  # type: Optional[asyncio.Queue]
        self.channel = OEFChannel(public_key,
                                  oef_addr,
                                  oef_port,
                                  core=self._core)

        self._connection_check_thread = None  # type: Optional[Thread]

    async def connect(self) -> None:
        """
        Connect to the channel.

        :return: None
        :raises Exception if the connection to the OEF fails.
        """
        if self.connection_status.is_connected:
            return
        try:
            self._core.run_threaded()
            loop = asyncio.get_event_loop()
            self.in_queue = asyncio.Queue()
            await self._try_connect()
            self.connection_status.is_connected = True
            self.channel.loop = loop
            self.channel.in_queue = self.in_queue
            self._connection_check_thread = Thread(
                target=self._connection_check)
            self._connection_check_thread.start()
        except (CancelledError, Exception) as e:  # pragma: no cover
            self._core.stop()
            self.connection_status.is_connected = False
            raise e

    async def _try_connect(self) -> None:
        """
        Try connect to the channel.

        :return: None
        :raises Exception if the connection to the OEF fails.
        """
        while not self.connection_status.is_connected:
            if not self.channel.connect():
                logger.warning(
                    "Cannot connect to OEFChannel. Retrying in 5 seconds...")
                await asyncio.sleep(5.0)
            else:
                break

    def _connection_check(self) -> None:
        """
        Check for connection to the channel.

        Try to reconnect if connection is dropped.

        :return: None
        """
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        while self.connection_status.is_connected:
            time.sleep(2.0)
            if not self.channel.get_state() == "connected":  # pragma: no cover
                self.connection_status.is_connected = False
                logger.warning(
                    "Lost connection to OEFChannel. Retrying to connect soon ..."
                )
                loop.run_until_complete(self._try_connect())
                self.connection_status.is_connected = True
                logger.warning(
                    "Successfully re-established connection to OEFChannel.")

    async def disconnect(self) -> None:
        """
        Disconnect from the channel.

        :return: None
        """
        assert self._connection_check_thread is not None, "Call connect before disconnect."
        assert self.in_queue is not None
        self.connection_status.is_connected = False
        self._connection_check_thread.join()
        self._connection_check_thread = None
        self.channel.disconnect()
        await self.in_queue.put(None)
        self._core.stop()

    async def receive(self, *args, **kwargs) -> Optional['Envelope']:
        """
        Receive an envelope. Blocking.

        :return: the envelope received, or None.
        """
        try:
            assert self.in_queue is not None
            envelope = await self.in_queue.get()
            if envelope is None:
                logger.debug("Received None.")
                return None
            logger.debug("Received envelope: {}".format(envelope))
            return envelope
        except CancelledError:
            logger.debug("Receive cancelled.")
            return None
        except Exception as e:
            logger.exception(e)
            return None

    async def send(self, envelope: 'Envelope') -> None:
        """
        Send an envelope.

        :param envelope: the envelope to send.
        :return: None
        """
        if self.connection_status.is_connected:
            self.channel.send(envelope)

    @classmethod
    def from_config(
            cls, public_key: str,
            connection_configuration: ConnectionConfig) -> 'Connection':
        """
        Get the OEF connection from the connection configuration.

        :param public_key: the public key of the agent.
        :param connection_configuration: the connection configuration object.
        :return: the connection object
        """
        oef_addr = cast(str, connection_configuration.config.get("addr"))
        oef_port = cast(int, connection_configuration.config.get("port"))
        return OEFConnection(
            public_key,
            oef_addr,
            oef_port,
            connection_id=connection_configuration.name,
            restricted_to_protocols=set(
                connection_configuration.restricted_to_protocols))