Restify PEP 3145 (#143)

This commit is contained in:
Mariatta 2016-11-28 09:17:27 -08:00 committed by Berker Peksag
parent 84de20b55d
commit c6fbead696
1 changed files with 110 additions and 96 deletions

View File

@ -5,136 +5,150 @@ Last-Modified: $Date$
Author: (James) Eric Pruitt, Charles R. McCreary, Josiah Carlson Author: (James) Eric Pruitt, Charles R. McCreary, Josiah Carlson
Status: Withdrawn Status: Withdrawn
Type: Standards Track Type: Standards Track
Content-Type: text/plain Content-Type: text/x-rst
Created: 04-Aug-2009 Created: 04-Aug-2009
Python-Version: 3.2 Python-Version: 3.2
Post-History: Post-History:
Abstract:
In its present form, the subprocess.Popen implementation is prone to Abstract
dead-locking and blocking of the parent Python script while waiting on data ========
from the child process. This PEP proposes to make
subprocess.Popen more asynchronous to help alleviate these In its present form, the subprocess.Popen implementation is prone to
problems. dead-locking and blocking of the parent Python script while waiting on data
from the child process. This PEP proposes to make
subprocess.Popen more asynchronous to help alleviate these
problems.
PEP Deferral: PEP Deferral
============
Further exploration of the concepts covered in this PEP has been deferred Further exploration of the concepts covered in this PEP has been deferred
at least until after PEP 3156 has been resolved. at least until after PEP 3156 has been resolved.
PEP Withdrawal: PEP Withdrawal
==============
This can be dealt with in the bug tracker. This can be dealt with in the bug tracker. A specific proposal is
A specific proposal is attached to http://bugs.python.org/issue18823 attached to [11]_.
Motivation: Motivation
==========
A search for "python asynchronous subprocess" will turn up numerous A search for "python asynchronous subprocess" will turn up numerous
accounts of people wanting to execute a child process and communicate with accounts of people wanting to execute a child process and communicate with
it from time to time reading only the data that is available instead of it from time to time reading only the data that is available instead of
blocking to wait for the program to produce data [1] [2] [3]. The current blocking to wait for the program to produce data [1]_ [2]_ [3]_. The current
behavior of the subprocess module is that when a user sends or receives behavior of the subprocess module is that when a user sends or receives
data via the stdin, stderr and stdout file objects, dead locks are common data via the stdin, stderr and stdout file objects, dead locks are common
and documented [4] [5]. While communicate can be used to alleviate some of and documented [4]_ [5]_. While communicate can be used to alleviate some of
the buffering issues, it will still cause the parent process to block while the buffering issues, it will still cause the parent process to block while
attempting to read data when none is available to be read from the child attempting to read data when none is available to be read from the child
process. process.
Rationale:
There is a documented need for asynchronous, non-blocking functionality in Rationale
subprocess.Popen [6] [7] [2] [3]. Inclusion of the code would improve the =========
utility of the Python standard library that can be used on Unix based and
Windows builds of Python. Practically every I/O object in Python has a
file-like wrapper of some sort. Sockets already act as such and for
strings there is StringIO. Popen can be made to act like a file by simply
using the methods attached to the subprocess.Popen.stderr, stdout and
stdin file-like objects. But when using the read and write methods of
those options, you do not have the benefit of asynchronous I/O. In the
proposed solution the wrapper wraps the asynchronous methods to mimic a
file object.
Reference Implementation: There is a documented need for asynchronous, non-blocking functionality in
subprocess.Popen [6]_ [7]_ [2]_ [3]_. Inclusion of the code would improve the
utility of the Python standard library that can be used on Unix based and
Windows builds of Python. Practically every I/O object in Python has a
file-like wrapper of some sort. Sockets already act as such and for
strings there is StringIO. Popen can be made to act like a file by simply
using the methods attached to the subprocess.Popen.stderr, stdout and
stdin file-like objects. But when using the read and write methods of
those options, you do not have the benefit of asynchronous I/O. In the
proposed solution the wrapper wraps the asynchronous methods to mimic a
file object.
I have been maintaining a Google Code repository that contains all of my
changes including tests and documentation [9] as well as blog detailing
the problems I have come across in the development process [10].
I have been working on implementing non-blocking asynchronous I/O in the Reference Implementation
subprocess.Popen module as well as a wrapper class for subprocess.Popen ========================
that makes it so that an executed process can take the place of a file by
duplicating all of the methods and attributes that file objects have.
There are two base functions that have been added to the subprocess.Popen I have been maintaining a Google Code repository that contains all of my
class: Popen.send and Popen._recv, each with two separate implementations, changes including tests and documentation [9]_ as well as blog detailing
one for Windows and one for Unix-based systems. The Windows the problems I have come across in the development process [10]_.
implementation uses ctypes to access the functions needed to control pipes
in the kernel 32 DLL in an asynchronous manner. On Unix based systems,
the Python interface for file control serves the same purpose. The
different implementations of Popen.send and Popen._recv have identical
arguments to make code that uses these functions work across multiple
platforms.
When calling the Popen._recv function, it requires the pipe name be I have been working on implementing non-blocking asynchronous I/O in the
passed as an argument so there exists the Popen.recv function that passes subprocess.Popen module as well as a wrapper class for subprocess.Popen
selects stdout as the pipe for Popen._recv by default. Popen.recv_err that makes it so that an executed process can take the place of a file by
selects stderr as the pipe by default. Popen.recv and Popen.recv_err duplicating all of the methods and attributes that file objects have.
are much easier to read and understand than Popen._recv('stdout' ...) and
Popen._recv('stderr' ...) respectively.
Since the Popen._recv function does not wait on data to be produced There are two base functions that have been added to the subprocess.Popen
before returning a value, it may return empty bytes. Popen.asyncread class: Popen.send and Popen._recv, each with two separate implementations,
handles this issue by returning all data read over a given time one for Windows and one for Unix-based systems. The Windows
interval. implementation uses ctypes to access the functions needed to control pipes
in the kernel 32 DLL in an asynchronous manner. On Unix based systems,
the Python interface for file control serves the same purpose. The
different implementations of Popen.send and Popen._recv have identical
arguments to make code that uses these functions work across multiple
platforms.
The ProcessIOWrapper class uses the asyncread and asyncwrite functions to When calling the Popen._recv function, it requires the pipe name be
allow a process to act like a file so that there are no blocking issues passed as an argument so there exists the Popen.recv function that passes
that can arise from using the stdout and stdin file objects produced from selects stdout as the pipe for Popen._recv by default. Popen.recv_err
a subprocess.Popen call. selects stderr as the pipe by default. Popen.recv and Popen.recv_err
are much easier to read and understand than Popen._recv('stdout' ...) and
Popen._recv('stderr' ...) respectively.
References: Since the Popen._recv function does not wait on data to be produced
before returning a value, it may return empty bytes. Popen.asyncread
handles this issue by returning all data read over a given time
interval.
[1] [ python-Feature Requests-1191964 ] asynchronous Subprocess The ``ProcessIOWrapper`` class uses the ``asyncread`` and ``asyncwrite`` functions to
http://mail.python.org/pipermail/python-bugs-list/2006-December/ allow a process to act like a file so that there are no blocking issues
036524.html that can arise from using the stdout and stdin file objects produced from
a subprocess.Popen call.
[2] Daily Life in an Ivory Basement : /feb-07/problems-with-subprocess
http://ivory.idyll.org/blog/feb-07/problems-with-subprocess
[3] How can I run an external command asynchronously from Python? - Stack References
Overflow ==========
http://stackoverflow.com/questions/636561/how-can-i-run-an-external-
command-asynchronously-from-python
[4] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation .. [1] [ python-Feature Requests-1191964 ] asynchronous Subprocess
http://docs.python.org/library/subprocess.html#subprocess.Popen.wait http://mail.python.org/pipermail/python-bugs-list/2006-December/
036524.html
[5] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation .. [2] Daily Life in an Ivory Basement : /feb-07/problems-with-subprocess
http://docs.python.org/library/subprocess.html#subprocess.Popen.kill http://ivory.idyll.org/blog/feb-07/problems-with-subprocess
[6] Issue 1191964: asynchronous Subprocess - Python tracker .. [3] How can I run an external command asynchronously from Python? - Stack
http://bugs.python.org/issue1191964 Overflow
http://stackoverflow.com/questions/636561/how-can-i-run-an-external-
command-asynchronously-from-python
[7] Module to allow Asynchronous subprocess use on Windows and Posix .. [4] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation
platforms - ActiveState Code http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
http://code.activestate.com/recipes/440554/
[8] subprocess.rst - subprocdev - Project Hosting on Google Code .. [5] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation
http://code.google.com/p/subprocdev/source/browse/doc/subprocess.rst?spec=svn2c925e935cad0166d5da85e37c742d8e7f609de5&r=2c925e935cad0166d5da85e37c742d8e7f609de5#437 http://docs.python.org/library/subprocess.html#subprocess.Popen.kill
[9] subprocdev - Project Hosting on Google Code .. [6] Issue 1191964: asynchronous Subprocess - Python tracker
http://code.google.com/p/subprocdev http://bugs.python.org/issue1191964
[10] Python Subprocess Dev .. [7] Module to allow Asynchronous subprocess use on Windows and Posix
http://subdev.blogspot.com/ platforms - ActiveState Code
http://code.activestate.com/recipes/440554/
Copyright: .. [8] subprocess.rst - subprocdev - Project Hosting on Google Code
http://code.google.com/p/subprocdev/source/browse/doc/subprocess.rst?spec=svn2c925e935cad0166d5da85e37c742d8e7f609de5&r=2c925e935cad0166d5da85e37c742d8e7f609de5#437
This P.E.P. is licensed under the Open Publication License; .. [9] subprocdev - Project Hosting on Google Code
http://www.opencontent.org/openpub/. http://code.google.com/p/subprocdev
.. [10] Python Subprocess Dev
http://subdev.blogspot.com/
.. [11] https://bugs.python.org/issue18823 -- Idle: use pipes instead of
sockets to talk with user subprocess
Copyright
=========
This P.E.P. is licensed under the Open Publication License;
http://www.opencontent.org/openpub/.