def _get_future_from_child_workflow_event(self, event): """Maps a child workflow event to a Future with the corresponding state. :param event: child workflow event :type event: dict[str, Any] """ future = futures.Future() state = event['state'] if state == 'start_initiated': pass # future._state = futures.PENDING elif state == 'start_failed': if event['cause'] == 'WORKFLOW_TYPE_DOES_NOT_EXIST': workflow_type = swf.models.WorkflowType( self.domain, name=event['name'], version=event['version'], ) logger.info('Creating workflow type {} in domain {}'.format( workflow_type.name, self.domain.name, )) try: workflow_type.save() except swf.exceptions.AlreadyExistsError: # Could have be created by a concurrent workflow execution. pass return None future.set_exception( exceptions.TaskFailed( name=event['id'], reason=event['cause'], details=event.get('details'), )) elif state == 'started': future.set_running() elif state == 'completed': future.set_finished(json_loads_or_raw(event['result'])) elif state == 'failed': future.set_exception( exceptions.TaskFailed( name=event['id'], reason=event['reason'], details=event.get('details'), )) elif state == 'timed_out': future.set_exception( exceptions.TimeoutError( event['timeout_type'], None, )) elif state == 'canceled': future.set_exception( exceptions.TaskCanceled(event.get('details'), )) elif state == 'terminated': future.set_exception(exceptions.TaskTerminated()) return future
def get_future_from_external_workflow_event(self, a_task, event): """Maps an external workflow event to a Future with the corresponding state. :param a_task: currently unused :type a_task: :param event: external workflow event :type event: dict[str, Any] :rtype: futures.Future """ future = futures.Future() if not event: return future state = event['state'] if state == 'signal_execution_initiated': # Don't re-initiate signal sending future.set_running() elif state == 'execution_signaled': future.set_finished(event['input']) elif state == 'signal_execution_failed': future.set_exception( exceptions.TaskFailed( name=event['name'], reason=event['cause'], )) return future
def _get_future_from_timer_event(self, a_task, event): """ Maps a timer event to a Future with the corresponding state. :param a_task: Timer task; unused. :type a_task: TimerTask :param event: Timer event :type event: dict[str, Any] :return: :rtype: futures.Future """ future = futures.Future() if not event: return future state = event['state'] if state == 'started': future.set_running() elif state == 'fired': future.set_finished(None) elif state == 'canceled': future.set_cancelled() elif state in ('start_failed', 'cancel_failed'): future.set_exception(exceptions.TaskFailed( name=event['timer_id'], reason=event['cause'], )) return future
def _get_future_from_activity_event(self, event): """Maps an activity event to a Future with the corresponding state. :param event: workflow event. :type event: swf.event.Event. """ future = futures.Future() # state is PENDING. state = event['state'] if state == 'scheduled': future._state = futures.PENDING elif state == 'schedule_failed': if event['cause'] == 'ACTIVITY_TYPE_DOES_NOT_EXIST': activity_type = swf.models.ActivityType( self.domain, name=event['activity_type']['name'], version=event['activity_type']['version']) logger.info('Creating activity type {} in domain {}'.format( activity_type.name, self.domain.name)) try: activity_type.save() except swf.exceptions.AlreadyExistsError: logger.info( 'Activity type {} in domain {} already exists'.format( activity_type.name, self.domain.name)) return None logger.info('failed to schedule {}: {}'.format( event['activity_type']['name'], event['cause'], )) return None elif state == 'started': future._state = futures.RUNNING elif state == 'completed': future._state = futures.FINISHED result = event['result'] future._result = json.loads(result) if result else None elif state == 'canceled': future._state = futures.CANCELLED elif state == 'failed': future._state = futures.FINISHED future._exception = exceptions.TaskFailed( name=event['id'], reason=event['reason'], details=event.get('details'), ) elif state == 'timed_out': future._state = futures.FINISHED future._exception = exceptions.TimeoutError( event['timeout_type'], event['timeout_value']) return future
def _get_future_from_activity_event(self, event): """Maps an activity event to a Future with the corresponding state. :param event: activity event :type event: dict[str, Any] :rtype: futures.Future """ future = futures.Future() # state is PENDING. state = event['state'] if state == 'scheduled': pass elif state == 'schedule_failed': if event['cause'] == 'ACTIVITY_TYPE_DOES_NOT_EXIST': activity_type = swf.models.ActivityType( self.domain, name=event['activity_type']['name'], version=event['activity_type']['version']) logger.info('creating activity type {} in domain {}'.format( activity_type.name, self.domain.name)) try: activity_type.save() except swf.exceptions.AlreadyExistsError: logger.info( 'oops: Activity type {} in domain {} already exists, creation failed, continuing...'.format( activity_type.name, self.domain.name)) return None logger.info('failed to schedule {}: {}'.format( event['activity_type']['name'], event['cause'], )) return None elif state == 'started': future.set_running() elif state == 'completed': result = event['result'] future.set_finished(json_loads_or_raw(result)) elif state == 'canceled': future.set_cancelled() elif state == 'failed': exception = exceptions.TaskFailed( name=event['id'], reason=event['reason'], details=event.get('details')) future.set_exception(exception) elif state == 'timed_out': exception = exceptions.TimeoutError( event['timeout_type'], event['timeout_value']) future.set_exception(exception) return future
def _get_future_from_marker_event(self, a_task, event): """Maps a marker event to a Future with the corresponding state. :param a_task: currently unused :type a_task: :param event: marker event :type event: dict[str, Any] :rtype: futures.Future """ future = futures.Future() if not event: return future state = event['state'] if state == 'recorded': future.set_finished(event['details']) elif state == 'failed': future.set_exception(exceptions.TaskFailed( name=event['name'], reason=event['cause'], )) return future