Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gevent
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gevent
Commits
2c858dcd
Commit
2c858dcd
authored
Sep 04, 2015
by
Jason Madden
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Documentation.
parent
2d5644e4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
90 additions
and
45 deletions
+90
-45
doc/whatsnew_1_1.rst
doc/whatsnew_1_1.rst
+12
-10
gevent/monkey.py
gevent/monkey.py
+1
-1
gevent/os.py
gevent/os.py
+16
-12
gevent/signal.py
gevent/signal.py
+32
-4
gevent/threadpool.py
gevent/threadpool.py
+1
-1
gevent/util.py
gevent/util.py
+28
-17
No files found.
doc/whatsnew_1_1.rst
View file @
2c858dcd
...
...
@@ -27,12 +27,12 @@ PyPy Notes
PyPy has been tested on OS X and 64-bit Linux from version 2.5.0
through 2.5.1, 2.6.0, 2.6.1, and pre-release versions of 2.7.0.
- Version 2.6.1
is required for the most robust signal handling. Prior
to 2.6.1 and its inclusion of `cffi 1.3.0`_, signals could be
delivered incorrectly or fail to be delivered during a blocking
operation. (PyPy 2.5.0 includes CFFI 0.8.6 while 2.6.0 has 1.1.0;
the necessary feature was added in `1.2.0`_ which is not itself
directly present in any PyPy release.)
- Version 2.6.1
or above is required for the most robust signal
handling. Prior to 2.6.1 and its inclusion of `cffi 1.3.0`_, signals
could be delivered incorrectly or fail to be delivered during a
blocking operation. (PyPy 2.5.0 includes CFFI 0.8.6 while 2.6.0 has
1.1.0; the necessary feature was added in `1.2.0`_ which is not
itself
directly present in any PyPy release.)
- Overall performance seems to be quite acceptable with newer versions
of PyPy. The benchmarks distributed with gevent typically perform as
well or better on PyPy than on CPython. Things that are known or
...
...
@@ -47,18 +47,20 @@ through 2.5.1, 2.6.0, 2.6.1, and pre-release versions of 2.7.0.
Improved subprocess support
===========================
In gevent 1.0, support and monkey patching for the
``subprocess`
`
In gevent 1.0, support and monkey patching for the
:mod:`subprocess
`
module was added. Monkey patching was off by default.
In 1.1, monkey patching
subprocess
is on by default due to
In 1.1, monkey patching
``subprocess``
is on by default due to
improvements in handling child processes and requirements by
downstream libraries, notably `gunicorn`_.
- :func:`gevent.os.fork`, which is monkey patched by default (and
should be used to fork a gevent-aware process that expects to use
gevent in the child process) has been improved and cooperates with
:func:`gevent.os.waitpid` (again monkey patched by default).
- fork-watchers will be called, even in multi-threaded programs.
:func:`gevent.os.waitpid` (again monkey patched by default) and
:func:`gevent.signal.signal` (which is monkey patched only for the
:data:`signal.SIGCHLD` case). The latter two patches are new in 1.1.
- Fork-watchers will be called, even in multi-threaded programs.
- The default threadpool and threaded resolver work in child
processes.
- File descriptors are no longer leaked if
...
...
gevent/monkey.py
View file @
2c858dcd
...
...
@@ -63,7 +63,7 @@ def get_original(mod_name, item_name):
If the object has not been patched, then that object will still be retrieved.
:param item_name: A string or sequenc of strings naming the attribute(s) on the module
:param item_name: A string or sequenc
e
of strings naming the attribute(s) on the module
``mod_name`` to return.
:return: The original value if a string was given for ``item_name`` or a sequence
of original values if a sequence was passed.
...
...
gevent/os.py
View file @
2c858dcd
...
...
@@ -149,16 +149,18 @@ if hasattr(os, 'fork'):
.. note::
The PID returned by this function may not be
waitable with either :func:`os.waitpid` or :func:`waitpid`
if libev child watchers are in use. For example, the
The PID returned by this function may not be waitable with
either :func:`os.waitpid` or :func:`waitpid` and it may
not generate SIGCHLD signals if libev child watchers are
or ever have been in use. For example, the
:mod:`gevent.subprocess` module uses libev child watchers
(which parts of gevent use libev child watchers is subject to change
at any time). Most applications should use :func:`fork_and_watch`,
which is monkey-patched as the default replacement for :func:`os.fork`
and implements the ``fork`` function of this module by default, unless
the environment variable ``GEVENT_NOWAITPID`` is defined before this
module is imported.
(which parts of gevent use libev child watchers is subject
to change at any time). Most applications should use
:func:`fork_and_watch`, which is monkey-patched as the
default replacement for :func:`os.fork` and implements the
``fork`` function of this module by default, unless the
environment variable ``GEVENT_NOWAITPID`` is defined
before this module is imported.
.. versionadded:: 1.1b2
"""
...
...
@@ -295,11 +297,13 @@ if hasattr(os, 'fork'):
:keyword loop: The loop to start the watcher in. Defaults to the
loop of the current hub.
:keyword fork: The fork function. Defaults to :func:`the one defined in this
module <gevent
_fork
>` (which automatically calls :func:`gevent.hub.reinit`).
module <gevent
.os.fork_gevent
>` (which automatically calls :func:`gevent.hub.reinit`).
Pass the builtin :func:`os.fork` function if you do not need to
initialize gevent in the child process.
.. versionadded:: 1.1a3
.. seealso::
:func:`gevent.monkey.get_original` To access the builtin :func:`os.fork`.
"""
pid
=
fork
()
if
pid
:
...
...
@@ -318,7 +322,7 @@ if hasattr(os, 'fork'):
def
fork
(
*
args
,
**
kwargs
):
"""
Forks a child process and starts a child watcher for it in the
parent process.
parent process
so that ``waitpid`` and SIGCHLD work as expected
.
This implementation of ``fork`` is a wrapper for :func:`fork_and_watch`
when the environment variable ``GEVENT_NOWAITPID`` is *not* defined.
...
...
@@ -333,7 +337,7 @@ if hasattr(os, 'fork'):
def
fork
():
"""
Forks a child process, initializes gevent in the child,
but *does not* prepare the parent to wait for the child.
but *does not* prepare the parent to wait for the child
or receive SIGCHLD
.
This implementation of ``fork`` is a wrapper for :func:`fork_gevent`
when the environment variable ``GEVENT_NOWAITPID`` *is* defined.
...
...
gevent/signal.py
View file @
2c858dcd
"""
Cooperative implementation of special cases of :func:`signal.signal`.
This module is designed to work with libev's child watchers, as used by
default in :func:`gevent.os.fork` Note that each SIGCHLD handler will be run
in a new greenlet when the signal is delivered (just like :class:`gevent.hub.signal`)
This module is designed to work with libev's child watchers, as used
by default in :func:`gevent.os.fork` Note that each ``SIGCHLD`` handler
will be run in a new greenlet when the signal is delivered (just like
:class:`gevent.hub.signal`)
The implementations in this module are only monkey patched if
:func:`gevent.os.waitpid` is being used (the default) and if
:const:`signal.SIGCHLD` is available; see :func:`gevent.os.fork` for
information on configuring this not to be the case for advanced uses.
.. versionadded:: 1.1b4
"""
...
...
@@ -25,6 +31,10 @@ _signal_getsignal = _signal.getsignal
def
getsignal
(
signalnum
):
"""
Exactly the same as :func:`signal.signal` except where
:const:`signal.SIGCHLD` is concerned.
"""
if
signalnum
!=
_signal
.
SIGCHLD
:
return
_signal_getsignal
(
signalnum
)
...
...
@@ -36,6 +46,22 @@ def getsignal(signalnum):
def
signal
(
signalnum
,
handler
):
"""
Exactly the same as :func:`signal.signal` except where
:const:`signal.SIGCHLD` is concerned.
.. note::
A :const:`signal.SIGCHLD` handler installed with this function
will only be triggered for children that are forked using
:func:`gevent.os.fork` (:func:`gevent.os.fork_and_watch`);
children forked before monkey patching, or otherwise by the raw
:func:`os.fork`, will not trigger the handler installed by this
function. (It's unlikely that a SIGCHLD handler installed with
the builtin :func:`signal.signal` would be triggered either;
libev typically overwrites such a handler at the C level. At
the very least, it's full of race conditions.)
"""
if
signalnum
!=
_signal
.
SIGCHLD
:
return
_signal_signal
(
signalnum
,
handler
)
...
...
@@ -43,6 +69,7 @@ def signal(signalnum, handler):
# greenlet, just like threads
if
handler
!=
_signal
.
SIG_IGN
and
handler
!=
_signal
.
SIG_DFL
and
not
callable
(
handler
):
# exact same error message raised by the stdlib
raise
TypeError
(
"signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object"
)
old_handler
=
getsignal
(
signalnum
)
...
...
@@ -65,7 +92,8 @@ def _on_child_hook():
import
gevent.os
if
'waitpid'
in
gevent
.
os
.
__implements__
and
hasattr
(
_signal
,
'SIGCHLD'
):
# Tightly coupled here to gevent.os and its waitpid implementation
# Tightly coupled here to gevent.os and its waitpid implementation; only use these
# if necessary.
gevent
.
os
.
_on_child_hook
=
_on_child_hook
__implements__
.
append
(
"signal"
)
__implements__
.
append
(
"getsignal"
)
...
...
gevent/threadpool.py
View file @
2c858dcd
...
...
@@ -323,7 +323,7 @@ class ThreadResult(object):
def
wrap_errors
(
errors
,
function
,
args
,
kwargs
):
"""
.. deprecated:: 1.1a2
On
ly used by ThreadPool.apply_e.
Previous
ly used by ThreadPool.apply_e.
"""
try
:
return
True
,
function
(
*
args
,
**
kwargs
)
...
...
gevent/util.py
View file @
2c858dcd
# Copyright (c) 2009 Denis Bilenko. See LICENSE for details.
__all__
=
[
'wrap_errors'
]
"""
Low-level utilities.
"""
from
__future__
import
absolute_import
import
functools
__all__
=
[
'wrap_errors'
]
class
wrap_errors
(
object
):
"""Helper to make function return an exception, rather than raise it.
"""
Helper to make function return an exception, rather than raise it.
Because every exception that is unhandled by greenlet will be logged,
it is desirable to prevent non-error exceptions from leaving a greenlet.
This can done with
simple ``try``/``
except`` construct::
This can done with
a simple ``try/
except`` construct::
def wrapped_func(*args, **kwargs):
try:
return func(*args, **kwargs)
except (
A, B, C
) as ex:
except (
TypeError, ValueError, AttributeError
) as ex:
return ex
:class:`wrap_errors`
provides a shortcut to write that in one line::
This class
provides a shortcut to write that in one line::
wrapped_func = wrap_errors((
A, B, C
), func)
wrapped_func = wrap_errors((
TypeError, ValueError, AttributeError
), func)
It also preserves ``__str__`` and ``__repr__`` of the original function.
"""
# QQQ could also support using wrap_errors as a decorator
def
__init__
(
self
,
errors
,
func
):
"""Make a new function from `func', such that it catches `errors' (an
Exception subclass, or a tuple of Exception subclasses) and return
it as a value.
"""
self
.
errors
=
errors
self
.
func
=
func
Calling this makes a new function from *func*, such that it catches *errors* (an
:exc:`BaseException` subclass, or a tuple of :exc:`BaseException` subclasses) and
return it as a value.
"""
self
.
__errors
=
errors
self
.
__func
=
func
# Set __doc__, __wrapped__, etc, especially useful on Python 3.
functools
.
update_wrapper
(
self
,
func
)
def
__call__
(
self
,
*
args
,
**
kwargs
):
func
=
self
.
func
func
=
self
.
__
func
try
:
return
func
(
*
args
,
**
kwargs
)
except
self
.
errors
as
ex
:
except
self
.
__
errors
as
ex
:
return
ex
def
__str__
(
self
):
return
str
(
self
.
func
)
return
str
(
self
.
__
func
)
def
__repr__
(
self
):
return
repr
(
self
.
func
)
return
repr
(
self
.
__
func
)
def
__getattr__
(
self
,
item
):
return
getattr
(
self
.
func
,
item
)
def
__getattr__
(
self
,
name
):
return
getattr
(
self
.
__func
,
name
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment