class Show(object): def __init__(self, name, cmd, num_flies=1, warmup_delay=0., working_dir=None, shell=False, uid=None, gid=None, send_hup=False, env=None, stopped=False, times=2, within=1., retry_in=7., max_retry=5): self.name = name self.num_flies = int(num_flies) self.warmup_delay = warmup_delay self.cmd = cmd self._fly_counter = 0 self.stopped = stopped self.max_retry = max_retry self.optnames = ("num_flies", "warmup_delay", "working_dir", "uid", "gid", "send_hup", "shell", "env", "cmd", "times", "within", "retry_in", "max_retry") if not working_dir: # working dir hasn't been set working_dir = util.get_working_dir() self.working_dir = working_dir self.flies = {} self.shell = shell self.uid = uid self.gid = gid self.env = env self.send_hup = send_hup # define flapping object self.flapping = Flapping(self, times, within, retry_in, max_retry) def __len__(self): return len(self.flies) def reap_flies(self): if self.stopped: return for wid, fly in self.flies.items(): if fly.poll() is not None: self.flapping.notify() if self.stopped: break self.flies.pop(wid) def manage_flies(self): if self.stopped: return if len(self.flies.keys()) < self.num_flies: self.spawn_flies() flies = self.flies.keys() flies.sort() while len(flies) > self.num_flies: wid = flies.pop(0) fly = self.flies.pop(wid) self.kill_fly(fly) def reap_and_manage_flies(self): self.reap_flies() self.manage_flies() def spawn_flies(self): for i in range(self.num_flies - len(self.flies.keys())): self.spawn_fly() time.sleep(self.warmup_delay) def spawn_fly(self): if self.stopped: return self._fly_counter += 1 nb_tries = 0 while nb_tries < self.max_retry: fly = None try: fly = Fly(self._fly_counter, self.cmd, wdir=self.working_dir, shell=self.shell, uid=self.uid, gid=self.gid, env=self.env) self.flies[self._fly_counter] = fly logger.info('running %s fly [pid %d]' % (self.name, fly.pid)) except OSError, e: logger.warning('error in %r: %s' % (self.name, str(e))) if fly is None: nb_tries += 1 continue else: return self.stop()