def set_progress(self, status): """ Informs the server of the current state of the publish operation. The contents of the status is dependent on how the distributor implementation chooses to divide up the publish process. @param status: contains arbitrary data to describe the state of the publish; the contents may contain whatever information is relevant to the distributor implementation so long as it is serializable """ try: self.progress_report[self.report_id] = status context = dispatch_factory.context() delta = {'progress_report': self.progress_report} TaskStatusManager.update_task_status(context.call_request_id, delta) context.report_progress(self.progress_report) except Exception, e: _LOG.exception('Exception from server setting progress for report [%s]' % self.report_id) try: _LOG.error('Progress value: %s' % str(status)) except Exception: # Best effort to print this, but if its that grossly unserializable # the log will tank and we don't want that exception to bubble up pass raise self.exception_class(e), None, sys.exc_info()[2]
def set_progress(self, status): """ Informs the server of the current state of the publish operation. The contents of the status is dependent on how the distributor implementation chooses to divide up the publish process. @param status: contains arbitrary data to describe the state of the publish; the contents may contain whatever information is relevant to the distributor implementation so long as it is serializable """ if self.task_id is None: # not running within a task return try: self.progress_report[self.report_id] = status delta = {'progress_report': self.progress_report} TaskStatusManager.update_task_status(self.task_id, delta) except Exception, e: logger.exception( 'Exception from server setting progress for report [%s]' % self.report_id) try: logger.error('Progress value: %s' % str(status)) except Exception: # Best effort to print this, but if its that grossly unserializable # the log will tank and we don't want that exception to bubble up pass raise self.exception_class(e), None, sys.exc_info()[2]
def on_success(self, retval, task_id, args, kwargs): """ This overrides the success handler run by the worker when the task executes successfully. It updates state, finish_time and traceback of the relevant task status for asynchronous tasks. Skip updating status for synchronous tasks. :param retval: The return value of the task. :param task_id: Unique id of the executed task. :param args: Original arguments for the executed task. :param kwargs: Original keyword arguments for the executed task. """ logger.debug("Task successful : [%s]" % task_id) if not self.request.called_directly: delta = {'state': dispatch_constants.CALL_FINISHED_STATE, 'finish_time': dateutils.now_utc_timestamp(), 'result': retval} if isinstance(retval, TaskResult): delta['result'] = retval.return_value if retval.error: delta['error'] = retval.error.to_dict() if retval.spawned_tasks: task_list = [] for spawned_task in retval.spawned_tasks: if isinstance(spawned_task, AsyncResult): task_list.append(spawned_task.task_id) elif isinstance(spawned_task, dict): task_list.append(spawned_task['task_id']) delta['spawned_tasks'] = task_list if isinstance(retval, AsyncResult): delta['spawned_tasks'] = [retval.task_id, ] delta['result'] = None TaskStatusManager.update_task_status(task_id=task_id, delta=delta)
def on_failure(self, exc, task_id, args, kwargs, einfo): """ This overrides the error handler run by the worker when the task fails. It updates state, finish_time and traceback of the relevant task status for asynchronous tasks. Skip updating status for synchronous tasks. :param exc: The exception raised by the task. :param task_id: Unique id of the failed task. :param args: Original arguments for the executed task. :param kwargs: Original keyword arguments for the executed task. :param einfo: celery's ExceptionInfo instance, containing serialized traceback. """ logger.debug("Task failed : [%s]" % task_id) if not self.request.called_directly: now = datetime.now(dateutils.utc_tz()) finish_time = dateutils.format_iso8601_datetime(now) delta = { 'state': constants.CALL_ERROR_STATE, 'finish_time': finish_time, 'traceback': einfo.traceback } if not isinstance(exc, PulpException): exc = PulpException(str(exc)) delta['error'] = exc.to_dict() TaskStatusManager.update_task_status(task_id=task_id, delta=delta)
def test_update_missing_task_status(self): """ Tests updating a task status that doesn't exist raises the appropriate exception. """ task_id = self.get_random_uuid() try: TaskStatusManager.update_task_status(task_id, {}) except exceptions.MissingResource, e: self.assertTrue(task_id == e.resources['resource_id'])
def test_update_missing_task_status(self): """ Tests updating a task status that doesn't exist raises the appropriate exception. """ task_id = self.get_random_uuid() try: TaskStatusManager.update_task_status(task_id, {}) except exceptions.MissingResource, e: self.assertTrue(task_id == e.resources['resource_id'])
def progress(self, reply): """ Notification (reply) indicating an RMI has reported status. This information is relayed to the task coordinator. :param reply: A progress reply object. :type reply: gofer.rmi.async.Progress """ call_context = dict(reply.any) task_id = call_context['task_id'] delta = {'progress_report': reply.details} TaskStatusManager.update_task_status(task_id, delta)
def progress(self, reply): """ Notification (reply) indicating an RMI has reported status. This information is relayed to the task coordinator. :param reply: A progress reply object. :type reply: gofer.rmi.async.Progress """ call_context = dict(reply.any) task_id = call_context['task_id'] delta = {'progress_report': reply.details} TaskStatusManager.update_task_status(task_id, delta)
def test_update_task_status(self): """ Tests the successful operation of update_task_status(). """ task_id = self.get_random_uuid() queue = 'special_queue' tags = ['test-tag1', 'test-tag2'] state = 'waiting' TaskStatusManager.create_task_status(task_id, queue, tags, state) now = datetime.now(dateutils.utc_tz()) start_time = dateutils.format_iso8601_datetime(now) delta = {'start_time': start_time, 'state': 'running', 'disregard': 'ignored', 'progress_report': {'report-id': 'my-progress'}} updated = TaskStatusManager.update_task_status(task_id, delta) task_status = TaskStatusManager.find_by_task_id(task_id) self.assertEqual(task_status['start_time'], delta['start_time']) # Make sure that parse_iso8601_datetime is able to parse the start_time without errors dateutils.parse_iso8601_datetime(task_status['start_time']) self.assertEqual(task_status['state'], delta['state']) self.assertEqual(task_status['progress_report'], delta['progress_report']) self.assertEqual(task_status['queue'], queue) self.assertEqual(updated['start_time'], delta['start_time']) self.assertEqual(updated['state'], delta['state']) self.assertEqual(updated['progress_report'], delta['progress_report']) self.assertTrue('disregard' not in updated) self.assertTrue('disregard' not in task_status)
def test_update_task_status(self): """ Tests the successful operation of update_task_status(). """ task_id = self.get_random_uuid() queue = 'special_queue' tags = ['test-tag1', 'test-tag2'] state = 'waiting' TaskStatusManager.create_task_status(task_id, queue, tags, state) now = datetime.now(dateutils.utc_tz()) start_time = dateutils.format_iso8601_datetime(now) delta = { 'start_time': start_time, 'state': 'running', 'disregard': 'ignored', 'progress_report': { 'report-id': 'my-progress' } } updated = TaskStatusManager.update_task_status(task_id, delta) task_status = TaskStatusManager.find_by_task_id(task_id) self.assertEqual(task_status['start_time'], delta['start_time']) # Make sure that parse_iso8601_datetime is able to parse the start_time without errors dateutils.parse_iso8601_datetime(task_status['start_time']) self.assertEqual(task_status['state'], delta['state']) self.assertEqual(task_status['progress_report'], delta['progress_report']) self.assertEqual(task_status['queue'], queue) self.assertEqual(updated['start_time'], delta['start_time']) self.assertEqual(updated['state'], delta['state']) self.assertEqual(updated['progress_report'], delta['progress_report']) self.assertTrue('disregard' not in updated) self.assertTrue('disregard' not in task_status)
def test_update_task_status(self): """ Tests the successful operation of update_task_status(). """ task_id = self.get_random_uuid() queue = 'special_queue' tags = ['test-tag1', 'test-tag2'] state = 'waiting' TaskStatusManager.create_task_status(task_id, queue, tags, state) delta = {'start_time': dateutils.now_utc_timestamp(), 'state': 'running', 'disregard': 'ignored', 'progress_report': {'report-id': 'my-progress'}} updated = TaskStatusManager.update_task_status(task_id, delta) task_status = TaskStatusManager.find_by_task_id(task_id) self.assertEqual(task_status['start_time'], delta['start_time']) self.assertEqual(task_status['state'], delta['state']) self.assertEqual(task_status['progress_report'], delta['progress_report']) self.assertEqual(task_status['queue'], queue) self.assertEqual(updated['start_time'], delta['start_time']) self.assertEqual(updated['state'], delta['state']) self.assertEqual(updated['progress_report'], delta['progress_report']) self.assertTrue('disregard' not in updated) self.assertTrue('disregard' not in task_status)
def test_DELETE_doesnt_cancel_spawned_celery_task(self, revoke): """ Test the DELETE() which should cause a revoke call to Celery's Controller. This also tests that the spawned tasks are canceled as well. """ task_id = '1234abcd' spawned_task_id = 'spawned_task' spawned_by_spawned_task_id = 'spawned_by_spawned_task' TaskStatusManager.create_task_status(task_id) TaskStatusManager.create_task_status(spawned_task_id) TaskStatusManager.create_task_status(spawned_by_spawned_task_id) TaskStatusManager.update_task_status(task_id, delta={'spawned_tasks': [spawned_task_id]}) TaskStatusManager.update_task_status(spawned_task_id, delta={'spawned_tasks': [spawned_by_spawned_task_id]}) self.task_resource.DELETE(task_id) self.assertEqual(revoke.call_count, 1) revoke.assert_called_once_with(task_id, terminate=True)
def on_success(self, retval, task_id, args, kwargs): """ This overrides the success handler run by the worker when the task executes successfully. It updates state, finish_time and traceback of the relevant task status for asynchronous tasks. Skip updating status for synchronous tasks. :param retval: The return value of the task. :param task_id: Unique id of the executed task. :param args: Original arguments for the executed task. :param kwargs: Original keyword arguments for the executed task. """ logger.debug("Task successful : [%s]" % task_id) if not self.request.called_directly: now = datetime.now(dateutils.utc_tz()) finish_time = dateutils.format_iso8601_datetime(now) delta = {'finish_time': finish_time, 'result': retval} task_status = TaskStatusManager.find_by_task_id(task_id) # Only set the state to finished if it's not already in a complete state. This is # important for when the task has been canceled, so we don't move the task from canceled # to finished. if task_status['state'] not in constants.CALL_COMPLETE_STATES: delta['state'] = constants.CALL_FINISHED_STATE if isinstance(retval, TaskResult): delta['result'] = retval.return_value if retval.error: delta['error'] = retval.error.to_dict() if retval.spawned_tasks: task_list = [] for spawned_task in retval.spawned_tasks: if isinstance(spawned_task, AsyncResult): task_list.append(spawned_task.task_id) elif isinstance(spawned_task, dict): task_list.append(spawned_task['task_id']) delta['spawned_tasks'] = task_list if isinstance(retval, AsyncResult): delta['spawned_tasks'] = [ retval.task_id, ] delta['result'] = None TaskStatusManager.update_task_status(task_id=task_id, delta=delta)
def test_DELETE_doesnt_cancel_spawned_celery_task(self, revoke): """ Test the DELETE() which should cause a revoke call to Celery's Controller. This also tests that the spawned tasks are canceled as well. """ task_id = '1234abcd' spawned_task_id = 'spawned_task' spawned_by_spawned_task_id = 'spawned_by_spawned_task' TaskStatusManager.create_task_status(task_id) TaskStatusManager.create_task_status(spawned_task_id) TaskStatusManager.create_task_status(spawned_by_spawned_task_id) TaskStatusManager.update_task_status( task_id, delta={'spawned_tasks': [spawned_task_id]}) TaskStatusManager.update_task_status( spawned_task_id, delta={'spawned_tasks': [spawned_by_spawned_task_id]}) self.task_resource.DELETE(task_id) self.assertEqual(revoke.call_count, 1) revoke.assert_called_once_with(task_id, terminate=True)
def on_success(self, retval, task_id, args, kwargs): """ This overrides the success handler run by the worker when the task executes successfully. It updates state, finish_time and traceback of the relevant task status for asynchronous tasks. Skip updating status for synchronous tasks. :param retval: The return value of the task. :param task_id: Unique id of the executed task. :param args: Original arguments for the executed task. :param kwargs: Original keyword arguments for the executed task. """ logger.debug("Task successful : [%s]" % task_id) if not self.request.called_directly: now = datetime.now(dateutils.utc_tz()) finish_time = dateutils.format_iso8601_datetime(now) delta = {'finish_time': finish_time, 'result': retval} task_status = TaskStatusManager.find_by_task_id(task_id) # Only set the state to finished if it's not already in a complete state. This is # important for when the task has been canceled, so we don't move the task from canceled # to finished. if task_status['state'] not in constants.CALL_COMPLETE_STATES: delta['state'] = constants.CALL_FINISHED_STATE if isinstance(retval, TaskResult): delta['result'] = retval.return_value if retval.error: delta['error'] = retval.error.to_dict() if retval.spawned_tasks: task_list = [] for spawned_task in retval.spawned_tasks: if isinstance(spawned_task, AsyncResult): task_list.append(spawned_task.task_id) elif isinstance(spawned_task, dict): task_list.append(spawned_task['task_id']) delta['spawned_tasks'] = task_list if isinstance(retval, AsyncResult): delta['spawned_tasks'] = [retval.task_id, ] delta['result'] = None TaskStatusManager.update_task_status(task_id=task_id, delta=delta)
def on_failure(self, exc, task_id, args, kwargs, einfo): """ This overrides the error handler run by the worker when the task fails. It updates state, finish_time and traceback of the relevant task status for asynchronous tasks. Skip updating status for synchronous tasks. :param exc: The exception raised by the task. :param task_id: Unique id of the failed task. :param args: Original arguments for the executed task. :param kwargs: Original keyword arguments for the executed task. :param einfo: celery's ExceptionInfo instance, containing serialized traceback. """ logger.debug("Task failed : [%s]" % task_id) if not self.request.called_directly: delta = {'state': dispatch_constants.CALL_ERROR_STATE, 'finish_time': dateutils.now_utc_timestamp(), 'traceback': einfo.traceback} if not isinstance(exc, PulpException): exc = PulpException(str(exc)) delta['error'] = exc.to_dict() TaskStatusManager.update_task_status(task_id=task_id, delta=delta)