Ensure fdopen uses greenio object under eventlet
The _fd_logger function works around a regular Unix pipe, with a python file object wrapped around both pipe file descriptors. This would be stupidly simple and obvious, except eventlet. We need to use the fdopen from io.open(), and not os.fdopen() (on py2; on py3 they're the same), because the older python file objects have broken behaviour regarding blocking reads. Eventlet doesn't monkey patch os.pipe, nor anything in io.* - so none of the existing eventlet monkey_patching will "just work" for our case. This change adds a custom `fdopen` function that explicitly uses greenio.GreenPipe or io.open as appropriate - and uses this to always return an eventlet-safe file object. Change-Id: I4a6c0d4247aca17536316fb0ab163241ad545b20
This commit is contained in:
parent
a6e554bd49
commit
4fba8f505b
|
@ -61,6 +61,7 @@ if platform.system() == 'Linux':
|
|||
import grp
|
||||
import pwd
|
||||
|
||||
import eventlet
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import importutils
|
||||
|
@ -177,11 +178,24 @@ class _ClientChannel(comm.ClientChannel):
|
|||
raise ProtocolError(_('Unexpected response: %r') % result)
|
||||
|
||||
|
||||
def fdopen(fd, *args, **kwargs):
|
||||
# NOTE(gus): We can't just use os.fdopen() here and allow the
|
||||
# regular (optional) monkey_patching to do its thing. Turns out
|
||||
# that regular file objects (as returned by os.fdopen) on python2
|
||||
# are broken in lots of ways regarding blocking behaviour. We
|
||||
# *need* the newer io.* objects on py2 (doesn't matter on py3,
|
||||
# since the old file code has been replaced with io.*)
|
||||
if eventlet.patcher.is_monkey_patched('os'):
|
||||
return eventlet.greenio.GreenPipe(fd, *args, **kwargs)
|
||||
else:
|
||||
return io.open(fd, *args, **kwargs)
|
||||
|
||||
|
||||
def _fd_logger(level=logging.WARN):
|
||||
"""Helper that returns a file object that is asynchronously logged"""
|
||||
read_fd, write_fd = os.pipe()
|
||||
read_end = io.open(read_fd, 'r', 1)
|
||||
write_end = io.open(write_fd, 'w', 1)
|
||||
read_end = fdopen(read_fd, 'r', 1)
|
||||
write_end = fdopen(write_fd, 'w', 1)
|
||||
|
||||
def logger(f):
|
||||
for line in f:
|
||||
|
|
|
@ -9,3 +9,5 @@ oslo.config>=3.4.0 # Apache-2.0
|
|||
oslo.utils>=3.4.0 # Apache-2.0
|
||||
enum34;python_version=='2.7' or python_version=='2.6' or python_version=='3.3' # BSD
|
||||
cffi # MIT
|
||||
eventlet>=0.18.2 # MIT
|
||||
greenlet>=0.3.2 # MIT
|
||||
|
|
Loading…
Reference in New Issue