def patch_signal():
"""
Make the signal.signal function work with a monkey-patched os.
.. caution:: This method must be used with :func:`patch_os` to have proper SIGCHLD
handling. :func:`patch_all` calls both by default.
.. caution:: For proper SIGCHLD handling, you must yield to the event loop.
Using :func:`patch_all` is the easiest way to ensure this.
.. seealso:: :mod:`gevent.signal`
"""
patch_module("signal")
python类patch_all()的实例源码
def main():
args = {}
argv = sys.argv[1:]
verbose = False
script_help, patch_all_args, modules = _get_script_help()
while argv and argv[0].startswith('--'):
option = argv[0][2:]
if option == 'verbose':
verbose = True
elif option.startswith('no-') and option.replace('no-', '') in patch_all_args:
args[option[3:]] = False
elif option in patch_all_args:
args[option] = True
if option in modules:
for module in modules:
args.setdefault(module, False)
else:
sys.exit(script_help + '\n\n' + 'Cannot patch %r' % option)
del argv[0]
# TODO: break on --
if verbose:
import pprint
import os
print('gevent.monkey.patch_all(%s)' % ', '.join('%s=%s' % item for item in args.items()))
print('sys.version=%s' % (sys.version.strip().replace('\n', ' '), ))
print('sys.path=%s' % pprint.pformat(sys.path))
print('sys.modules=%s' % pprint.pformat(sorted(sys.modules.keys())))
print('cwd=%s' % os.getcwd())
patch_all(**args)
if argv:
sys.argv = argv
__package__ = None
assert __package__ is None
globals()['__file__'] = sys.argv[0] # issue #302
with open(sys.argv[0]) as f:
exec(f.read())
else:
print(script_help)
def _get_script_help():
from inspect import getargspec
patch_all_args = getargspec(patch_all)[0] # pylint:disable=deprecated-method
modules = [x for x in patch_all_args if 'patch_' + x in globals()]
script_help = """gevent.monkey - monkey patch the standard modules to use gevent.
USAGE: python -m gevent.monkey [MONKEY OPTIONS] script [SCRIPT OPTIONS]
If no OPTIONS present, monkey patches all the modules it can patch.
You can exclude a module with --no-module, e.g. --no-thread. You can
specify a module to patch with --module, e.g. --socket. In the latter
case only the modules specified on the command line will be patched.
MONKEY OPTIONS: --verbose %s""" % ', '.join('--[no-]%s' % m for m in modules)
return script_help, patch_all_args, modules
def __init__(self, arguments):
self.config_loader = ConfigTestLoader(
arguments.root_dir,
arguments.config
)
self.single_test = arguments.single_test
monkey.patch_all()
def run(self, handler):
from gevent import wsgi as wsgi_fast, pywsgi, monkey, local
if self.options.get('monkey', True):
if not threading.local is local.local: monkey.patch_all()
wsgi = wsgi_fast if self.options.get('fast') else pywsgi
wsgi.WSGIServer((self.host, self.port), handler).serve_forever()
def gevent_spawn(self):
""" Spawn worker threads (using gevent) """
monkey.patch_all(thread=False)
joinall([spawn(self.gevent_worker) for x in range(self.queue_worker_amount)])
def multi_coroutine(self, spider_name, coroutine):
try:
coroutine = int(coroutine)
except ValueError:
print('ERROR: coroutine must be int!!!')
sys.exit(1)
from gevent import monkey
monkey.patch_all()
gevent.joinall([
gevent.spawn(self.execute, spider_name) for i in
xrange(coroutine)
])
def eventlet(app, address, **options):
from gevent import monkey
monkey.patch_all()
from eventlet import wsgi, listen
wsgi.server(listen(address), app)
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER):
"""
REST-JSON API server
"""
DataStore.admin_id = hexencode(os.urandom(16))
Database.filepath = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.IPC, text=False)[1]
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
logger.info("Admin ID: %s" % DataStore.admin_id)
logger.debug("IPC database: %s" % Database.filepath)
# Initialize IPC database
DataStore.current_db = Database()
DataStore.current_db.connect()
DataStore.current_db.init()
# Run RESTful API
try:
if adapter == "gevent":
from gevent import monkey
monkey.patch_all()
elif adapter == "eventlet":
import eventlet
eventlet.monkey_patch()
logger.debug("Using adapter '%s' to run bottle" % adapter)
run(host=host, port=port, quiet=True, debug=False, server=adapter)
except socket.error, ex:
if "already in use" in getSafeExString(ex):
logger.error("Address already in use ('%s:%s')" % (host, port))
else:
raise
except ImportError:
errMsg = "Adapter '%s' is not available on this system" % adapter
if adapter in ("gevent", "eventlet"):
errMsg += " (e.g.: 'sudo apt-get install python-%s')" % adapter
logger.critical(errMsg)
def extract_geventsocketio_server(config):
from gevent import monkey
monkey.patch_all()
return dict(resource='socket.io')
def patch_os():
"""
Replace :func:`os.fork` with :func:`gevent.fork`, and, on POSIX,
:func:`os.waitpid` with :func:`gevent.os.waitpid` (if the
environment variable ``GEVENT_NOWAITPID`` is not defined). Does
nothing if fork is not available.
.. caution:: This method must be used with :func:`patch_signal` to have proper SIGCHLD
handling and thus correct results from ``waitpid``.
:func:`patch_all` calls both by default.
.. caution:: For SIGCHLD handling to work correctly, the event loop must run.
The easiest way to help ensure this is to use :func:`patch_all`.
"""
patch_module('os')
def patch_signal():
"""
Make the signal.signal function work with a monkey-patched os.
.. caution:: This method must be used with :func:`patch_os` to have proper SIGCHLD
handling. :func:`patch_all` calls both by default.
.. caution:: For proper SIGCHLD handling, you must yield to the event loop.
Using :func:`patch_all` is the easiest way to ensure this.
.. seealso:: :mod:`gevent.signal`
"""
patch_module("signal")
def main():
args = {}
argv = sys.argv[1:]
verbose = False
script_help, patch_all_args, modules = _get_script_help()
while argv and argv[0].startswith('--'):
option = argv[0][2:]
if option == 'verbose':
verbose = True
elif option.startswith('no-') and option.replace('no-', '') in patch_all_args:
args[option[3:]] = False
elif option in patch_all_args:
args[option] = True
if option in modules:
for module in modules:
args.setdefault(module, False)
else:
sys.exit(script_help + '\n\n' + 'Cannot patch %r' % option)
del argv[0]
# TODO: break on --
if verbose:
import pprint
import os
print('gevent.monkey.patch_all(%s)' % ', '.join('%s=%s' % item for item in args.items()))
print('sys.version=%s' % (sys.version.strip().replace('\n', ' '), ))
print('sys.path=%s' % pprint.pformat(sys.path))
print('sys.modules=%s' % pprint.pformat(sorted(sys.modules.keys())))
print('cwd=%s' % os.getcwd())
patch_all(**args)
if argv:
sys.argv = argv
__package__ = None
assert __package__ is None
globals()['__file__'] = sys.argv[0] # issue #302
with open(sys.argv[0]) as f:
exec(f.read())
else:
print(script_help)
def patch():
global is_patched
if is_patched or os.environ.get('RILL_SKIP_GEVENT_PATCH', False):
return
from gevent import monkey
print("Performing gevent monkey-patching")
monkey.patch_all()
is_patched = True
def patch_os():
"""
Replace :func:`os.fork` with :func:`gevent.fork`, and, on POSIX,
:func:`os.waitpid` with :func:`gevent.os.waitpid` (if the
environment variable ``GEVENT_NOWAITPID`` is not defined). Does
nothing if fork is not available.
This method must be used with :func:`patch_signal` to have proper SIGCHLD
handling. :func:`patch_all` calls both by default.
"""
patch_module('os')
def patch_signal():
"""
Make the signal.signal function work with a monkey-patched os.
This method must be used with :func:`patch_os` to have proper SIGCHLD
handling. :func:`patch_all` calls both by default.
.. seealso:: :mod:`gevent.signal`
"""
patch_module("signal")
def main():
args = {}
argv = sys.argv[1:]
verbose = False
script_help, patch_all_args, modules = _get_script_help()
while argv and argv[0].startswith('--'):
option = argv[0][2:]
if option == 'verbose':
verbose = True
elif option.startswith('no-') and option.replace('no-', '') in patch_all_args:
args[option[3:]] = False
elif option in patch_all_args:
args[option] = True
if option in modules:
for module in modules:
args.setdefault(module, False)
else:
sys.exit(script_help + '\n\n' + 'Cannot patch %r' % option)
del argv[0]
# TODO: break on --
if verbose:
import pprint
import os
print('gevent.monkey.patch_all(%s)' % ', '.join('%s=%s' % item for item in args.items()))
print('sys.version=%s' % (sys.version.strip().replace('\n', ' '), ))
print('sys.path=%s' % pprint.pformat(sys.path))
print('sys.modules=%s' % pprint.pformat(sorted(sys.modules.keys())))
print('cwd=%s' % os.getcwd())
patch_all(**args)
if argv:
sys.argv = argv
__package__ = None
assert __package__ is None
globals()['__file__'] = sys.argv[0] # issue #302
with open(sys.argv[0]) as f:
exec(f.read())
else:
print(script_help)
def tornado_combiner(configs, use_gevent=False, start=True, monkey_patch=None,
Container=None, Server=None, threadpool=None): # pragma: no cover
"""Combine servers in one tornado event loop process
:param configs: [
{
'app': Microservice Application or another wsgi application, required
'port': int, default: 5000
'address': str, default: ""
},
{ ... }
]
:param use_gevent: if True, app.wsgi will be run in gevent.spawn
:param start: if True, will be call utils.tornado_start()
:param Container: your class, bases on tornado.wsgi.WSGIContainer, default: tornado.wsgi.WSGIContainer
:param Server: your class, bases on tornado.httpserver.HTTPServer, default: tornado.httpserver.HTTPServer
:param monkey_patch: boolean, use gevent.monkey.patch_all() for patching standard modules, default: use_gevent
:return: list of tornado servers
"""
servers = []
if monkey_patch is None:
monkey_patch = use_gevent
if use_gevent:
if monkey_patch:
from gevent import monkey
monkey.patch_all()
if threadpool is not None:
from multiprocessing.pool import ThreadPool
if not isinstance(threadpool, ThreadPool):
threadpool = ThreadPool(threadpool)
for config in configs:
app = config['app']
port = config.get('port', 5000)
address = config.get('address', '')
server = tornado_run(app, use_gevent=use_gevent, port=port,
monkey_patch=False, address=address, start=False,
Container=Container,
Server=Server, threadpool=threadpool)
servers.append(server)
if start:
tornado_start()
return servers
def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, httplib=False,
subprocess=True, sys=False, aggressive=True, Event=False,
builtins=True, signal=True):
"""
Do all of the default monkey patching (calls every other applicable
function in this module).
.. versionchanged:: 1.1
Issue a :mod:`warning <warnings>` if this function is called multiple times
with different arguments. The second and subsequent calls will only add more
patches, they can never remove existing patches by setting an argument to ``False``.
.. versionchanged:: 1.1
Issue a :mod:`warning <warnings>` if this function is called with ``os=False``
and ``signal=True``. This will cause SIGCHLD handlers to not be called. This may
be an error in the future.
"""
# Check to see if they're changing the patched list
_warnings, first_time = _check_repatching(**locals())
if not _warnings and not first_time:
# Nothing to do, identical args to what we just
# did
return
# order is important
if os:
patch_os()
if time:
patch_time()
if thread:
patch_thread(Event=Event)
# sys must be patched after thread. in other cases threading._shutdown will be
# initiated to _MainThread with real thread ident
if sys:
patch_sys()
if socket:
patch_socket(dns=dns, aggressive=aggressive)
if select:
patch_select(aggressive=aggressive)
if ssl:
patch_ssl()
if httplib:
raise ValueError('gevent.httplib is no longer provided, httplib must be False')
if subprocess:
patch_subprocess()
if builtins:
patch_builtins()
if signal:
if not os:
_queue_warning('Patching signal but not os will result in SIGCHLD handlers'
' installed after this not being called and os.waitpid may not'
' function correctly if gevent.subprocess is used. This may raise an'
' error in the future.',
_warnings)
patch_signal()
_process_warnings(_warnings)
def patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, httplib=False,
subprocess=True, sys=False, aggressive=True, Event=False,
builtins=True, signal=True):
"""
Do all of the default monkey patching (calls every other applicable
function in this module).
.. versionchanged:: 1.1
Issue a :mod:`warning <warnings>` if this function is called multiple times
with different arguments. The second and subsequent calls will only add more
patches, they can never remove existing patches by setting an argument to ``False``.
.. versionchanged:: 1.1
Issue a :mod:`warning <warnings>` if this function is called with ``os=False``
and ``signal=True``. This will cause SIGCHLD handlers to not be called. This may
be an error in the future.
"""
# pylint:disable=too-many-locals,too-many-branches
# Check to see if they're changing the patched list
_warnings, first_time = _check_repatching(**locals())
if not _warnings and not first_time:
# Nothing to do, identical args to what we just
# did
return
# order is important
if os:
patch_os()
if time:
patch_time()
if thread:
patch_thread(Event=Event, _warnings=_warnings)
# sys must be patched after thread. in other cases threading._shutdown will be
# initiated to _MainThread with real thread ident
if sys:
patch_sys()
if socket:
patch_socket(dns=dns, aggressive=aggressive)
if select:
patch_select(aggressive=aggressive)
if ssl:
patch_ssl()
if httplib:
raise ValueError('gevent.httplib is no longer provided, httplib must be False')
if subprocess:
patch_subprocess()
if builtins:
patch_builtins()
if signal:
if not os:
_queue_warning('Patching signal but not os will result in SIGCHLD handlers'
' installed after this not being called and os.waitpid may not'
' function correctly if gevent.subprocess is used. This may raise an'
' error in the future.',
_warnings)
patch_signal()
_process_warnings(_warnings)