Evergreen 0.2.0 released!

I’m very happy to announce I just released evergreen 0.2.0! From the API standpoint, not many things changed, but a number of important internal changes happened, including a change in how callbacks are scheduled in the event loop, which fixed a nasty issue in Windows.

For those who may not know:

Evergreen is a cooperative multitasking and i/o library for Python. It provides equivalent primitives to those for thread programming, but uses a cooperative model instead.

Operations are driven by an event loop which will run the given tasks and i/o operations in a non-blocking manner while presenting the user a synchronous, blocking API.

Here is the full changelog:

 – Revert “Don’t allow futures to be used more than once”
 – Break potential cycle because we are storing the traceback
 – Fixed passing traceback when propagating exception to MAIN parent
 – Process all callbacks using an Idle handle
 – Replaced use of Future in io module for Result
 – Don’t wait for send operation to complete in UDPEndpoint
 – Always run tests from the right directory
 – Fix UDP test case on Windows
 – Added flush() method to UDPEndpoint and Stream objects
 – Cache sockname and peername properties
The code can be downloaded from GitHub, as usual. Hope you like it!
:wq

fibers: lightweight cooperative microthreads for Python

Hi all!

Today I’m really happy to share the first version of fibers, a project I’ve working on for a while.

Fibers are lightweight primitives for cooperative multitasking in Python. They provide means for running pieces of code that can be paused and resumed. Unlike threads, which are preemptively scheduled, fibers are scheduled cooperatively, that is, only one fiber will be running at a given point in time, and no other fiber will run until the user explicitly decides so.

When a fiber is created it will not run automatically. A fiber must be ‘switched’ into for it to run. Fibers can switch control to other fibers by way of the switch or throw functions, which switch control or raise and exception in the target fiber respectively.

 

This project is heavily inspired by greenlet, as you may have noticed. I’ve been using greenlet for a long while, but for a recent project I’ve worked on, I wanted to offer an interface similar to the Thread class from the threading module. Unfortunately the API in greenlet didn’t make it easy, so I took it as an excuse to try to build the library I wanted to use, which hopefully also helps others.

The obvious step would have been to fork greenlet itself and change the API to my needs, but I randomly ran into stacklet, a tiny library hidden in the PyPy source code, which is used as the base for the greenlet implementation in PyPy.

So, I stood on shoulders of giants and built fibers using stacklet. It solves my problems, hopefully it can help you too! In case you are interested in a more verbose version of the project rationale, I added a specific section in the documentation.

The source code is available on GitHub, with MIT license, enjoy!

:wq

greenlet local storage on greenlet 0.4.0

Greenlet 0.4.0 brought an interesting new feature: an instance dictionary on each greenlet object, which makes it a lot simpler to implement greenlet local storage. Here is how greenlet local storage is currently implemented in Eventlet and in Gevent.

As it can be seen, the implementation is not particularly straightforward, mainly due to the fact that the actual information needs to be stored in a separate entity and mapped to each greenlet.

Thanks to the instance dictionary added in 0.4.0, we can use some attribute in it to keep the locally stored objects. The plan is to use a dictionary called __local_dict__ and store the greenlet local attributes there. Here is how it looks like:

Hope it’s of use.

:wq