<s> import os <EOL> import shlex <EOL> from uuid import uuid4 <EOL> from twisted . python import log <EOL> from twisted . internet . error import ProcessExitedAlready <EOL> from twisted . internet . protocol import ProcessProtocol <EOL> from twisted . spread . pb import Referenceable <EOL> from rce . monitor . common import ArgumentMixin <EOL> class NodeProtocol ( ProcessProtocol ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , monitor , out , err ) : <EOL> self . _monitor = monitor <EOL> self . _out = open ( out , '<STR_LIT:w>' ) <EOL> self . _err = open ( err , '<STR_LIT:w>' ) <EOL> self . outReceived = self . _out . write <EOL> self . errReceived = self . _err . write <EOL> def connectionMade ( self ) : <EOL> self . _monitor . started ( ) <EOL> def processEnded ( self , reason ) : <EOL> self . _monitor . stopped ( reason . value . exitCode ) <EOL> self . _monitor = None <EOL> def __del__ ( self ) : <EOL> self . _out . close ( ) <EOL> self . _err . close ( ) <EOL> class Node ( Referenceable , ArgumentMixin ) : <EOL> """<STR_LIT>""" <EOL> _STOP_ESCALATION = [ ( '<STR_LIT>' , <NUM_LIT:15> ) , ( '<STR_LIT>' , <NUM_LIT:2> ) , ( '<STR_LIT>' , None ) ] <EOL> _LOG_DIR = '<STR_LIT>' <EOL> def __init__ ( self , owner , pkg , exe , args , name , namespace ) : <EOL> """<STR_LIT>""" <EOL> ArgumentMixin . __init__ ( self , owner . loader ) <EOL> owner . registerNode ( self ) <EOL> self . _owner = owner <EOL> self . _reactor = owner . reactor <EOL> self . _call = None <EOL> self . _protocol = None <EOL> cmd = [ self . _loader . findNode ( pkg , exe ) ] <EOL> args = self . processArgument ( args ) <EOL> cmd += shlex . split ( args ) <EOL> if name : <EOL> cmd . append ( '<STR_LIT>' . format ( name ) ) <EOL> if namespace : <EOL> cmd . append ( '<STR_LIT>' . format ( namespace ) ) <EOL> uid = uuid4 ( ) . hex <EOL> out = os . path . join ( self . _LOG_DIR , <EOL> '<STR_LIT>' . format ( uid , name or exe ) ) <EOL> err = os . path . join ( self . _LOG_DIR , <EOL> '<STR_LIT>' . format ( uid , name or exe ) ) <EOL> self . _protocol = NodeProtocol ( self , out , err ) <EOL> log . msg ( '<STR_LIT>' <EOL> '<STR_LIT>' . format ( namespace , name or exe , pkg , exe ) ) <EOL> self . _reactor . spawnProcess ( self . _protocol , cmd [ <NUM_LIT:0> ] , cmd , env = os . environ ) <EOL> self . _name = '<STR_LIT>' . format ( pkg , exe ) <EOL> def started ( self ) : <EOL> """<STR_LIT>""" <EOL> def stopped ( self , exitCode ) : <EOL> """<STR_LIT>""" <EOL> self . _protocol = None <EOL> if self . _call : <EOL> self . _call . cancel ( ) <EOL> if exitCode : <EOL> log . msg ( '<STR_LIT>' <EOL> '<STR_LIT>' . format ( self . _name , exitCode ) ) <EOL> if self . _owner : <EOL> self . _owner . unregisterNode ( self ) <EOL> self . _owner = None <EOL> def remote_destroy ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _destroy ( ) <EOL> def _destroy ( self , lvl = <NUM_LIT:0> ) : <EOL> if not self . _protocol : <EOL> return <EOL> cmd , delay = self . _STOP_ESCALATION [ lvl ] <EOL> try : <EOL> self . _protocol . transport . signalProcess ( cmd ) <EOL> except ProcessExitedAlready : <EOL> return <EOL> if delay is not None : <EOL> self . _call = self . _reactor . callLater ( delay , self . _destroy , lvl + <NUM_LIT:1> ) <EOL> else : <EOL> self . _call = None </s>
