@ -939,6 +939,33 @@ class Stream(mitogen.core.Stream):
#: ExternalContext.main().
#: ExternalContext.main().
max_message_size = None
max_message_size = None
#: If :attr:`create_child` supplied a diag_fd, references the corresponding
#: :class:`DiagLogStream`, allowing it to be disconnected when this stream
#: is disconnected. Set to :data:`None` if no `diag_fd` was present.
diag_stream = None
#: Function with the semantics of :func:`create_child` used to create the
#: child process.
create_child = staticmethod ( create_child )
#: Dictionary of extra kwargs passed to :attr:`create_child`.
create_child_args = { }
#: :data:`True` if the remote has indicated that it intends to detach, and
#: should not be killed on disconnect.
detached = False
#: If :data:`True`, indicates the child should not be killed during
#: graceful detachment, as it the actual process implementing the child
#: context. In all other cases, the subprocess is SSH, sudo, or a similar
#: tool that should be reminded to quit during disconnection.
child_is_immediate_subprocess = True
#: Prefix given to default names generated by :meth:`connect`.
name_prefix = u ' local '
_reaped = False
def __init__ ( self , * args , * * kwargs ) :
def __init__ ( self , * args , * * kwargs ) :
super ( Stream , self ) . __init__ ( * args , * * kwargs )
super ( Stream , self ) . __init__ ( * args , * * kwargs )
self . sent_modules = set ( [ ' mitogen ' , ' mitogen.core ' ] )
self . sent_modules = set ( [ ' mitogen ' , ' mitogen.core ' ] )
@ -976,15 +1003,6 @@ class Stream(mitogen.core.Stream):
)
)
)
)
#: If :data:`True`, indicates the subprocess managed by us should not be
#: killed during graceful detachment, as it the actual process implementing
#: the child context. In all other cases, the subprocess is SSH, sudo, or a
#: similar tool that should be reminded to quit during disconnection.
child_is_immediate_subprocess = True
detached = False
_reaped = False
def _reap_child ( self ) :
def _reap_child ( self ) :
"""
"""
Reap the child process during disconnection .
Reap the child process during disconnection .
@ -1024,8 +1042,10 @@ class Stream(mitogen.core.Stream):
raise
raise
def on_disconnect ( self , broker ) :
def on_disconnect ( self , broker ) :
self . _reap_child ( )
super ( Stream , self ) . on_disconnect ( broker )
super ( Stream , self ) . on_disconnect ( broker )
if self . diag_stream is not None :
self . diag_stream . on_disconnect ( broker )
self . _reap_child ( )
# Minimised, gzipped, base64'd and passed to 'python -c'. It forks, dups
# Minimised, gzipped, base64'd and passed to 'python -c'. It forks, dups
# file descriptor 0 as 100, creates a pipe, then execs a new interpreter
# file descriptor 0 as 100, creates a pipe, then execs a new interpreter
@ -1129,10 +1149,6 @@ class Stream(mitogen.core.Stream):
)
)
return zlib . compress ( source . encode ( ' utf-8 ' ) , 9 )
return zlib . compress ( source . encode ( ' utf-8 ' ) , 9 )
create_child = staticmethod ( create_child )
create_child_args = { }
name_prefix = u ' local '
def start_child ( self ) :
def start_child ( self ) :
args = self . get_boot_command ( )
args = self . get_boot_command ( )
try :
try :
@ -1154,26 +1170,28 @@ class Stream(mitogen.core.Stream):
def connect ( self ) :
def connect ( self ) :
LOG . debug ( ' %r .connect() ' , self )
LOG . debug ( ' %r .connect() ' , self )
self . pid , fd , extra _fd = self . start_child ( )
self . pid , fd , diag _fd = self . start_child ( )
self . name = u ' %s . %s ' % ( self . name_prefix , self . pid )
self . name = u ' %s . %s ' % ( self . name_prefix , self . pid )
self . receive_side = mitogen . core . Side ( self , fd )
self . receive_side = mitogen . core . Side ( self , fd )
self . transmit_side = mitogen . core . Side ( self , os . dup ( fd ) )
self . transmit_side = mitogen . core . Side ( self , os . dup ( fd ) )
LOG . debug ( ' %r .connect(): child process stdin/stdout= %r ' ,
if diag_fd is not None :
self , self . receive_side . fd )
self . diag_stream = DiagLogStream ( diag_fd , self )
else :
self . diag_stream = None
LOG . debug ( ' %r .connect(): stdin= %r , stdout= %r , diag= %r ' ,
self , self . receive_side . fd , self . transmit_side . fd ,
self . diag_stream and self . diag_stream . receive_side . fd )
try :
try :
self . _connect_bootstrap ( extra_fd )
self . _connect_bootstrap ( )
except EofError :
except EofError :
self . receive_side . close ( )
self . on_disconnect ( self . _router . broker )
self . transmit_side . close ( )
e = sys . exc_info ( ) [ 1 ]
e = sys . exc_info ( ) [ 1 ]
self . _adorn_eof_error ( e )
self . _adorn_eof_error ( e )
raise
raise
except Exception :
except Exception :
self . receive_side . close ( )
self . on_disconnect ( self . _router . broker )
self . transmit_side . close ( )
if extra_fd is not None :
os . close ( extra_fd )
self . _reap_child ( )
self . _reap_child ( )
raise
raise
@ -1188,8 +1206,10 @@ class Stream(mitogen.core.Stream):
write_all ( self . transmit_side . fd , self . get_preamble ( ) )
write_all ( self . transmit_side . fd , self . get_preamble ( ) )
discard_until ( self . receive_side . fd , self . EC1_MARKER ,
discard_until ( self . receive_side . fd , self . EC1_MARKER ,
self . connect_deadline )
self . connect_deadline )
if self . diag_stream :
self . _router . broker . start_receive ( self . diag_stream )
def _connect_bootstrap ( self , extra_fd ) :
def _connect_bootstrap ( self ):
discard_until ( self . receive_side . fd , self . EC0_MARKER ,
discard_until ( self . receive_side . fd , self . EC0_MARKER ,
self . connect_deadline )
self . connect_deadline )
self . _ec0_received ( )
self . _ec0_received ( )