def save_state(self): """ Saves the state to persistent storage. """ state = { 'events': [ { 'name': event.name, 'arguments': event.arguments, } for event in self.events ], 'processed_tasks': self.processed_tasks, } if not self._running_job: self._running_job = RunningJob( initial_task_name=self.initial_task_name, additional_parameters=self.additional_parameters) self._running_job.state = state self._running_job.save()
class JobState(object): """ Represents the current state of a running job. Provides a way to persist the state and reconstruct it in order to re-run failed tasks in a job. """ def __init__(self, initial_task_name, additional_parameters=None): self.initial_task_name = initial_task_name self.additional_parameters = additional_parameters self.events = [] self.processed_tasks = [] self._running_job = None @classmethod def deserialize_running_job_state(cls, running_job): """ Deserializes a :class:`RunningJob <pts.core.models.RunningJob>` instance and returns a matching :class:`JobState`. """ instance = cls(running_job.initial_task_name) instance.additional_parameters = running_job.additional_parameters instance.events = [ Event(name=event['name'], arguments=event.get('arguments', None)) for event in running_job.state['events'] ] instance.processed_tasks = running_job.state['processed_tasks'] instance._running_job = running_job return instance def add_processed_task(self, task): """ Marks a task as processed. :param task: The task which should be marked as processed :type task: :class:`BaseTask` subclass instance """ self.events.extend(task.raised_events) self.processed_tasks.append(task.task_name()) def save_state(self): """ Saves the state to persistent storage. """ state = { 'events': [ { 'name': event.name, 'arguments': event.arguments, } for event in self.events ], 'processed_tasks': self.processed_tasks, } if not self._running_job: self._running_job = RunningJob( initial_task_name=self.initial_task_name, additional_parameters=self.additional_parameters) self._running_job.state = state self._running_job.save() def mark_as_complete(self): """ Signals that the job is finished. """ self._running_job.is_complete = True self.save_state() def events_for_task(self, task): """ :param task: The task for which relevant :class:`Event` instances should be returned. :returns: Raised events which are relevant for the given ``task`` :rtype: ``generator`` """ return ( event for event in self.events if event.name in task.DEPENDS_ON_EVENTS )