3333
3434from supervisor .socket_manager import SocketManager
3535
36- from supervisor .rpcinterface import SupervisorNamespaceRPCInterface
37- from supervisor .xmlrpc import (
38- capped_int ,
39- Faults ,
40- RPCError ,
41- )
42-
4336@functools .total_ordering
4437class Subprocess (object ):
4538
@@ -200,96 +193,95 @@ def record_spawnerr(self, msg):
200193 self .config .options .logger .info ("spawnerr: %s" % msg )
201194
202195 def queue_all_dependee_processes (self , supervisor ):
203- if self .config .name not in supervisor .process_spawn_set :
204- supervisor .process_spawn_queue .append (self )
205- supervisor .process_spawn_set .add (self .config .name )
206- # all dependees that are not in queue and not in STARTING need to be added to queue.
196+ if (self .config .name not in supervisor .process_spawn_dict .keys () or
197+ self .config .name not in supervisor .process_started_dict .keys ()):
198+ supervisor .process_spawn_dict [self .config .name ] = self
207199 if self .config .depends_on is not None :
208200 for dependee in self .config .depends_on .values ():
209- if dependee .state is not ProcessStates .RUNNING :
210- ready_to_be_spawned = False
211- if dependee .state is not ProcessStates .STARTING :
212- if dependee .config .name not in supervisor .process_spawn_set :
213- supervisor .process_spawn_queue .append (dependee )
214- supervisor .process_spawn_set .add (dependee .config .name )
201+ if dependee .state is not ProcessStates .RUNNING and dependee .state is not ProcessStates .STARTING :
202+ if (dependee .config .name not in supervisor .process_spawn_dict .keys () or
203+ dependee .config .name not in supervisor .process_started_dict .keys ()):
204+ supervisor .process_spawn_dict [dependee .config .name ] = dependee
215205 dependee .queue_all_dependee_processes (supervisor )
216206
217-
218207 def spawn (self , supervisor = None ):
219208 """Start the subprocess. It must not be running already.
220209
221210 Return the process id. If the fork() call fails, return None.
222211 """
223- # spawn if all dependees are running - else add to queue if not in queue already
224- ready_to_be_spawned = True
225-
226- options = self .config .options
227- processname = as_string (self .config .name )
228-
229- if self .pid :
230- msg = 'process \' %s\' already running' % processname
231- options .logger .warn (msg )
212+ if self .config .depends_on is not None :
213+ if any ([dependee .state is not ProcessStates .RUNNING for dependee in
214+ self .config .depends_on .values ()]):
215+ self .queue_all_dependee_processes (supervisor )
232216 return
233217
234- self .killing = False
235- self .spawnerr = None
236- self .exitstatus = None
237- self .system_stop = False
238- self .administrative_stop = False
218+ options = self .config .options
219+ processname = as_string (self .config .name )
239220
240- self .laststart = time .time ()
221+ if self .pid :
222+ msg = 'process \' %s\' already running' % processname
223+ options .logger .warn (msg )
224+ return
241225
242- self ._assertInState (ProcessStates .EXITED , ProcessStates .FATAL ,
243- ProcessStates .BACKOFF , ProcessStates .STOPPED )
226+ self .killing = False
227+ self .spawnerr = None
228+ self .exitstatus = None
229+ self .system_stop = False
230+ self .administrative_stop = False
244231
245- self . change_state ( ProcessStates . STARTING )
232+ self . laststart = time . time ( )
246233
247- try :
248- filename , argv = self .get_execv_args ()
249- except ProcessException as what :
250- self .record_spawnerr (what .args [0 ])
251- self ._assertInState (ProcessStates .STARTING )
252- self .change_state (ProcessStates .BACKOFF )
253- return
234+ self ._assertInState (ProcessStates .EXITED , ProcessStates .FATAL ,
235+ ProcessStates .BACKOFF , ProcessStates .STOPPED )
254236
255- try :
256- self .dispatchers , self .pipes = self .config .make_dispatchers (self )
257- except (OSError , IOError ) as why :
258- code = why .args [0 ]
259- if code == errno .EMFILE :
260- # too many file descriptors open
261- msg = 'too many open files to spawn \' %s\' ' % processname
262- else :
263- msg = 'unknown error making dispatchers for \' %s\' : %s' % (
264- processname , errno .errorcode .get (code , code ))
265- self .record_spawnerr (msg )
266- self ._assertInState (ProcessStates .STARTING )
267- self .change_state (ProcessStates .BACKOFF )
268- return
237+ self .change_state (ProcessStates .STARTING )
269238
270- try :
271- pid = options .fork ()
272- except OSError as why :
273- code = why .args [0 ]
274- if code == errno .EAGAIN :
275- # process table full
276- msg = ('Too many processes in process table to spawn \' %s\' ' %
277- processname )
278- else :
279- msg = 'unknown error during fork for \' %s\' : %s' % (
280- processname , errno .errorcode .get (code , code ))
281- self .record_spawnerr (msg )
282- self ._assertInState (ProcessStates .STARTING )
283- self .change_state (ProcessStates .BACKOFF )
284- options .close_parent_pipes (self .pipes )
285- options .close_child_pipes (self .pipes )
286- return
239+ try :
240+ filename , argv = self .get_execv_args ()
241+ except ProcessException as what :
242+ self .record_spawnerr (what .args [0 ])
243+ self ._assertInState (ProcessStates .STARTING )
244+ self .change_state (ProcessStates .BACKOFF )
245+ return
287246
288- if pid != 0 :
289- return self ._spawn_as_parent (pid )
247+ try :
248+ self .dispatchers , self .pipes = self .config .make_dispatchers (self )
249+ except (OSError , IOError ) as why :
250+ code = why .args [0 ]
251+ if code == errno .EMFILE :
252+ # too many file descriptors open
253+ msg = 'too many open files to spawn \' %s\' ' % processname
254+ else :
255+ msg = 'unknown error making dispatchers for \' %s\' : %s' % (
256+ processname , errno .errorcode .get (code , code ))
257+ self .record_spawnerr (msg )
258+ self ._assertInState (ProcessStates .STARTING )
259+ self .change_state (ProcessStates .BACKOFF )
260+ return
290261
262+ try :
263+ pid = options .fork ()
264+ except OSError as why :
265+ code = why .args [0 ]
266+ if code == errno .EAGAIN :
267+ # process table full
268+ msg = ('Too many processes in process table to spawn \' %s\' ' %
269+ processname )
291270 else :
292- return self ._spawn_as_child (filename , argv )
271+ msg = 'unknown error during fork for \' %s\' : %s' % (
272+ processname , errno .errorcode .get (code , code ))
273+ self .record_spawnerr (msg )
274+ self ._assertInState (ProcessStates .STARTING )
275+ self .change_state (ProcessStates .BACKOFF )
276+ options .close_parent_pipes (self .pipes )
277+ options .close_child_pipes (self .pipes )
278+ return
279+
280+ if pid != 0 :
281+ return self ._spawn_as_parent (pid )
282+
283+ else :
284+ return self ._spawn_as_child (filename , argv )
293285
294286 def _spawn_as_parent (self , pid ):
295287 # Parent
@@ -677,7 +669,7 @@ def __repr__(self):
677669 def get_state (self ):
678670 return self .state
679671
680- def transition (self , supervisord_instance = None ):
672+ def transition (self , supervisor = None ):
681673 now = time .time ()
682674 state = self .state
683675
@@ -698,15 +690,7 @@ def transition(self, supervisord_instance=None):
698690 self .spawn (supervisor )
699691 elif state == ProcessStates .STOPPED and not self .laststart :
700692 if self .config .autostart :
701- # STOPPED -> STARTING
702- # make sure dependent processes are spawned before
703- # check if the process is dependent upon any other process and if so,
704- # make sure that one is in the RUNNING state
705- if self .config .depends_on is not None :
706- rpc_interface = SupervisorNamespaceRPCInterface (supervisord_instance )
707- rpc_interface .startProcess (self .group .config .name + ':' + self .config .name )
708- else :
709- self .spawn ()
693+ self .spawn (supervisor )
710694 elif state == ProcessStates .BACKOFF :
711695 if self .backoff <= self .config .startretries :
712696 if now > self .delay :
@@ -715,7 +699,7 @@ def transition(self, supervisord_instance=None):
715699
716700 processname = as_string (self .config .name )
717701 if state == ProcessStates .STARTING :
718- if now - self .laststart > self .config .startsecs and not self . config . runningregex :
702+ if now - self .laststart > self .config .startsecs :
719703 # STARTING -> RUNNING if the proc has started
720704 # successfully and it has stayed up for at least
721705 # proc.config.startsecs,
@@ -728,27 +712,6 @@ def transition(self, supervisord_instance=None):
728712 '> than %s seconds (startsecs)' % self .config .startsecs )
729713 logger .info ('success: %s %s' % (processname , msg ))
730714
731- if self .config .runningregex :
732- logfile = getattr (self .config , 'stdout_logfile' )
733- logfile_as_str = as_string (readFile (logfile , self .log_offset , 0 ))
734-
735- # delete ascii escape sequence and newlines with regular expression
736- ansi_escape = re .compile (r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]|\n' )
737- logfile_as_str = ansi_escape .sub ('' , logfile_as_str )
738-
739- # STARTING -> RUNNING if the process has started
740- # successfully and the runningregex is met
741- if self .config .runningregex .match (logfile_as_str ):
742- self .delay = 0
743- self .backoff = 0
744- self ._assertInState (ProcessStates .STARTING )
745- self .change_state (ProcessStates .RUNNING )
746- msg = ('entered RUNNING state, found runningregex in stdout' )
747- logger .info ('success: %s %s' % (processname , msg ))
748-
749-
750-
751-
752715 if state == ProcessStates .BACKOFF :
753716 if self .backoff > self .config .startretries :
754717 # BACKOFF -> FATAL if the proc has exceeded its number
@@ -894,9 +857,9 @@ def before_remove(self):
894857 pass
895858
896859class ProcessGroup (ProcessGroupBase ):
897- def transition (self , supervisord_instance ):
860+ def transition (self , supervisor ):
898861 for proc in self .processes .values ():
899- proc .transition (supervisord_instance )
862+ proc .transition (supervisor )
900863
901864class FastCGIProcessGroup (ProcessGroup ):
902865
0 commit comments