- Enforce that multiple calls to `pykka.Future.set()` raises an exception. This was already the case for some implementations. The exception raised is not specified.
- Add `pykka.Future.set_get_hook()`.
- Add `pykka.Future.filter()`, `pykka.Future.join()`, `pykka.Future.map()`, and `pykka.Future.reduce()` as convenience methods using the new `pykka.Future.set_get_hook()` method.
- Add support for running actors based on eventlet greenlets. See `pykka.eventlet` for details. Thanks to Jakub Stasiak for the implementation.
- Update documentation to reflect that the `reply_to` field on the message is private to Pykka. Actors should reply to messages simply by returning the response from `pykka.Actor.on_receive()`. The internal field is renamed to `pykka_reply_to` to avoid collisions with other message fields. It is also removed from the message before the message is passed to `pykka.Actor.on_receive()`. Thanks to Jakub Stasiak.
- When messages are left in the actor inbox after the actor is stopped, those messages that are expecting a reply are now rejected by replying with a `pykka.ActorDeadError` exception. This causes other actors that are blocking on the returned `pykka.Future` without a timeout to raise the exception instead of waiting forever. Thanks to Jakub Stasiak.
This makes the behavior of messaging an actor around the time it is stopped more consistent:
- Messaging an already dead actor immediately raises `pykka.ActorDeadError`.
- Messaging an alive actor that is stopped before it processes the message will cause the reply future to raise `pykka.ActorDeadError`.
Similarly, if you ask an actor to stop multiple times, and block on the responses, all the messages will now get a reply. Previously only the first message got a reply, potentially making the application wait forever on replies to the subsequent stop messages.
- When `pykka.ActorRef.ask()` is used to asynchronously message a dead actor (e.g. `block=False`), it will no longer immediately raise `pykka.ActorDeadError`. Instead, it will return a future and fail the future with the `pykka.ActorDeadError` exception. This makes the interface more consistent, as you'll have one instead of two ways the call can raise exceptions under normal conditions. If `pykka.ActorRef.ask` is called synchronously (e.g. `block=True`), the behavior is unchanged.
- A change to `pykka.ActorRef.stop()` reduces the likelihood of a race condition when asking an actor to stop multiple times by not checking if the actor is dead before asking it to stop, but instead, just go ahead and leave it to `pykka.ActorRef.tell()` to do the alive-or-dead check a single time, and as late as possible.
- Change `pykka.ActorRef.is_alive()` to check the actor's runnable flag instead of checking if the actor is registered in the actor registry.