def run(self): """Worker main method""" self.worker = Worker() for host in self.servers: self.worker.add_server(host) self.register_tasks(self.task_module) # self.worker.work() blocks in libgearman.so, # so make it time out occasionally and give back control. self.worker.set_timeout(TIMEOUT) while self.is_running: # is_running is always True result = self.worker.work() if result not in [GEARMAN_SUCCESS, GEARMAN_TIMEOUT]: LOGGER.warn('Oilcan: Gearman task result code: %d', result)
class OilcanWorker(Process): """Runs in a sub-process. There can be lots of these. Listens for Gearman messages and runs tasks. """ def __init__(self, task_module, servers): super(OilcanWorker, self).__init__() self.task_module = task_module self.servers = servers self.is_running = True self.worker = None self.task_map = {} def run(self): """Worker main method""" self.worker = Worker() for host in self.servers: self.worker.add_server(host) self.register_tasks(self.task_module) # self.worker.work() blocks in libgearman.so, # so make it time out occasionally and give back control. self.worker.set_timeout(TIMEOUT) while self.is_running: # is_running is always True result = self.worker.work() if result not in [GEARMAN_SUCCESS, GEARMAN_TIMEOUT]: LOGGER.warn('Oilcan: Gearman task result code: %d', result) def register_tasks(self, task_module): """Inspect task_module and records the tasks it finds. Tasks are a function with an is_oilcan_task attribute. Usually this attribute is set via the @tasks decorator. """ system_import(task_module) tasks = sys.modules[task_module] LOGGER.debug('Oilcan: Imported: %s', tasks) for name in dir(tasks): if name.startswith('__'): continue func = getattr(tasks, name) if hasattr(func, 'is_oilcan_task'): self.task_map[name] = func self.worker.add_function(name, self.run_task) LOGGER.debug('Oilcan: Registered task "%s"', name) if not self.task_map: LOGGER.error('Oilcan: No tasks found in module "%s"', self.task_module) return def run_task(self, job): """Called by Gearman""" func = self.task_map[job.function_name()] workload = job.get_workload() func_log = '%s(%s)' % (func.__name__, workload) LOGGER.debug('Oilcan: Running task: %s', func_log) ret = None try: ret = func(workload) except Exception: # pylint: disable-msg=W0703 job.send_fail() LOGGER.exception('Exception calling %s', func_log) # Gearman tasks must return a string result return "OK" if not ret else str(ret)