77import os , sys
88import time
99import json_parser as json
10+ import commands
1011
1112class Worker (object ):
1213 """Defines a worker. The ``pyres_worker`` script instantiates this Worker class and
@@ -22,6 +23,7 @@ def __init__(self, queues=[], server="localhost:6379", password=None):
2223 self ._shutdown = False
2324 self .child = None
2425 self .pid = os .getpid ()
26+ self .hostname = os .uname ()[1 ]
2527 if isinstance (server ,basestring ):
2628 self .resq = ResQ (server = server , password = password )
2729 elif isinstance (server , ResQ ):
@@ -62,8 +64,21 @@ def unregister_worker(self):
6264 Stat ("processed:%s" % self , self .resq ).clear ()
6365 Stat ("failed:%s" % self , self .resq ).clear ()
6466
67+ def prune_dead_workers (self ):
68+ all_workers = Worker .all (self .resq )
69+ known_workers = self .worker_pids ()
70+ for worker in all_workers :
71+ host , pid , queues = worker .id .split (':' )
72+ if host != self .hostname :
73+ continue
74+ if pid in known_workers :
75+ continue
76+ logging .warning ("pruning dead worker: %s" % worker )
77+ worker .unregister_worker ()
78+
6579 def startup (self ):
6680 self .register_signal_handlers ()
81+ self .prune_dead_workers ()
6782 self .register_worker ()
6883
6984 def register_signal_handlers (self ):
@@ -83,12 +98,11 @@ def kill_child(self, signum, frame):
8398 if self .child :
8499 logging .info ("Killing child at %s" % self .child )
85100 os .kill (self .child , signal .SIGKILL )
86-
101+
87102 def __str__ (self ):
88103 if getattr (self ,'id' , None ):
89104 return self .id
90- hostname = os .uname ()[1 ]
91- return '%s:%s:%s' % (hostname , self .pid , ',' .join (self .queues ))
105+ return '%s:%s:%s' % (self .hostname , self .pid , ',' .join (self .queues ))
92106
93107 def work (self , interval = 5 ):
94108 """Invoked by ``run`` method. ``work`` listens on a list of queues and sleeps
@@ -204,6 +218,13 @@ def processing(self):
204218
205219 def state (self ):
206220 return 'working' if self .resq .redis .exists ('resque:worker:%s' % self ) else 'idle'
221+
222+ def worker_pids (self ):
223+ """Returns an array of all pids (as strings) of the workers on
224+ this machine. Used when pruning dead workers."""
225+ return map (lambda l : l .split (' ' )[0 ],
226+ commands .getoutput ("ps -A -o pid,command | \
227+ grep pyres_worker" ).split ("\n " ))
207228
208229 @classmethod
209230 def run (cls , queues , server , interval ):
0 commit comments