Change log

2.0.1 – 2017-12-29

  • [CHANGE] Restore support for Python 3.5 so that the docs on Read the Docs build again.

2.0.0 – 2017-12-28

  • [BREAKING] Converted to f-Strings and async/await syntax. The minimum required Python versions are now Python 3.6 and PyPy3 5.10.0.
  • [BREAKING] Removed aiomas.util.async() and aiomas.util.create_task().
  • [CHANGE] Move from Bitbucket and Mercurial to GitLab and Git.
  • [FIX] Adjust to asyncio changes and explicitly pass references to the current event loop where necessary.

1.0.3 – 2016-05-09

  • [FIX] The function asyncio.ensure_future() called in aiomas.util.create_task() was introduced in Python 3.4.4 and is not available in Python 3.4.0–3.4.3 (which is, e.g., used on Ubuntu 14.04). There is now a fallback to asyncio.async() if asyncio.ensure_future() is not available.

1.0.2 – 2016-05-04

  • [CHANGE] aiomas.util.create_task() replaces aiomas.util.async(). aiomas.util.async() is now deprecated and will be removed in aiomas 2 and when a new Python release no longer allows to use async as name.
  • [NEW] Added developer documentation.

1.0.1 – 2016-04-22

  • [BREAKING CHANGE] Renamed the async argument for Container.create() and Container.shutdown() to as_coro. Realized to late that it will come to name clashes with the async keyword added to Python 3.5. I assume that no one really uses this project yet, thus I mark it as bug-fix relaese rather then bumping aiomas to v2.

1.0.0 – 2016-04-18

  • [BREAKING CHANGE] channel.Channel.close() and rpc.RpcClient.close() are now coroutines.
  • [BREAKING CHANGE] rpc.start_server() and rpc.open_connection() now take RPC services instead of routers. Services are the objects that contain the routers. To fix your code, replace things like router=MyService().router with rpc_service=MyService().
  • [CHANGE] channel.Channel.send() now raises a ValueError if a message is too long to be send. A message is too long if its length does not fit into a 32bit unsigned integer.
  • [NEW] The various connect functions now accept a timeout parameter. If it is set to a number > 0 (or to None) it tries to connect for the specified amount of time (or indefinitely) before raise a ConnectionRefusedError. This way, you can start clients before (or at the “same” time) you start the server.
  • [NEW] You can register a callback to rpc.RpcClient that gets called when the network connection is reset. This helps reacting to connection losses if the rpc.RpcClient only has an RPC service running but is not actively performing any task.
  • [NEW] Added a SerializationError that gets raised if a message cannot be serialized.
  • [NEW] Added a subproc module that helps you to spawn subprocesses for agents. Each subprocess will have a container and a managing agent that can be remote-controlled to start more agents within its container.
  • [NEW] Added a LocalQueue transport that sends messages of multiple connections (e.g., from different agent containers) within a process in a deterministic order. This should make debugging, tuning and testing easier.
  • [NEW] A lot of documentation.

0.6.1 – 2015-10-21

  • [CHANGE] Agent now also accepts subclasses of Container (issue #17).
  • [FIX] issue #16: Container API docs no correctly refer to the “create()” method.

0.6.0 – 2015-09-18

  • [CHANGE] Asserted Python 3.5 compatibility and converted all examples to use the new async and await keywords.
  • [CHANGE] Container.__init__() no longer contains an asynchronous task. Instead, you now need to call the factory function Container.create().
  • [CHANGE] Removed Container.spawn(). You can now directly instantiate agent instances but you still need to pass a reference to the agent’s container to Agent.__init__().
  • [NEW] AiomasError is the new base class for all errors in aiomas (issue #15).
  • [NEW] Documentation tests now have their own tox environment (tox -e docs).
  • [NEW] Added support and docs for TLS encryption.
  • [NEW] Added some documentation about the channel layer.

0.5.0 – 2015-06-27

  • [CHANGE] Agent addresses now start with tcp:// or ipc:// (for Unix domain sockets) instead of just agent://.
  • [CHANGE] Using dictionaries as routers is now easier (issue #13).
  • [CHANGE] Renamed the rpc attribute for routers to router.
  • [CHANGE] Renamed to Agent.addr and improved agent’s str representation.
  • [CHANGE] Updated and improved str and repr for agents, proxies and agent proxies.
  • [CHANGE] Codec.add_serializer() now raises an exception if there is already a serializer for a given type (issue #9).
  • [NEW] Added (and an alias) which are shortcuts for loop = asyncio.get_event_loop(); loop_run_{until_complete|forever}().
  • [NEW] Added a @serializable decorator to aiomas.codecs which simplifies making a type serializable.
  • [NEW] Documentation: Overview, Agents, Codecs, Clocks (draft), Testing (draft).
  • [NEW] Container.connect() checks if an agent exists in the remote container.
  • [NEW] Proxies are now cached with weakrefs.
  • [FIX] issue #12: Router.path reversed the order of path components.
  • [FIX] Fixed a bug where concurrent calls to Container.connect() would lead to multiple connections to the same address.

0.4.0 – 2015-04-15

  • [CHANGE] Channel and Container no longer take codec instances but classes. They also accept a list of factories for extra serializers.
  • [CHANGE] The rpc.open_connection() and rpc.start_server() methods no longer accept the add_to parameter. rpc.start_server() accept a client_connected_cb instead, which should be a function with one argument, the RpcClient for each new connection. rpc.open_connection() already returns the RpcClient().
  • [CHANGE] Renamed the package extras from MsgPack to mp and from MsgPackBlosc to mpb to work around a bug in pip/setuptools. They are also shorter now. ;-)
  • [NEW] RpcClient no has a channel and a service attribute.
  • [NEW] Improved error message for LookupError.
  • [FIX] issue #8: Every channel instance created by channel.start_server() now has a separate codec instance to avoid problems with some serializers.

0.3.0 – 2015-03-11

  • [CHANGE] Removed LocalProxies and everything related to it because they caused several problems. That means that agents within a single container now also communicate via TCP sockets. Maybe something similar but more robust will be reintroduced in a later release.
  • [CHANGE] Channel.send() is no longer a coroutine. It returns a Future instead.
  • [CHANGE] Removed Container.get_url_for() which didn’t (and couldn’t) work as I originally assumed.
  • [CHANGE] JSON is now the default codec. msgpack and blosc don’t get installed by default. This way, we only have pure Python dependencies for the default installation which is very handy if you are on Windows. You can enable the other codecs via pip install -U aiomas[MsgPack] or pip install -U aiomas[MsgPackBlosc].
  • [NEW] Support for Python 3.4.0 and 3.4.1 (yes, Python 3.3 with asyncio works, too, but I’ll drop support for it as soon as it becomes a burden) (Resolves issue #6).
  • [NEW] ExternalClock accepts a date string or an Arrow object to set the inital date and time.
  • [NEW] aiomas.util.async() which is like asyncio.async() but registers a callback that instantly captures and raises exceptions, instead of delaying them until the task gets garbage collected.
  • [NEW] The agent container adds a serializer for Arrow dates.
  • [NEW] Proxy implements __eq__() and __hash__(). Two different proxy objects sharing the same channel and pointing to the same remote function will no appear to be equal. This makes it less error prone to use Proxy instances as keys in dictionaries.
  • [NEW] Updated and improved flow-control for Channel and its protocol.
  • [NEW] Improved error handling if the future returned by Channel.send() is triggered or cancelled by an external party (e.g., by going out of scope). If asyncio’s DEBUG mode is enabled, you will even get more detailed error messages.
  • [NEW] MessagePackBlosc codec. It uses msgpack to serialize messages and blosc to compress them. It can massively reduce the message size and consumes very little CPU time.
  • [NEW] A Contract Net example (
  • [NEW] __str__() representations for agents, containers and codecs (fixes issue #5).
  • [FIX] issue #7: Improved error handling and messages if the (de)serialization raises an exception.
  • [FIX] Containers now work with unix domain sockets.
  • [FIX] Various minor bug-fixes

0.2.0 - 2015-01-23

  • [CHANGE] The MsgPack codec is now the default. Thus, msgpack-python is now a mandatory dependency.
  • [CHANGE] Renamed to RpcClient.remote.
  • [NEW] aiomas.agent module with an Agent base class and a Container for agents. Agents within a container communicate via direct method calls. Agents in different containers use RPC.
  • [NEW] aiomas.clock module which offers various clocks for a MAS:
    • AsyncioClock is a real-time clock and wraps asyncio’s time(), sleep(), call_later() and call_at() functions.
    • ExternalClock can be synchronized with external simulation environments. This allows you to stop the time or let it pass faster/slower than the wall-clock time.
  • [NEW] Support for unix domain sockets in and aiomas.rpc.
  • [NEW] “rpc_service()” tasks created by an RPC server can now be collected so that you can wait for their completion before you shutdown your program.
  • [NEW] Added contents to the README and created a Sphinx project. Only the API reference is done yet. A tutorial and topical guides will follow.
  • [FIX] aiomas with the JSON codec is now compatible to

0.1.0 – 2014-12-18

Initial release with the following features:

  • A request-reply channel via TCP that allows to send multiple messages and to asynconously wait for results (or an exception).
  • Messages can be serialized with JSON or msgpack.
  • The underlying communication protocol should be compatible with (if you use JSON and no custom serializers).
  • Remote procedure calls (RPCs) supporting nested handlers and bidirectional calls (callees can make calls to the caller before returning the actual result).