aiomas.agent

This module implements the base class for agents (Agent) and containers for agents (Container).

Every agent must live in a container. A container can contain one ore more agents. Containers are responsible for making connections to other containers and agents. They also provide a factory function for spawning new agent instances and registering them with the container.

Thus, the Agent base class is very light-weight. It only has a name, a reference to its container and an RPC router (see aiomas.rpc).

class aiomas.agent.SSLCerts(cafile, certfile, keyfile)

namedtuple() storing the names of a CA file, a certificate file and the associated private key file.

See also aiomas.util.make_ssl_server_context() and aiomas.util.make_ssl_client_context().

cafile

Alias for field number 0

certfile

Alias for field number 1

keyfile

Alias for field number 2

class aiomas.agent.Container(base_url, clock, connect_kwargs)[source]

Container for agents.

You should not instantiate containers directly but use the create() method/coroutine instead. This makes sure that the container’s server socket is fully operational when it is created.

The container allows its agents to create connections to other agents (via connect()).

In order to destroy a container and close all of its sockets, call shutdown().

classmethod create(addr, *, clock=None, codec=None, extra_serializers=None, ssl=None, as_coro=False)[source]

Instantiate a container and create a server socket for it.

This function is a classmethod and coroutine.

Parameters:
  • addr

    is the address that the server socket is bound to. It may be a (host, port) tuple for a TCP socket, a path for a Unix domain socket, or a LocalQueue instance as returned by the aiomas.local_queue.get_queue() function.

    TCP sockets

    If host is '0.0.0.0' or '::', the server is bound to all available IPv4 or IPv6 interfaces respectively. If host is None or '', the server is bound to all available IPv4 and IPv6 interfaces. In these cases, the machine’s FQDN (see socket.getfqdn()) should be resolvable and point to that machine as it will be used for the agent’s addresses.

    If host is a simple (IPv4 or IPv6) IP address, it will be used for the agent’s addresses as is.

    LocalQueue

    In contrast to TCP, multiple LocalQueue connections between containers (within the same thread and OS process) send and receive message in a deterministic order, which is useful for testing and debugging.

    LocalQueue instances should be retrieved via the aiomas.local_queue.get_queue() function (which also available as aiomas.get_queue()). This function always returns the same instance for a given queue ID.

  • clock

    can be an instance of BaseClock.

    It allows you to decouple the container’s (and thus, its agent’s) time from the system clock. This makes it easier to integrate your system with other simulators that may provide a clock for you or to let your MAS run as fast as possible.

    By default, the real-time AsyncioClock will be used.

  • codec – can be a Codec subclass (not an instance!). JSON is used by default.
  • extra_serializers – is an optional list of extra serializers for the codec. The list entries need to be callables that return a tuple with the arguments for add_serializer().
  • ssl – allows you to enable TLS for all incoming and outgoing TCP connections. It may either be an SSLCerts instance or a tuple containing two SSLContext instances, where the first one will be used for the server socket, the second one for client sockets.
  • as_coro – must be set to True if the event loop is already running when you call this method. This function then returns a coroutine that you need to await in order to get the container. By default it will block until the server has been started and return the container.
Returns:

a fully initialized Container instance if async is False or else a coroutine returning the instance when it is done.

Invocation examples:

# Synchronous:
container = Container.create(...)

# Asynchronous:
container = await Container.create(..., as_coro=True)
clock

The clock of the container. Instance of aiomas.clocks.BaseClock.

connect(url, timeout=0)[source]

Connect to the argent available at url and return a proxy to it.

url is a string <protocol>://<addr>//<agent-id> (e.g., 'tcp://localhost:5555/0').

With a timeout of 0 (the default), there will only be one connection attempt before an error is raised (ConnectionRefusedError for TCP sockets and LocalQueue, FileNotFoundError for Unix domain sockets). If you set timeout to a number > 0 or None, this function will try to connect repeatedly for at most that many seconds (or indefinitely) before an error is raised. Use this if the remote agent’s container may not yet exist.

This function is a coroutine.

shutdown(as_coro=False)[source]

Close the container’s server socket and the RPC services for all outgoing TCP connections.

If async is left to False, this method calls asyncio.BaseEventLoop.run_until_complete() in order to wait until all sockets are closed.

Set async to True if the event loop is already running (e.g., because you are in a coroutine). The return value then is a coroutine that you need to await in order to actually shut the container down:

await container.shutdown(as_coro=True)
validate_aid(aid)[source]

Return the class name for the agent represented by aid if it exists or None.

class aiomas.agent.Agent(container)[source]

Base class for all agents.

router

Descriptor that creates an RPC Router for every agent instance.

You can override this in a sub-class if you need to. (Usually, you don’t.)

container

The Container that the agent lives in.

addr

The agent’s address.