def _execute_task(self, worker, task): # Asynchronous execution of a Task. This method is called # on a separate thread of execution from the worker event loop thread. logger = worker.logger pubsub = self._pubsub task_id = task.id lock_id = task.get('lock_id') time_ended = time.time() job = self.registry.get(task.get('name')) consumer = TaskConsumer(self, worker, task_id, job) task_info = task.lazy_info() try: if not consumer.job: raise RuntimeError('%s not in registry' % task_info) if task['status'] > states.STARTED: expiry = task.get('expiry') if expiry and time_ended > expiry: raise TaskTimeout else: logger.info('starting %s', task_info) kwargs = task.get('kwargs') or {} self.models.task.update(task, status=states.STARTED, time_started=time_ended, worker=worker.aid) pubsub.publish(self.channel('task_started'), task_id) # This may block for a while result = yield job(consumer, **kwargs) status = states.SUCCESS else: logger.error('invalid status for %s', task_info) self.concurrent_tasks.discard(task_id) coroutine_return(task_id) except TaskTimeout: logger.warning('%s timed-out', task_info) result = None status = states.REVOKED except Exception as exc: logger.exception('failure in %s', task_info) result = str(exc) status = states.FAILURE # try: yield self.models.task.update(task, time_ended=time.time(), status=status, result=result) finally: self.concurrent_tasks.discard(task_id) self.finish_task(task_id, lock_id) # logger.info('finished %s', task_info) # publish into the task_done channel pubsub.publish(self.channel('task_done'), task_id) coroutine_return(task_id)
def _execute_task(self, worker, task): # Asynchronous execution of a Task. This method is called # on a separate thread of execution from the worker event loop thread. logger = get_logger(worker.logger) pubsub = self._pubsub task_id = task['id'] lock_id = task.get('lock_id') time_ended = time.time() job = self.registry.get(task.get('name')) consumer = TaskConsumer(self, worker, task_id, job) task_info = task.lazy_info() try: if not consumer.job: raise RuntimeError('%s not in registry' % task_info) if task['status'] > states.STARTED: expiry = task.get('expiry') if expiry and time_ended > expiry: raise TaskTimeout else: logger.info('starting %s', task_info) kwargs = task.get('kwargs') or {} self.models.task.update(id=task_id, status=states.STARTED, time_started=time_ended, worker=worker.aid) pubsub.publish(self.channel('task_started'), task_id) # This may block for a while result = yield job(consumer, **kwargs) status = states.SUCCESS else: logger.error('invalid status for %s', task_info) self.concurrent_tasks.discard(task_id) coroutine_return(task_id) except TaskTimeout: logger.info('%s timed-out', task_info) result = None status = states.REVOKED except Exception as exc: logger.exception('failure in %s', task_info) result = str(exc) status = states.FAILURE # try: yield self.models.task.update(id=task_id, time_ended=time.time(), status=status, result=result) finally: self.concurrent_tasks.discard(task_id) self.finish_task(task_id, lock_id) # logger.info('finished %s', task_info) # publish into the task_done channel pubsub.publish(self.channel('task_done'), task_id) coroutine_return(task_id)
def _test_done(self, monitor, task_id=None, exc=None): runner = self.runner if task_id: self._tests_done.add(to_string(task_id)) if self._tests_queued is not None: left = self._tests_queued.difference(self._tests_done) if not left: tests = yield self.backend.get_tasks(self._tests_done) self.logger.info('All tests have finished.') time_taken = default_timer() - self._time_start for task in tests: runner.add(task.get('result')) runner.on_end() runner.printSummary(time_taken) # Shut down the arbiter if runner.result.errors or runner.result.failures: exit_code = 2 else: exit_code = 0 monitor._loop.call_soon(self._exit, exit_code)