durusmail: quixote-users: eventlet
eventlet
2010-11-30
2010-12-01
2011-01-24
eventlet
Salman Haq
2011-01-24
On 12/01/2010 03:41 AM, Robert Ladyman wrote:
>> I was thinking of writing an eventlet server for Quixote so it can
>> handle requests that block or require heavy computation more
>> efficiently. Has anyone already tried to this or foresee any issues?
>>
>> I realize that there is Twisted server for Quixote as well (which I am
>> currently using in one of my projects) but Twisted's "deferred
>> generator" doesn't play well with Quixote.
>>
>> Thanks,
>> Salman
> I would watch out for session management - some of the storage methods are not
> thread-safe.
>
After wrestling with that thought for a while, I've come to the
conclusion that it may be a non-issue since eventlet uses co-routines
rather than actual threads (although it is certainly possible to use
real threads too).

That said, here are the two things that I needed to implement to run my
site using eventlet's event loop.


eventlet_server.py
---
import eventlet
from eventlet import wsgi
from quixote2.wsgi import QWIP

def run(create_publisher, host='', port=80):
     """ Wrap the publisher inside a QWIP instance and serve via
eventlet.wsgi
     """
     publisher = create_publisher()
     app = QWIP(publisher)
     logfd = open('/dev/null', 'w')
     wsgi.server(eventlet.listen((host, port)), app, logfd)

if __name__ == '__main__':
     from quixote2.server.util import main
     main(run)
---

eventlet_publisher.py
---
from quixote.publish import Publisher
import eventlet

class EventletPublisher (Publisher):
     """ Extends the quixote Publisher class so it can handle multiple http
     request objects simultaneously.

     Inspired from Quixote-2.6/doc/multi-threaded.txt
     """

     is_thread_safe = True

     def __init__ (self, root_directory, logger=None, session_manager=None,
                  config=None, **kwargs):
         Publisher.__init__(self, root_directory, logger, session_manager,
                            config, **kwargs)
         self._request_dict = {}

     def _set_request(self, request):
         self._request_dict[eventlet.greenlet.getcurrent()] = request

     def _clear_request(self):
         try:
             del self._request_dict[eventlet.greenlet.getcurrent()]
         except KeyError:
             pass

     def get_request(self):
         return self._request_dict.get(eventlet.greenlet.getcurrent())
---

Thanks,
Salman


reply