Fix HTTPServer.serve_forever blocking whole process
Original report: https://github.com/eventlet/eventlet/issues/249 Explanation is in the comments in the code. Originally reverted[1] because a commit preceding it[2] broke the build but it wasn't clear what commit was responsible. [1]02b693a45d
[2]4656eadfa5
This commit is contained in:
@@ -3,9 +3,29 @@ import sys
|
|||||||
from eventlet import patcher
|
from eventlet import patcher
|
||||||
from eventlet.green import select
|
from eventlet.green import select
|
||||||
|
|
||||||
|
__patched__ = [
|
||||||
|
'SelectSelector',
|
||||||
|
'PollSelector',
|
||||||
|
'EpollSelector',
|
||||||
|
'DevpollSelector',
|
||||||
|
'KqueueSelector',
|
||||||
|
]
|
||||||
|
|
||||||
patcher.inject('selectors', globals(), ('select', select))
|
patcher.inject('selectors', globals(), ('select', select))
|
||||||
|
|
||||||
del patcher
|
del patcher
|
||||||
|
|
||||||
if sys.platform != 'win32':
|
if sys.platform != 'win32':
|
||||||
SelectSelector._select = staticmethod(select.select)
|
SelectSelector._select = staticmethod(select.select)
|
||||||
|
|
||||||
|
|
||||||
|
# We only have green select so the options are:
|
||||||
|
# * leave it be and have selectors that block
|
||||||
|
# * try to pretend the "bad" selectors don't exist
|
||||||
|
# * replace all with SelectSelector for the price of possibly different
|
||||||
|
# performance characteristic and missing fileno() method (if someone
|
||||||
|
# uses it it'll result in a crash, we may want to implement it in the future)
|
||||||
|
PollSelector = SelectSelector
|
||||||
|
EpollSelector = SelectSelector
|
||||||
|
DevpollSelector = SelectSelector
|
||||||
|
KqueueSelector = SelectSelector
|
||||||
|
@@ -331,7 +331,13 @@ def _green_os_modules():
|
|||||||
|
|
||||||
def _green_select_modules():
|
def _green_select_modules():
|
||||||
from eventlet.green import select
|
from eventlet.green import select
|
||||||
return [('select', select)]
|
modules = [('select', select)]
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 4):
|
||||||
|
from eventlet.green import selectors
|
||||||
|
modules.append(('selectors', selectors))
|
||||||
|
|
||||||
|
return modules
|
||||||
|
|
||||||
|
|
||||||
def _green_socket_modules():
|
def _green_socket_modules():
|
||||||
|
28
tests/isolated/patcher_socketserver_selectors.py
Normal file
28
tests/isolated/patcher_socketserver_selectors.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
if __name__ == '__main__':
|
||||||
|
import eventlet
|
||||||
|
eventlet.monkey_patch()
|
||||||
|
|
||||||
|
from eventlet.support.six.moves.BaseHTTPServer import (
|
||||||
|
HTTPServer,
|
||||||
|
BaseHTTPRequestHandler,
|
||||||
|
)
|
||||||
|
import threading
|
||||||
|
|
||||||
|
server = HTTPServer(('localhost', 0), BaseHTTPRequestHandler)
|
||||||
|
thread = threading.Thread(target=server.serve_forever)
|
||||||
|
|
||||||
|
# Before fixing it the code would never go pass this line because:
|
||||||
|
# * socketserver.BaseServer that's used behind the scenes here uses
|
||||||
|
# selectors.PollSelector if it's available and we don't have green poll
|
||||||
|
# implementation so this just couldn't work
|
||||||
|
# * making socketserver use selectors.SelectSelector wasn't enough as
|
||||||
|
# until now we just failed to monkey patch selectors module
|
||||||
|
#
|
||||||
|
# Due to the issues above this thread.start() call effectively behaved
|
||||||
|
# like calling server.serve_forever() directly in the current thread
|
||||||
|
#
|
||||||
|
# Original report: https://github.com/eventlet/eventlet/issues/249
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
server.shutdown()
|
||||||
|
print('pass')
|
@@ -506,3 +506,7 @@ def test_threading_condition():
|
|||||||
|
|
||||||
def test_threading_join():
|
def test_threading_join():
|
||||||
tests.run_isolated('patcher_threading_join.py')
|
tests.run_isolated('patcher_threading_join.py')
|
||||||
|
|
||||||
|
|
||||||
|
def test_socketserver_selectors():
|
||||||
|
tests.run_isolated('patcher_socketserver_selectors.py')
|
||||||
|
Reference in New Issue
Block a user