Added Daniele Varrazzo's green-psycopg2 patch. Untested in the case where the module is actually present, but verified that it's a no-op if not installed.
This commit is contained in:
@@ -136,7 +136,7 @@ def monkey_patch(**on):
|
||||
|
||||
It's safe to call monkey_patch multiple times.
|
||||
"""
|
||||
accepted_args = set(('os', 'select', 'socket', 'thread', 'time'))
|
||||
accepted_args = set(('os', 'select', 'socket', 'thread', 'time', 'psycopg'))
|
||||
default_on = on.pop("all",None)
|
||||
for k in on.iterkeys():
|
||||
if k not in accepted_args:
|
||||
@@ -167,6 +167,13 @@ def monkey_patch(**on):
|
||||
if on['time'] and not already_patched.get('time'):
|
||||
modules_to_patch += _green_time_modules()
|
||||
already_patched['time'] = True
|
||||
if on['psycopg'] and not already_patched.get('psycopg'):
|
||||
try:
|
||||
from eventlet.support import psycopg2_patcher
|
||||
psycopg2_patcher.make_psycopg_green()
|
||||
except ImportError:
|
||||
pass
|
||||
already_patched['psycopg'] = True
|
||||
|
||||
for name, mod in modules_to_patch:
|
||||
orig_mod = sys.modules.get(name)
|
||||
@@ -201,6 +208,7 @@ def _green_time_modules():
|
||||
from eventlet.green import time
|
||||
return [('time', time)]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.argv.pop(0)
|
||||
|
||||
53
eventlet/support/psycopg2_patcher.py
Normal file
53
eventlet/support/psycopg2_patcher.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""A wait callback to allow psycopg2 cooperation with eventlet.
|
||||
|
||||
Use `make_psycopg_green()` to enable eventlet support in Psycopg.
|
||||
"""
|
||||
|
||||
# Copyright (C) 2010 Daniele Varrazzo <daniele.varrazzo@gmail.com>
|
||||
# and licensed under the MIT license:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import psycopg2
|
||||
from psycopg2 import extensions
|
||||
|
||||
from eventlet.hubs import trampoline
|
||||
|
||||
def make_psycopg_green():
|
||||
"""Configure Psycopg to be used with eventlet in non-blocking way."""
|
||||
if not hasattr(extensions, 'set_wait_callback'):
|
||||
raise ImportError(
|
||||
"support for coroutines not available in this Psycopg version (%s)"
|
||||
% psycopg2.__version__)
|
||||
|
||||
extensions.set_wait_callback(eventlet_wait_callback)
|
||||
|
||||
def eventlet_wait_callback(conn, timeout=-1):
|
||||
"""A wait callback useful to allow eventlet to work with Psycopg."""
|
||||
while 1:
|
||||
state = conn.poll()
|
||||
if state == extensions.POLL_OK:
|
||||
break
|
||||
elif state == extensions.POLL_READ:
|
||||
trampoline(conn.fileno(), read=True)
|
||||
elif state == extensions.POLL_WRITE:
|
||||
trampoline(conn.fileno(), write=True)
|
||||
else:
|
||||
raise psycopg2.OperationalError(
|
||||
"Bad result from poll: %r" % state)
|
||||
@@ -171,15 +171,15 @@ print "already_patched", ",".join(sorted(patcher.already_patched.keys()))
|
||||
|
||||
def test_boolean(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch()",
|
||||
'os,select,socket,thread,time')
|
||||
'os,psycopg,select,socket,thread,time')
|
||||
|
||||
def test_boolean_all(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(all=True)",
|
||||
'os,select,socket,thread,time')
|
||||
'os,psycopg,select,socket,thread,time')
|
||||
|
||||
def test_boolean_all_single(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(all=True, socket=True)",
|
||||
'os,select,socket,thread,time')
|
||||
'os,psycopg,select,socket,thread,time')
|
||||
|
||||
def test_boolean_all_negative(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(all=False, "\
|
||||
@@ -197,12 +197,12 @@ print "already_patched", ",".join(sorted(patcher.already_patched.keys()))
|
||||
|
||||
def test_boolean_negative(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False)",
|
||||
'os,select,thread,time')
|
||||
'os,psycopg,select,thread,time')
|
||||
|
||||
def test_boolean_negative2(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False,"\
|
||||
"time=False)",
|
||||
'os,select,thread')
|
||||
'os,psycopg,select,thread')
|
||||
|
||||
def test_conflicting_specifications(self):
|
||||
self.assert_boolean_logic("patcher.monkey_patch(socket=False, "\
|
||||
|
||||
Reference in New Issue
Block a user