Archive

Author Archive

EuroPython 2010

May 27, 2010 5 comments

UPDATE: Slides and the text of the talk are available for download. Feel free to use for your own presentations under CC3.0.

I’m going to give a talk on gevent at EuroPython on Thursday 22nd July at 11.00am in Birmingham, United Kingdom.

The contents of the talk is not well defined yet but I’d like to cover the following:

  • Coroutine-based approach to network programming and how it solves Python’s concurrency problems.
  • Greenlets: what they do and how they do it. Why they are better than the alternatives – generators, threads.
  • How gevent and eventlet use greenlet to do what they do, the basic principles they operate on.
  • How sockets/events/queues implemented.
  • Real-world applications using gevent; future development plans.

If you have any suggestions regarding the contents of the talk, please post a comment or email me.

Categories: Advocacy Tags:

Google Summer of Code

March 16, 2010 Comments off

Are you a student? Want to contribute to an Open Source project and get paid for that? Apply to Google Summer of Code 2010 to work on gevent.

The Stackless Python’s ideas page for GSoC 2010 includes a gevent-related project.

The proposed idea is to enhance gevent’s core to

  1. support Stackless Python in addition to greenlet
  2. support non-libevent event loops

Stackless Python is an enhanced version of Python with microthreads built-in as well as other interesting features, like microthread pickling and thread-safe channels. The core function is similar to greenlet, which is a switching functionality from Stackless packaged as CPython extension. Other features of Stackless are not present in greenlet which is why it is desirable to port gevent to Stackless.

There are open source implementations of synchronous I/O for Stackless but they are not as comprehensive as gevent’s, which implements a compatible subset of the standard library and provides a way to patch the blocking functions in place.

Successfully undertaking this project would require deep understanding of Stackless API and gevent internals as well as having a good sense of design to keep things simple while making them more general.

Read the project description on the stackless website.

Feel free to ask about this project on the gevent mailing list.

Categories: Uncategorized

Comparing gevent to eventlet

February 27, 2010 5 comments

In this post I try to explain why gevent was started and how it is compares to eventlet.

Note: gevent has switched to libev.

History

Bob Ippolito wrote the first version of Eventlet in 2006 but ceased working on it fairly early. Donovan Preston took over the maintenance, together with other folks at Linden Lab where he worked at the time. I became interested in Eventlet in 2008, when I was looking for simpler ways to write networking software than with state machines and callbacks. Greenlet-based Eventlet was ahead of the other options that existed at the time (Python’s native generators, raw greenlet, Corotwine) in terms of features and easiness of use.

The project I worked on already depended on Twisted, so I started integrating the two libraries together. In the process of doing that I discovered a number of bugs in Eventlet and ended up rewriting most of its core. My branch was accepted as the way forward and finally released in 2009 as Eventlet 0.8.11. By that time Donovan had already left Linden Lab and Ryan Williams became the primary maintainer.

In the summer of 2009, I have started a new project where a networking library was going to be a major component. However, Eventlet did not meet a couple of requirements:

  • I needed it to use libevent’s event loop because I had another library (written in C) that used it and I wanted to integrate them together in a single process. Eventlet at the time did not have a working libevent support.
  • I needed socket module to work perfectly as I planned to use Python libraries implemented on top of it through monkey-patching. At the time Eventlet had a few bugs that could cause a socket operation to hang.

I have spent some time working on the pyevent-based hub. The result was not very compatible with the rest of Eventlet due to the fact that its Hub API is geared towards pure Python event loops. Making it work smoothly would require significant changes in the interface and implementation of every other hub. The socket module bugs were also specific to event loop, so even though I fixed them for pyevent, they were still present in every other hub. Not having time for a major rewrite of Eventlet I started a leaner project.

Gevent started as Eventlet with a few bugs fixed and a few features dropped.

The differences

1. gevent is built on top of libevent

Update: since 1.0, gevent uses libev and c-ares.

Libevent is a popular portable event loop. It runs your app using the fastest mechanism available on your system, such as epoll on Linux, and kqueue on FreeBSD. Unlike Eventlet, which maintains its own event loops in pure Python and has only recently gained epoll support, all of gevent’s event loops have been well-tested in real-world, high-scale environments.

The superior performance is one of the benefits of tight integration with libevent, but not the only one. Other benefits are

  • Signal handling is integrated with the event loop.
  • Other libevent-based libraries can integrate with your app through single event loop.
  • DNS requests are resolved asynchronously rather than via a threadpool of blocking calls.
  • WSGI server is based on the libevent’s built-in HTTP server, making it super fast.

2. gevent’s interface follows the conventions set by the standard library

For example, gevent.event.Event has the same interface and the same semantics as threading.Event and multiprocessing.Event but works across greenlets. Eventlet has Event class too, but it uses its own way of doing things for no good reason.

I’ve used the standard interfaces in gevent unless a brand new interface has an obvious advantage. In some cases, where re-implementing the whole class wasn’t necessary, the conventions on the method names set by the standard library were followed.

Here are some of those conventions:

  • wait() does not raise an exception;
  • get() can raise an exception or return a value;
  • join() is like wait(), but for units of execution.

Having consistent interface improves the speed at which we can read and reason about the code. Learning the API becomes easier as well.

Not being constrained by backward compatibility, gevent fixed all the API quirks that Eventlet had. The quality of the API is recognized by the users and Eventlet maintainers. Portions of gevent that are not specific to libevent are being incorporated into Eventlet.

3. gevent is not eventlet

It does not have all the features that Eventlet has. If you already use Eventlet these are the reasons why you might not be able to switch to gevent:

  • If you depend on eventlet.db_pool; gevent doesn’t have a module like that.
  • If you depend on eventlet.processes; there’s no support for subprocesses in the library yet. Here’s an example how to build it yourself.
  • If you depend on Eventlet’s threadpool; gevent does have one currently. Update: there’s a new gevent.threadpool module.
  • If you run Eventlet on Twisted reactor.
  • If you cannot depend on libevent.

Gevent aims to be a small and stable core everyone can depend upon. It delegates the job to libevent whenever possible and provides convenient abstractions for coroutine-based programming. It’s inspired by Eventlet but it’s not a fork and it features a new API. The implementation is simpler and more stable.

Read why others are choosing gevent and what you might encounter when porting from eventlet to gevent.

Thanks to Marcus Cavanaugh, Brad Clements, Nicholas Piël, Andrey Popp and Bob Van Zant for reading drafts of this.

Japanese Translation

Categories: Advocacy Tags: , , ,

gevent 0.12.1 released

February 26, 2010 Comments off

Update 2/Mar: Version 0.12.2 is released.

This release improves compatibility of gevent.socket with the standard socket a little bit more and fixes some of the installation issues that people reported on the mailing list.

Read the full changelog and download the package.

Thank you for participating in the discussion, reporting the problems and suggesting the remedies!

Categories: Announcement Tags:

gevent 0.12.0 is released

February 5, 2010 Comments off

Version 0.12.0 of gevent has been released on PyPI. Install it with

easy_install -U gevent

  • The major new feature is a gevent.ssl module, that provides cooperative implementation of the standard ssl module. It does not require any additional extensions on Python ≥ 2.6. It also works on 2.4 and 2.5 if ssl package is installed. The old, PyOpenSSL-based implementation of SSL objects is still available, but the new version is the preferred way now.
  • The library now compiles and passes most of the relevant tests on Windows. It’s still has a few rough edges (e.g. Ctrl-C is not working), so it should be considered experimental.
  • The socket object gained some performance improvements as well as a number of bugfixes.
  • Several incompatibilities of wsgi module with the WSGI spec have been fixed.

Read the details in the changelog.

Categories: Announcement Tags: ,

Preview for release 0.12.0 is available

January 22, 2010 Comments off

UPDATE 5/Feb: The final version has been released.

UPDATE 29/Jan: Second preview is available. Read the announcement here.

Version 0.12.0 is about to be released.

Get it on the bitbucket downloads page.

Here some of that notable changes:

  • Added gevent.ssl module.
  • Fixed Windows compatibility.
  • Improved performance of socket.recv(), socket.send() and similar methods.
  • Added a new module – dns – with synchronous wrappers around libevent’s DNS API.
  • Added core.readwrite_event and socket.wait_readwrite() functions.
  • Fixed a number of incompatibilities of wsgi module with the WSGI spec.

For the details refer to the changelog.

Please try it out and let me know if there are any issues. I’ll make a release in the middle of the next week if there are none.

Categories: Announcement Tags: ,

gevent 0.11.2 is released

December 10, 2009 Comments off

This is a bugfix release.

Changelog

Download page

Categories: Announcement Tags: ,

More comet with gevent

December 5, 2009 Comments off

Check out http://rss.im/stream/

This is my response to Superfeedr competition. It’s a gevent/django webapp that reads an Atom stream provided by Superfeedr, converts the entries to JSON and broadcasts them to a number of long polling listeners, similar to the long polling chat example I posted before.

On the client side, to make the stream digestible by humans, scrolling is avoided altogether and the pace of the stream is controlled by hovering mouse over the entries.

The source code: http://bitbucket.org/denis/stream-web/

Categories: Example Tags: , , ,

gevent 0.11.1 is released

November 15, 2009 Comments off

Thanks to Ludvig Ericson for the fixes! See the changelog for details. Get it on PyPI.

Categories: Announcement Tags: ,

Simpler long polling with Django and gevent

October 10, 2009 4 comments

Recently released Tornado web server includes an example chat application. This post describes a modification of that example that runs on Django and gevent wsgi server. The modified version achieves the same goal while staying within a familiar web framework Django and using simpler concurrency model.

It implements a simple web chat room with instant notifications and does so by using Ajax with long polling. A dynamic web application of this kind is thought of as a better fit for an asynchronous framework like Tornado or Twisted, than for a traditional thread-pool and/or process-pool based approach like apache+mod_wsgi. This is because each user participating in the chat (or simply not closing their browser window) maintains an open connection with the server for message updates and the amount of memory an open connection takes on server is significantly different depending on the server setup: a few KB for async versus a few MB for thread/process.

However, using an asynchronous framework requires twisting your code somewhat: because it’s all running in the same thread, you cannot simply wait in a view handler until a new message is available, then construct a response and return it to the framework. Instead, you usually return a callback that will be called when a new message is posted to generate the response and thus complete the long polling request. Not a huge obstacle but it does obscure the code flow.

If only we had more light-weight units of execution than threads and processes, implementing ajax apps like this chat would be a lot simpler. Turns out we do, and there are options: Stackless Python and greenlet. The latter is an extension module that runs on the stock Python and that’s what gevent currently supports.

The wsgi server bundled with gevent creates a new greenlet for each incoming connection making it’s possible in a request handler to sleep, wait for event and even access network without blocking anyone. Greenlets are cheap, memory-wise, so it’s about as scalable as callback- or Deferred- based solution. The logic, however, becomes much more transparent:

  • When a new message is posted, set the event.
  • When a client requests the updates (and it already has the latest message), wait for the event.

The code: views.py