Skip to content

Releases: jodal/pykka

v2.0.2 (2019-12-02)

07 Mar 10:51
v2.0.2
Compare
Choose a tag to compare

Bugfix release.

  • Fix test suite when executed with pytest-mocker >= 1.11.2. (Fixes: #85)

v2.0.1 (2019-10-10)

07 Mar 10:50
Compare
Choose a tag to compare

Bugfix release.

  • Make pykka.ActorRef hashable.

v2.0.0 (2019-05-07)

07 Mar 10:50
Compare
Choose a tag to compare

Major feature release.

Dependencies

  • Drop support for Python 2.6, 3.2, 3.3, and 3.4. All have reached their end of life and do no longer receive security updates.

  • Include CPython 3.5, 3.6, 3.7, and 3.8 pre-releases, and PyPy 3.5 in the test matrix.

  • Include gevent and Eventlet tests in all environments. Since Pykka was originally developed, both have grown support for Python 3 and PyPy.

  • On Python 3, import Callable and Iterable from collections.abc instead of collections. This fixes a deprecation warning on Python 3.7 and prepares for Python 3.8.

Actors

  • Actor messages are no longer required to be dict objects. Any object type can be used as an actor message. (Fixes: #39, #45, PR: #79)

    For existing code, this means that pykka.Actor.on_receive() implementations should no longer assume the received message to be a
    dict, and guard with the appropriate amount of isinstance() checks. As an existing application will not observe any new message types before it starts using them itself, this is not marked as backward incompatible.

Proxies

  • Backwards incompatible: Avoid accessing actor properties when creating a proxy for the actor. For properties with side effects, this is a major bug fix. For properties which do heavy work, this is a major startup performance improvement.

    This is backward incompatible if you in a property getter returned an object instance with the pykka_traversable marker. Previously, this would work just like a traversable attribute. Now, the property always returns a future with the property getter's return value.

  • Fix infinite recursion when creating a proxy for an actor with an attribute or method replaced with a unittest.mock.Mock without a spec defined. (Fixes: #26, #27)

  • Fix infinite recursion when creating a proxy for an actor with an attribute that was itself a proxy to the same actor. The attribute will now be ignored and a warning log message will ask you to consider making the self-proxy private. (Fixes: #48)

  • Add pykka.CallableProxy.defer() to support method calls through a proxy with pykka.ActorRef.tell() semantics. (Contributed by Andrey Gubarev. Fixes: #63. PR: #72)

  • Add pykka.traversable() for marking an actor's attributes as traversable when used through actor proxies. The old way of manually adding a pykka_traversable attribute to the object to be traversed still works, but the new function is recommended as it provides protection against typos in the marker name, and keeps the traversable marking in the actor class itself. (PR: #81)

Futures

  • Backwards incompatible: pykka.Future.set_exception() no longer accepts an exception instance, which was deprecated in 0.15. The method can be called with either an exc_info tuple or None, in which case it will use sys.exc_info() to get information on the current exception.

  • Backwards incompatible: pykka.Future.map() on a future with an iterable result no longer applies the map function to each item in iterable. Instead, the entire future result is passed to the map function. (Fixes: :issue:64)

    To upgrade existing code, make sure to explicitly apply the core of your map function to each item in the iterable:

    >>> f = pykka.ThreadingFuture()
    >>> f.set([1, 2, 3])
    >>> f.map(lambda x: x + 1).get()  # Pykka < 2.0
    [2, 3, 4]
    >>> f.map(lambda x: [i + 1 for i in x]).get()  # Pykka >= 2.0
    [2, 3, 4]

    This change makes it easy to use :meth:pykka.Future.map to extract a field from a future that returns a dict:

    >>> f = pykka.ThreadingFuture()
    >>> f.set({'foo': 'bar'})
    >>> f.map(lambda x: x['foo']).get()
    'bar'

    Because dict is an iterable, the now removed special handling of iterables made this pattern difficult to use.

  • Reuse result from pykka.Future.filter(), pykka.Future.map(), and pykka.Future.reduce(). Recalculating the result on each call to pykka.Future.get() is both inconsistent with regular futures and can cause problems if the function is expensive or has side effects. (Fixes: #32)

  • If using Python 3.5+, one can now use the await keyword to get the result from a future. (Contributed by Joshua Doncaster-Marsiglio. PR: #78)

Logging

  • Pykka's use of different log levels has been documented.

  • Exceptions raised by an actor that are captured into a reply future are now logged on the logging.INFO level instead of the logging.DEBUG level. This makes it possible to detect potentially unhandled exceptions during development without having to turn on debug logging, which can have a low signal-to-noise ratio. (Contributed by Stefan Möhl. Fixes: #73)

Gevent support

  • Ensure that the original traceback is preserved when an exception is returned through a future from a Gevent actor. (Contributed by Arne Brutschy. Fixes: #74, PR: #75)

Internals

  • Backwards incompatible: Prefix all internal modules with _. This is backward-incompatible if you have imported objects from other import paths than what is used in the documentation.

  • Port tests to pytest.

  • Format code with Black.

  • Change internal messaging format from dict to namedtuple. (PR: #80)

v1.2.1 (2015-07-20)

07 Mar 10:39
Compare
Choose a tag to compare
  • Increase log level of pykka.debug.log_thread_tracebacks() debugging helper from logging.INFO to logging.CRITICAL.

  • Fix errors in docs examples. (PR: #29, #43)

  • Fix typos in docs.

  • Various project setup and development improvements.

v1.2.0 (2013-07-15)

07 Mar 10:38
Compare
Choose a tag to compare
  • 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.

v1.1.0 (2013-01-19)

07 Mar 10:31
Compare
Choose a tag to compare
  • An exception raised in pykka.Actor.on_start() didn't stop the actor properly. Thanks to Jay Camp for finding and fixing the bug.

  • Make sure exceptions in pykka.Actor.on_stop() and pykka.Actor.on_failure() is logged.

  • Add pykka.ThreadingActor.use_daemon_thread flag for optionally running an actor on a daemon thread, so that it doesn't block the Python program from exiting. (Fixes: #14)

  • Add pykka.debug.log_thread_tracebacks() debugging helper. (Fixes: #17)

v1.0.1 (2012-12-12)

07 Mar 10:29
Compare
Choose a tag to compare
  • Name the threads of pykka.ThreadingActor after the actor class name instead of PykkaThreadingActor-N to ease debugging. (Fixes: #12)

v1.0.0 (2012-10-26)

07 Mar 10:28
Compare
Choose a tag to compare
  • Backwards incompatible: Removed pykka.VERSION and pykka.get_version(), which have been deprecated since v0.14. Use pykka.__version__ instead.

  • Backwards incompatible: Removed pykka.ActorRef.send_one_way() and pykka.ActorRef.send_request_reply(), which have been deprecated since v0.14. Use pykka.ActorRef.tell() and pykka.ActorRef.ask() instead.

  • Backwards incompatible: Actors no longer subclass threading.Thread or gevent.Greenlet. Instead, they have a thread or greenlet that executes the actor's main loop.

    This is backward incompatible because you no longer have access to fields/methods of the thread/greenlet that runs the actor through fields/methods on the actor itself. This was never advertised in Pykka's docs or examples, but the fields/methods have always been available.

    As a positive side effect, this fixes an issue on Python 3.x, that was introduced in Pykka 0.16, where pykka.ThreadingActor would
    accidentally override the method threading.Thread._stop().

  • Backwards incompatible: Actors that override pykka.Actor.__init__() must call the method they override. If not, the actor will no longer be properly initialized. Valid ways to call the overridden __init__() method include::

    super().__init__()
    # or
    pykka.ThreadingActor.__init__()
    # or
    pykka.gevent.GeventActor.__init__()
  • Make pykka.Actor.__init__() accept any arguments and keyword arguments by default. This allows you to use super() in __init__() like this:

    super().__init__(1, 2, 3, foo='bar')

    Without this fix, the above use of super() would cause an exception because the default implementation of __init__() in pykka.Actor would not accept the arguments.

  • Allow all public classes and functions to be imported directly from the pykka module. E.g. from pykka.actor import ThreadingActor can now be written as from pykka import ThreadingActor. The exception is pykka.gevent, which still needs to be imported from its own package due to its additional dependency on gevent.

v0.16 (2012-09-19)

07 Mar 10:23
Compare
Choose a tag to compare
  • Let actors access themselves through a proxy. See the pykka.ActorProxy documentation for use cases and usage examples. (Fixes: #9)

  • Give proxies direct access to the actor instances for inspecting available attributes. This access is only used for reading and works since both threading and gevent based actors share memory with other actors. This reduces the creation cost for proxies, which is mostly visible in test suites that are starting and stopping lots of actors. For the Mopidy test suite, the run time was reduced by about 33%. This change also makes self-proxying possible.

  • Fix bug where pykka.Actor.stop() called by an actor on itself did not process the remaining messages in the inbox before the actor stopped. The behavior now matches the documentation.

v0.15 (2012-08-11)

07 Mar 10:22
Compare
Choose a tag to compare
  • Change the argument of pykka.Future.set_exception() from an exception instance to an exc_info three-tuple. Passing just an exception instance to the method still works, but it is deprecated and may be unsupported in a future release.

  • Due to the above change pykka.Future.get() will now reraise exceptions with complete traceback from the point when the exception was first raised and not just a traceback from when it was reraised by get(). (Fixes: #10)