Queue(None).full()
returns False
now (previously it returned True
).__copy__
method to gevent.local.local
class that implements copy semantics compatible with built-in threading.local
. Patch by Galfy Pundee.StreamServer
class to catch EWOULDBLOCK
rather than EAGAIN
. This fixes lots of spurious tracebacks on Windows where these two constants are not the same. Patch by Alexey Borzenkov.fork()
now calls event_reinit
only in the child process; otherwise the process could hang when using libevent2. Patch by Alexander Boudkar.TypeError
that occurred when environ["wsgi.input"].read
function was called with an integer argument.monkey.patch_thread()
now patches threading
too, even if it’s already imported. Patch by Shaun Lindsay.joinall()
and killall()
functions used to hang if their argument contained duplicate greenlets.pywsgi.WSGIServer
reported “Connection reset by peer” if the client did not close the connection gracefully after the last request. Such errors are now ignored.wsgi.WSGIServer
add REQUEST_URI
to environ. Patch by Andreas Blixt.httplib
with gevent.httplib
used to break HTTPSConnection
. Patch by Nick Barkas.create_connection
now raises proper exception when getaddrinfo
fails.BaseServer.__repr__()
method, BaseServer.server_host
and BaseServer.server_port
attributes to handle the case of AF_UNIX
addresses properly. Previously they assumed address is always a tuple.pywsgi.WSGIServer
to handle AF_UNIX
listeners. The server now sets environ["SERVER_NAME"]
and environ["SERVER_PORT"]
to empty string in such case.StreamServer
(and thus pywsgi.WSGIServer
) accept up to 100 connections per one readiness notification. This behaviour is controlled by StreamServer.max_accept
class attribute.gevent.httplib
that rendered it unusable.getaddrinfo
by calling resolve_ipv4
and resolve_ipv6
concurrently rather than sequentially in AF_UNSPEC
case.gevent.httplib
– experimental support for libevent-http client (issue #9). Thanks to Tommie Gannert, Örjan Persson.gevent.wsgi
with libevent2 (issue #62).pywsgi
not to use chunked transfer encoding in case of 304 and 204 responses as it creates a non-empty message body which is against RFC and causes some browsers to fail. Patch by Nicholas Piël.socket.getaddrinfo()
to handle AF_UNSPEC
properly and resolve service names (issue #56). Thanks to Elizabeth Jennifer Myers.socket.getaddrinfo()
to handle international domain names.sys.exc_info
set. Leaking is prevented by not preserving traceback at all and only keeping the value of the exception. Thanks to Ned Rockson.ssl.SSLSocket.unwrap()
to shutdown SSLSocket
properly, without raising SSLError(read operation timeout)
.TypeError
inside Hub
on Python 2.4.gevent.pywsgi
to make subclassing easier.WSGIServer
to explicitly close the socket after the last request. Patch by Ralf Schmitt.pywsgi.WSGIHandler
not to add CONTENT_TYPE
to the environ dict when there’s no Content-Type
header in the request. Previously a default text/plain
was added in such case.imap_unordered
to Pool
class. Unlike previous “dummy” implementation this one starts yielding the results as soon as they are ready.Queue
. The main use case is the implementation of Pool.imap_unordered()
.BaseServer.started
property: it is now set to True
after start
until stop
or kill
. Previously it could become False
for short period of times, because StreamServer
could stop accepting for a while in presence of errors and StreamServer.started
was defined as “whether the server is currently accepting”.wsgi.WSGIServer
to reply with 500 error immediately if the application raises an error (issue #58). Thanks to Jon Aslund.monkey.patch_httplib()
function which is disabled by default.monkey.patch_all()
(defaults to False
).write
method to core.buffer
.OverflowError
that could happen in core.event.__str__()
.http_request.get_input_headers()
return header names in lower case.StreamServer
to accept ciphers as an SSL argument.build_exc --cython=
option to setup.py
. Patch by Ralf Schmitt.local
to raise AttributeError
if __dict__
attribute is set or deleted.Release highlights:
monkey
to patch socket.create_connection
.gevent.ssl
module to fully match the functionality of ssl
on Python 2.7.Group.join()
to handle raise_error=True
properly, it used to raise TypeError
(issue #36). Thanks to by David Hain.gevent.wsgi
and gevent.pywsgi
to join multiple Cookie
headers (issue #40).select
to recognize long
arguments in addition to int
.Semaphore.acquire()
to return False
when timeout expires instead of raising AssertionError
(issue #39). Patch by Erik Näslund.JoinableQueue.join()
to return immediately if queue is already empty (issue #45). Patch by Dmitry Chechik.gevent.sslold
module.gevent.socket
module:
socket.shutdown()
method to interrupt read/write operations on socket.NameError
in socket.connect_ex()
method. Patch by Alexey Borzenkov.create_connection()
function.gevent.socket
import all public items from stdlib socket
that do not do I/O.gevent.ssl
module:
makefile()
method on an SSL object would prevent the underlying socket from being closed until all objects get truly destroyed (Python issue #5238).getpeername()
in SSLSocket.__init__
, only silence exceptions caused by the “socket not connected” condition.SSLSocket.send
and SSLSocket.recv
methods to match the behavior of stdlib ssl
better.ssl.SSLObject
to delete events used by other greenlets when closing the instance (issue #34).Miscellaneous:
BaseServer
accept long
values as pool argument in addition to int
.http._requests
attribute public.OperationalError
.webproxy.py
example to be runnable under external WSGI server.test__exc_info.py
.xtest_pep8.py
.BackdoorServer
close the connection on SystemExit
and simplified the code.Pool
raise ValueError
when initialized with size=0
.setup.py --libevent
to configure and make libevent if it’s not built already.setup.py
to use setuptools
if present and add dependency on greenlet
.Release highlights:
gevent.server
module with StreamServer
class for easy implementing of TCP and SSL servers.gevent.baseserver
module with BaseServer
class.gevent.pywsgi
based on gevent.server
. Contributed by Ralf Schmitt.gevent.local
module. Fixed issue #24. Thanks to Ted Suzman.gevent.wsgi
module.exc_info
.socket.sendall()
to use buffer object to prevent string copies.gevent.wsgi
and gevent.pywsgi
much more similar to each other.Backward-incompatible changes:
Greenlet.kill()
method and other kill* methods.http.HTTPServer
to match the interface of other servers.Pool
’s spawn()
method to block until there’s a free slot.backdoor.backdoor_server()
function.socket
module:socket_bind_and_listen()
set_reuse_addr()
connect_tcp()
tcp_server()
socket.fd
property.core.event.add()
and socket.wait_read()
and similar. Use None
from now on, which is compatible with the previous versions.backdoor.BackdoorServer
from StreamServer
rather than from Greenlet
. This adds lots of new features and removes a few old ones.balance
property from Semaphore
.start()
, set_cb()
and set_gencb()
from core.http
.set_closecb()
from core.http_connection
. It is now used internally to detach the requests of the closed connections.rawgreenlet
module.util.lazy_property()
.GreenletSet
to Group
. The old name is currently available as an alias.gevent.socket
module:
getfqdn()
from socket
module.sys.platform
to detect Windows rather than platform
module.getaddrinfo()
used to handle the case when socktype or proto were equal to 0
. Thanks to Randall Leeds.gevent.coros
module:
RLock
class.DummySemaphore
class.BoundedSemaphore
class to behave like threading.BoundedSemaphore
behaves.gevent.event
module:
Event.wait()
return internal flag instead of None
.AsyncResult.wait()
return its value
instead of None
.ready()
method as an alias for is_set()
.gevent.wsgi
module:
wsgi.buffer_proxy
.gevent.pywsgi
module:
server
and not to depend on BaseHTTPServer
.wsgi
module.
Removed server()
function, add Server
class, added WSGIServer
class.HttpProtocol
to WSGIHandler
.readline()
.gevent.core
module:
event
class.read_event
, write_event
and readwrite_event
.flags_str
property to event
. It is used by __str__
and __repr__
.buffer
:detach()
method.readline()
and readlines()
methods.http_request
:detach()
to detach input and output buffers too.input_buffer
and output_buffer
store and reuse the buffer
object they create.__str__()
and meth:__repr__
to include spaces where needed.http
class no longer has set_cb()
and set_gencb()
. Instead its contructor accepts handle which will be called on each request.gevent.http
and gevent.wsgi
modules:
HTTPServer
use "Connection: close"
header by default.HTTPServer
now derives from baseserver.BaseServer
. Thus its start()
method no longer accepts socket to listen on, it must be passed to the contructor.Pool
instance. While the pool is full, the server replies with 503 error.http_request
which will send 500 reply when deallocated if the user hasn’t send any.Miscellaneous:
gevent.thread
to use Greenlet
instead of raw greenlets. This means monkey patched thread will become Greenlet
too.started
property to Greenlet
.gevent.baseserver
module. All servers in gevent package are now derived from BaseServer
.sleep()
now raises IOError
if passed a negative argument.USE_LIBEVENT_?
is no longer needed to build gevent.core
.backdoor
when a client typed quit()
.greenlet
failed with ImportError, keep the original error message,
because sometimes the error originates in setuptools.select.select()
to return all the file descriptors signalled, not just the first one.thread
(and thus monkey patched threads) to spawn Greenlet
instances, rather than raw greenlets.Examples:
StreamServer
.Thanks to Ralf Schmitt for pywsgi
, a number of fixes for wsgi
, help with
baseserver
and server
modules, improving setup.py and various other patches and suggestions.
Thanks to Uriel Katz for pywsgi
patches.
build/lib.../gevent/core.so
to gevent/core.so
.gevent.socket
: Improved compatibility with stdlib’s socket:socket
to raise timeout("timed out")
rather than simply timeout
._GLOBAL_DEFAULT_TIMEOUT
from standard socket
module instead of creating a new object.Release highlights:
gevent.ssl
module.socket.recv()
, socket.send()
and similar methods.dns
- with synchronous wrappers around libevent’s DNS API.core.readwrite_event
and socket.wait_readwrite()
functions.wsgi
module with the WSGI spec.pywsgi
module.gevent.wsgi
module:
env["REMOTE_PORT"]
into a string.wsgi.input
object iterable.gevent.core
module:
IOError
if they failed.core.dns_err_to_string()
.gevent.socket
module:
gethostbyname()
and getaddrinfo()
to call the stdlib if the passed hostname has no dots.getaddrinfo()
to filter the results using socktype and proto arguments.getnameinfo()
as it didn’t quite match the stdlib interface.
Use dns.resolve_reverse()
for reverse resolutions.socket.connect_ex()
to use cooperative gethostbyname()
.socket.dup()
not to call underlying socket’s dup()
(which is not available
on Windows) but to use Python’s reference counting similar to how the stdlib’s socket
implements dup()
socket
’s constructor. Passing the socket instance
as first argument is no longer supported.socket.connect()
to ignore WSAEINVAL
on Windows.socket.connect()
to use wait_readwrite()
instead of wait_write()
.socket.connect()
to consult SO_ERROR
.socket.send()
and socket.sendall()
to support flags argument.socket_bind_and_listen()
to socket.bind_and_listen()
. The old name
is still available as a deprecated alias._sock
property.socket
into gevent.socket
.
(Thanks to Matt Goodall for the original patch).wrap_ssl()
to ssl()
. (the old name is still available but deprecated)connect_tcp()
and tcp_server()
.sslerror
to socket.__all__
.GreenSocket
alias for socket class.socket.ssl()
into gevent.oldssl
module.
It’s imported into gevent.socket
if importing gevent.ssl
fails.Miscellaneous:
select
to clean up properly if event creation fails.select
to raise select.error
instead of IOError
.select.select()
to what they are called in the stdlib.getLinkedCompleted()
from gevent.greenlet
.#warning
directives from libevent.h
. They are not supported by vc90.coros
.Waiter
now stores the value if no one’s waiting for it.testrunner.py
script that replaces a bunch of small scripts that were used before.is_secure
attribute from sockets and ssl objects.Greenlet
not to print a traceback when a not-yet-started greenlet is killed.BackdoorServer
class to backdoor
. Removed backdoor()
function and deprecated backdoor_server()
function.__getattr__
from socket class.monkey.patch_socket()
not to fail if socket.ssl()
is not present in gevent.socket
.monkey.patch_ssl()
.monkey.patch_all()
.test
package directly and run them in monkey patched environment.wsgi
to unquote environ['PATH_INFO']
before passing to application.SERVER_SOFTWARE
variable to wsgi
environ.JoinableQueue.task_done()
that caused ValueError
to be raised incorrectly here.gevent.socket
not to fail with ImportError
if Python was not built with ssl support.select.select()
function. Passing non-empty list of write descriptors used to cause this function to fail.Contributed by Ludvig Ericson:
wsgi
’s start_response
to recognize exc_info argument.joinall()
, Greenlet.join()
, pool.Pool.join()
: if timeout has expired
it used to raise Timeout
; now it returns silently.signal()
to run the signal handler in a new greenlet; it was run in the Hub
greenlet before.Timeout.start_new()
: if passed a Timeout
instance, it now calls its start
method before returning it.gevent.monkey
to patch threading.local
properly.Queue.empty()
and Queue.full()
to be compatible
with the standard Queue
. It tried to take into account the greenlets currently blocking on
get
/put
which
was not useful and hard to reason about. Now it simply compares qsize
to maxsize,
which what the standard Queue
does too.Event
to behave exactly like the standard threading.Event
:Event.set()
does not accept a parameter anymore; it’s now either set or not.Event.get
method is gone.Event.set(); Event.clear()
used to be a no-op; now it properly wakes up all the waiters.AsyncResult
behaves exactly like before, but it does not inherit from Event
anymore
and does miss clear()
method.socket.wait_reader()
/socket.wait_writer()
to socket.wait_read()
/socket.wait_write()
.gevent.socket.GreenSocket
to gevent.socket.socket
. GreenSocket
is still available
as an alias but will be removed in the future.gevent.core
now includes wrappers for evbuffer, evdns, evhttp.gevent.wsgi
to gevent.pywsgi
.gevent.http
module based on libevent-http wrappers.gevent.wsgi
module based on gevent.http
.gevent.core
and DNS functions to gevent.socket
module. Contributed by Jason Toffaletti..setup.py
to select a libevent library to compile against. Check them out with setup.py -h
.__all__
to many modules that missed it.Changed Timeout
API in a backward-incompatible way:
Timeout.__init__()
does not start the timer immediately anymore;
Timeout.start()
must be called explicitly.
A shortcut - Timeout.start_new()
- is provided that creates and starts
a Timeout
.
Added gevent.Greenlet
class which is a subclass of greenlet that adds a few
useful methods join
/get
/kill
/link
.
spawn()
now returns Greenlet
instance. The old spawn
, which returns py.magic.greenlet
instance, can be still accessed as spawn_raw()
.
Note
The implementation of Greenlet
is an improvement on proc
module, with these bugs fixed:
getcurrent()
useless and using
Procs as keys in dict impossible.Greenlet
executes each link in a new greenlet by default, unless
it is set up with Greenlet.rawlink
method.Greenlet
, override its _run
and __init__ methods.Added pool.Pool
class with the methods compatible to the standard multiprocessing.pool
:
apply
, map
and others.
It also has spawn
method which is always async and returns a
Greenlet
instance.
Added gevent.event
module with 2 classes: Event
and AsyncResult
.
Event
is a drop-in replacement for threading.Event
, supporting
set
/wait
/get
methods. AsyncResult
is an extension of Event
that supports exception passing via set_exception
method.
Added queue.JoinableQueue
class with task_done
and join
methods.
Renamed core.read
and core.write
classes to core.read_event
and core.write_event
.
gevent.pywsgi
: pulled Mike Barton’s eventlet patches that fix double content-length issue.
Fixed setup.py
to search more places for system libevent installation.
This fixes 64bit CentOS 5.3 installation issues, hopefully covers other platforms
as well.
The following items were added to the gevent top level package:
spawn_link()
spawn_link_value()
spawn_link_exception()
spawn_raw()
joinall()
killall()
Greenlet
GreenletExit
core
The following items were marked as deprecated:
wrap_errors
helper was moved to util
module)Internally, gevent.greenlet
was split into a number of modules:
gevent.hub
provides Hub
class and basic utilities, like sleep()
;
Hub
is now a subclass of greenlet.gevent.timeout
provides Timeout
and with_timeout()
;gevent.greenlet
provides Greenlet
class and helpers like joinall()
and killall()
.gevent.rawgreenlet
contains the old “polling” versions of
joinall
and killall
(they do not need link
functionality and work with any greenlet by polling their status and sleeping in a loop)Thanks to Jason Toffaletti for reporting the installation issue and providing a test case for WSGI double content-length header bug.
gevent.queue
module and made it 2.4-compatible.
LifoQueue
and PriorityQueue
are implemented as well.
gevent.queue
will deprecate both coros.Queue
and coros.Channel
.Timeout
to raise itself by default. TimeoutError
is gone.
Silent timeout is now created by passing False
instead of None
.gevent.select.select()
where it could silent the wrong timeout.spawn()
and spawn_later()
now avoid creating a closure and this decreases spawning
time by 50%.kill
’s and killall
’s wait argument was renamed to block. The polling is now
implemented by greenlet.join
and greenlet.joinall
functions and it become more
responsive, with gradual increase of sleep time.proc.RunningProcSet
to proc.ProcSet
.shutdown()
function, which blocks until libevent has finished dispatching the events.event_add
and event_del
in core.pyx are now checked properly
and IOError
is raised if they have failed.gevent.socket
’s implementation and fixed SSL bug reported on eventletdev
by Cesar Alaniz as well as failures in test_socket_ssl.py
.GreenSocket.makeGreenFile
; Use socket.socket.makefile()
that returns _fileobject
and is available on both GreenSocket
and GreenSSL
.
The gevent.socket
is still a work in progress.core.active_event
class that takes advantage of libevent’s event_active
function.
core.active_event(func)
schedules func to be run in this event loop iteration as opposed
to core.timer(0, ...)
which schedules an event to be run in the next iteration.
active_event
is now used throughout the library wherever core.timer(0, ....)
was previously used.
This results in spawn()
being at least 20% faster compared to release 0.9.1 and twice as fast compared to
eventlet. (The results are obtained with bench_spawn.py script in greentest/
directory)kill()
and killall()
functions. If set to True
, it makes the
function block until the greenlet(s) is actually dead. By default, kill()
and killall()
are asynchronous,
i.e. they don’t unschedule the current greenlet.gevent.core.event
: fd
, events
,
events_str
and flags
. It also has __enter__
and __exit__
now, so it can be used as a context
manager. event
’s callback
signature has changed from (event, fd, evtype)
to (event, evtype)
.Hub
’s mainloop to never return successfully as this will screw up main greenlet’s switch()
call.
Instead of returning it raises DispatchExit
.reinit()
function - wrapper for libevent’s event_reinit
.
This function is a must have at least for daemons, as it fixes epoll
and some others eventloops to work after fork
.spawn_link[exception/value]
to proc.RunningProcSet
.setup.py
not to depend on setuptools
.gevent.timeout
. Use gevent.Timeout
.Hub
to recover silently after event_dispatch()
failures (I’ve seen this
happen after fork
even though event_reinit()
is called as necessary). The end result is that fork()
now works more reliably, as detected by test_socketserver.py
- it used to fail occasionally, now it does not.gevent/__init__.py
was moved to gevent/greenlet.py
.
gevent/__init__.py
imports some of it back but not everything.gevent.timeout
to gevent.Timeout
. The old name is available as an alias.queue.Queue
.
Added test_queue.py from standard tests to check how good is queue.Queue
a replacement
for a standard Queue
(not good at all, timeouts in queue.Queue.put()
don’t work yet)monkey
now patches ssl module when on 2.6 (very limited support).GreenSocket
now wraps a socket
object from _socket
module rather
than from socket
.Started as eventlet 0.8.11 fork, with the intention to support only libevent as a backend. Compared to eventlet, this version has a much simpler API and implementation and a few severe bugs fixed, namely
read()
and write()
on the same fd do not cancel one another.GreenSocket.close
method does not hang as it could with eventlet.There’s a test in my repo of eventlet that reproduces both of them: http://bitbucket.org/denis/eventlet/src/tip/greentest/test__socket.py
Besides having less bugs and less code to care about the goals of the fork are: