v0.20.0 release


Important backward incompatible changes:
- removed select.poll(). We never had green poll implementation. If you really need blocking poll, use patcher.original('select').
- DNS resolving is always green with dnspython bundled in. This is just a nice free improvement. Be alert only if you intentionally wanted blocking resolving.

Other goodies:
* greenio: only trampoline when we block
* convenience: listen() sets SO_REUSEPORT when available; Thanks to Zhengwei Gao
* ssl: Fix "TypeError: read() argument 2 must be read-write bytes-like object, not None"
* greenio: _recv_loop behaviour with recv_into on closed sock
* ipv6: getaddrinfo would fail with scope index
* green.zmq: Support {send,recv}_{string,json,pyobj} wrappers
* greendns: Return answers from /etc/hosts despite nameserver errors
* patcher: fixed green existing locks fail (Python3)
* Add DAGPool, a dependency-driven greenthread pool
* wsgi: Unix socket address representation; Thanks to Samuel Merritt
* tpool: isolate internal socket from default timeout; Thanks to Alex Villacís Lasso
* wsgi: only skip Content-Type and Content-Length headers (GH-327)
* wsgi: 400 on blank Content-Length headers (GH-334)
* greenio: makefile related pypy socket ref counting
* ssl: Fix recv_into blocking when reading chunks of data
* websocket: support Gunicorn environ['gunicorn.socket']

Our website: http://eventlet.net/

Try latest version with `pip install -U eventlet`

Post has attachment
v0.18.3 release

The most scandal Eventlet release so far: https://pypi.python.org/pypi/eventlet/0.18.3

Important note: do not use versions 0.18.0 and 0.18.1, they contain known bug in wsgi on Python3.

0.18 line features Python3 compatible green.OpenSSL.

Now important backward incompatible changes:
- socket.send() will return fast, it no longer attempts to retry like sendall() which makes it consistent with Python standard library and removes a source of very subtle errors.
- monkey patching removes things from `select` module, that we could not make green. This includes `select.poll()`, epoll, kqueue, etc. See full list here http://eventlet.net/doc/changelog.html the motivation here is that we want to prevent you from accidentally blocking whole process, while thinking it should all work together.

Other goodies:
- greenio: Fixed a bug that could cause send() to start an endless loop on ENOTCONN; Thanks to Seyeong Kim
- wsgi: Fixed UNIX socket address being trimmed in “wsgi starting” log; Thanks to Ihar Hrachyshka
- subprocess: Fixed missing subprocess.mswindows attribute on Python 3.5; Thanks to Josh VanderLinden
- ssl/monkey patching: Fixed a bug that would cause merely importing eventlet to monkey patch the ssl module; Thanks to David Szotten
- wsgi: Made the error raised in case of chunk read failures more precise (this should be backwards compatible as the new exception class, wsgi.ChunkReadError, is a subclass of ValueError which was being used there before); Thanks to Samuel Merritt
- greenio: Fixed socket.recv() sometimes returning str instead of bytes on Python 3; Thanks to Janusz Harkot
- websocket: Fixed TypeError on empty websocket message (Python 3); Thanks to Fukuchi Daisuke
- greenio: Fixed handling blocking IO errors in various GreenSocket methods; Thanks to Victor Stinner
- greenio: Fixed GreenPipe ignoring the bufsize parameter on Python 2; Thanks to Phus Lu
- greenio: Made read() support buflen=-1 and added readall() (Python 3); Thanks to David Szotten
- wsgi: Improved request body discarding
- subprocess: Fixed universal_newlines support
- wsgi: Output of 0-byte chunks is now suppressed; Thanks to Samuel Merritt
Improved the documentation; Thanks to Ramakrishnan G, ashutosh-mishra and Azhar Hussain
- greenio: Changed GreenFileIO.write() (Python 3) to always write all data to match the behavior on Python 2; Thanks to Victor Stinner
documentation: Added support for building plain text documentation; thanks to Levente Polyak
- backdoor: Added Unix and IPv6 socket support; Thanks to Eric Urban

Post has attachment
I am a new eventlet user and had a query, regarding using eventlet in something similar to a dispatch pattern. Can someone help me out?



I have an issue when I use eventlet Api to create parallel threads.
In fact, when I run the below code, only the program dealing with the synchronozation with ldap data base is working and is continuously blocking the others to run.
But, when I use the 'thread' Api the program is working fine without any blocking issue. However, I can not use thread Api and I must to use eventlet.
So I am wondering how to get the thread Api behavior using the eventlet Api ?

Could you please inform me how to fix this issue ?

Kindly find below my code.
But you need some configurations regarding ldap server/client.

# -*- coding: utf-8 -*-
This script implements a syncrepl consumer which syncs data from an OpenLDAP
server to a local (shelve) database.
The bound user needs read access to the attributes entryDN and entryCSN.
This needs the following software:
pyasn1 0.1.4+
python-ldap 2.4.10+

# Import the python-ldap modules
import ldap,ldapurl
# Import specific classes from python-ldap
from ldap.ldapobject import ReconnectLDAPObject
from ldap.syncrepl import SyncreplConsumer

# Import modules from Python standard lib
import shelve,signal,time,sys,logging
import eventlet
#import thread

# Global state
watcher_running = True
ldap_connection = False

class SyncReplConsumer(ReconnectLDAPObject,SyncreplConsumer):
    Syncrepl Consumer interface
    def _init_(self,db_path,*args,**kwargs):
        # Initialise the LDAP Connection first
        ldap.ldapobject.ReconnectLDAPObject.__init__(self, *args, **kwargs)
        # Now prepare the data store
        self.__data = shelve.open(db_path, 'c')
        # We need this for later internal use
        self.__presentUUIDs = dict()

    def _del_(self):
            # Close the data store properly to avoid corruption

    def syncrepl_get_cookie(self):
        if 'cookie' in self.__data:
            return self.__data['cookie']

    def syncrepl_set_cookie(self,cookie):
        self.__data['cookie'] = cookie

    def syncrepl_entry(self,dn,attributes,uuid):

        # First we determine the type of change we have here (and store away the previous data for later if needed)
        previous_attributes = dict()
        if uuid in self.__data:
            change_type = 'modify'
            previous_attributes = self.__data[uuid]
            change_type = 'add'
        # Now we store our knowledge of the existence of this entry (including the DN as an attribute for convenience)
        attributes['dn'] = dn
        self.__data[uuid] = attributes
        # Debugging
        print 'Detected', change_type, 'of entry:', dn
        # If we have a cookie then this is not our first time being run, so it must be a change
        if 'ldap_cookie' in self.__data:
                self.perform_application_sync(dn, attributes, previous_attributes)

    def syncrepl_delete(self,uuids):
        # Make sure we know about the UUID being deleted, just in case...
        uuids = [uuid for uuid in uuids if uuid in self.__data]
        # Delete all the UUID values we know of
        for uuid in uuids:
            print 'Detected deletion of entry:', self.__data[uuid]['dn']
            del self.__data[uuid]

    def syncrepl_present(self,uuids,refreshDeletes=False):
        # If we have not been given any UUID values, then we have recieved all the present controls...
        if uuids is None:
            # We only do things if refreshDeletes is false as the syncrepl extension will call syncrepl_delete instead when it detects a delete notice
            if refreshDeletes is False:
                deletedEntries = [uuid for uuid in self.__data.keys() if uuid not in self.__presentUUIDs and uuid != 'ldap_cookie']
                self.syncrepl_delete( deletedEntries )
            # Phase is now completed, reset the list
            self.__presentUUIDs = {}
            # Note down all the UUIDs we have been sent
            for uuid in uuids:
                    self.__presentUUIDs[uuid] = True

    def perform_application_sync(self,dn,attributes,previous_attributes):
        print 'Performing application sync for:', dn
        return True

# Shutdown handler
#def commenceShutdown(signum, stack):
def commenceShutdown():
    # Declare the needed global variables
    global watcher_running, ldap_connection
    print 'Shutting down!'

    # We are no longer running
    watcher_running = False

    # Tear down the server connection
    if( ldap_connection ):
            del ldap_connection

    # Shutdown

def mainOfSyncrepl(threadName):
     # Time to actually begin execution
     # Install our signal handlers
#     signal.signal(signal.SIGTERM,commenceShutdown)
#     signal.signal(signal.SIGINT,commenceShutdown)
       ldap_url = ldapurl.LDAPUrl('ldap://localhost/dc=example,dc=org??sub?(objectClass=)?bindname=cn=admin%2cdc=test%2cdc=com,X-BINDPW=myPassword')#ldapurl.LDAPUrl(sys.argv[1])
     #  ldap_url = ldapurl.LDAPUrl(link)
       database_path = 'test.com'#sys.argv[2]
     #  database_path = pathName
     except IndexError,e:
       print 'Usage: syncrepl-client.py <LDAP URL> <pathname of database>'
     except ValueError,e:
       print 'Error parsing command-line arguments:',str(e)

     while watcher_running:
         print 'Connecting to LDAP server now...'
         # Prepare the LDAP server connection (triggers the connection as well)
         ldap_connection = SyncReplConsumer(database_path,ldap_url.initializeUrl())

         # Now we login to the LDAP server
         except ldap.INVALID_CREDENTIALS, e:
             print 'Login to LDAP server failed: ', str(e)
         except ldap.SERVER_DOWN:

         # Commence the syncing
         print 'Commencing sync process'
         ldap_search = ldap_connection.syncrepl_search(
           ldap_url.dn or '',
           ldap_url.scope or ldap.SCOPE_SUBTREE,
           mode = 'refreshAndPersist',
           filterstr = ldap_url.filterstr or '(objectClass=*)')
         print 'After syncrepl_search.'
             while ldap_connection.syncrepl_poll( all = 1, msgid = ldap_search):
         except KeyboardInterrupt:
          # User asked to exit
         except Exception, e:
          # Handle any exception
             if watcher_running:
                 print 'Encountered a problem, going to retry. Error:', str(e)

# Define a function for the 2nd thread
def print_time(ThreadName):
     count = 0
     delay = 3
     while 1:#count < 5:
         count += 1
         print "%s: %s" % (ThreadName, time.ctime(time.time()) )

print 'Before call threads'

evt1 = eventlet.spawn(mainOfSyncrepl, "Thread-1",)
evt2 = eventlet.spawn(print_time, "Thread-2",)
evt3 = eventlet.spawn(print_time, "Thread-3",)

print 'After call threads'


print 'After wait'

Post has attachment
v0.17.4 release

First attempt at 2015-02-23, it's 4th bug fix release in 0.17 series. https://pypi.python.org/pypi/eventlet/0.17.4

Featuring full Python3 and IPv6 support! Thanks to everyone involved. I'm already using Python3 for all my new projects and glad to report another important library is available.

Also, Github https://github.com/eventlet/eventlet/ is now main official repository and Bitbucket is eventually consistent mirror.

* ssl: incorrect initalization of default context; Thanks to stuart-mclaren
* green.thread: Python3.3+ fixes; Thanks to Victor Stinner
* Semaphore.acquire() accepts timeout=-1; Thanks to Victor Stinner
* wsgi: Provide python logging compatibility; Thanks to Sean Dague
* greendns: fix premature connection closing in DNS proxy; Thanks to Tim Simmons
* greenio: correct fd close; Thanks to Antonio Cuni and Victor Sergeyev
* green.ssl: HTTPS client Python 2.7.9+ compatibility
* setup: tests.{isolated,manual} polluted top-level packages
* greendns: fix dns.name import and Python3 compatibility
* Full Python3 compatibility; Thanks to Jakub Stasiak
* greendns: IPv6 support, improved handling of /etc/hosts; Thanks to Floris Bruynooghe
* tpool: make sure we return results during killall; Thanks to David Szotten
* semaphore: Don't hog a semaphore if someone else is waiting for it; Thanks to Shaun Stanworth
* green.socket: create_connection() was wrapping all exceptions in socket.error; Thanks to Donagh McCabe
* Make sure SSL retries are done using the exact same data buffer; Thanks to Lior Neudorfer
* greenio: shutdown already closed sockets without error; Thanks to David Szotten

Our website: http://eventlet.net/ 
Direct package download links:

I am a new user of Eventlet. I faced a problem in using eventlet.green.httplib.HttpConnection. 
When I send a PUT request for a server, it blocks the second PUT request to the same server until the previous response is read. 

I think its the intended behaviour of the library but isn't it possible to do multiple requests at the same time to the same server?

Note: I faced this problem when I test Openstack-Swift which use this library to create BufferedHttpConnections to storage nodes.

Post has attachment
v0.16.1 release

Happy new year! You wanted it so bad. Please, welcome,

This release features Python 2.7.9 SSL compatibility and improved Python3 support (bleeding edge, not finished officially). Thanks to all contributors!

Also, we removed lots of deprecated unsupported code, including Twisted hub. This will allow us to focus on what's important and get there sooner. Next targets: Python3 and IPv6.

Important note if you already installed v0.16.0: please, take a minute and update your build to 0.16.1. Module eventlet.util was removed from source tree and tarball but still made it into wheel package by my mistake. You may have code that depends (but shouldn't) on this module and will work in some cases.

* Fix SSL socket wrapping and Python 2.7.9 compatibility; Thanks to Jakub Stasiak
* Fix monkey_patch() on Python 3; Thanks to Victor Stinner
* Fix "maximum recursion depth exceeded in GreenSocket.__del__"; Thanks to Jakub Stasiak
* db_pool: BaseConnectionPool.clear updates .current_size #139; Thanks to Andrey Gubarev
* Fix _str_ method on the TimeoutExpired exception class.; Thanks to Tomaz Muraus
* hubs: drop Twisted support
* Removed deprecated modules: api, most of coros, pool, proc, processes and util
* Improved Python 3 compatibility (including patch by raylu); Thanks to Jakub Stasiak
* Allow more graceful shutdown of wsgi server; Thanks to Stuart McLaren
* wsgi.input: Make send_hundred_continue_headers() a public API; Thanks to Tushar Gohad
* tpool: Windows compatibility, fix ResourceWarning. Thanks to Victor Stinner
* tests: Fix timers not cleaned up on MySQL test skips; Thanks to Corey Wright

Our website: http://eventlet.net/ 
Direct package download links:

I know how developers hate questions like this one, but nevertheless I must ask it: is there any estimated date for release of version 0.16? If I read the repo correctly, it fixes issue https://github.com/eventlet/eventlet/issues/137 , which affects our project.

Post has attachment
Hello! Is there any particular reason there is no single changelog for the project? The only one I found is https://github.com/JeremyGrosser/python-eventlet/blob/master/debian/changelog, which is not very helpful. It would be great to know if new versions introduce any breaking changes without having to go check the group.

v0.15.2 has just been released.

It fixes memory leak introduced in v0.15.1
Wait while more posts are being loaded