-
Notifications
You must be signed in to change notification settings - Fork 202
Description
In mitogen.parent.Connection._first_stage() it may be advantagous to read preamble bytes from stdin, until EOF. Rather than trying to read exactly PREAMBLE_COMPRESSED_LEN bytes.
Using f.read() rather than f.read(PREAMBLE_COMPRESSED_LEN) may
- Shorten the boot command, by reducing the size of the first stage
- Simplify construction of the first stage by eliminating a substitution
- Improve reliability of the first stage by adding an implicit
read()loop
Achieving this would need
- Closing the write side of pipe that feeds the child's stdin, once all bytes of the preamble have been written, so that
read()will return an EOF and return all the read bytes - Confirming that calling
close()on the write fd of a pipe does not discard any bytes in flight, while the read fd is still open. This should be both as specified behaviour, and actual behaviour on common platforms. - Confirming that said behaviour is consistent when the transport is over a network, and or across privilege elevation (e.g. ssh -> sudo -> setns)
Background
Mitogen bootstraps a child process by running python -c <boot_command <decompress(b64decode(first_stage))>>. The first stage in turn reads the preamble from stdin of the child process. Currently the first stage code performs a single io.BufferedReader.read(PREAMBLE_COMPRESSED_LEN)1 call to do this, i.e.
Lines 1440 to 1442 in 058787f
| fp=os.fdopen(0,'rb') | |
| C=zlib.decompress(fp.read(PREAMBLE_COMPRESSED_LEN)) | |
| fp.close() |
BufferedReader.read(n) is only specificed to return upto n bytes. This issue is a speculative offshoot of PR #1299, which attempts add a retry loop to the firset stage.
Footnotes
-
On Python versions >= 2.6 that have the
iohierarchy. ↩