def signal(self, signal_name, input=None, workflow_id=None, run_id=None, *args, **kwargs): """Records a signal event in the workflow execution history and creates a decision task. The signal event is recorded with the specified user defined ``signal_name`` and ``input`` (if provided). Default to send to oneself (for compatibility with the previous versions). :param signal_name: The name of the signal. This name must be meaningful to the target workflow. :type signal_name: str :param input: Data to attach to the WorkflowExecutionSignaled event in the target workflow execution’s history. :type input: dict :param workflow_id: Workflow ID to send the signal to. :type workflow_id: str :param run_id: Run ID to send the signal to. :type run_id: str """ if input is None: input = {} self.connection.signal_workflow_execution( self.domain.name, signal_name, workflow_id or self.workflow_id, input=format.input(input), run_id=run_id if workflow_id else self.run_id, )
def signal(self, signal_name, workflow_id, control=None, input=None, run_id=None): """Signal external workflow execution decision builder :param signal_name: name of the signal :type signal_name: str :param workflow_id: workflow id of the workflow execution to be signaled :type workflow_id: str :param control: data attached to the event that can be used by the decider in subsequent decision tasks :type control: Optional[dict] :param input: input to be provided with the signal :type input: Optional[dict] :param run_id: run id of the workflow execution to be signaled :type run_id: str """ if input is not None: input = format.input(input) if control is not None: control = format.control(control) self.update_attributes( { "signalName": signal_name, "workflowId": workflow_id, "control": control, "input": input, "runId": run_id, } )
def start_execution(self, workflow_id=None, task_list=None, child_policy=None, execution_timeout=None, input=None, tag_list=None, decision_tasks_timeout=None): """Starts a Workflow execution of current workflow type :param workflow_id: The user defined identifier associated with the workflow execution :type workflow_id: String :param task_list: task list to use for scheduling decision tasks for execution of this workflow :type task_list: String :param child_policy: policy to use for the child workflow executions of this workflow execution. :type child_policy: CHILD_POLICIES.{TERMINATE | REQUEST_CANCEL | ABANDON} :param execution_timeout: maximum duration for the workflow execution :type execution_timeout: String :param input: Input of the workflow execution :type input: dict :param tag_list: Tags associated with the workflow execution :type tag_list: String or list of strings or None :param decision_tasks_timeout: maximum duration of decision tasks for this workflow execution :type decision_tasks_timeout: String """ workflow_id = workflow_id or '%s-%s-%i' % (self.name, self.version, time.time()) task_list = task_list or self.task_list child_policy = child_policy or self.child_policy if child_policy not in CHILD_POLICIES: raise ValueError("invalid child policy value: {}".format(child_policy)) if input is None: input = {} if tag_list is not None and not isinstance(tag_list, list): tag_list = [tag_list] # checks if tag_list and len(tag_list) > 5: raise ValueError("You cannot have more than 5 tags in StartWorkflowExecution.") run_id = self.connection.start_workflow_execution( self.domain.name, workflow_id, self.name, self.version, task_list=task_list, child_policy=child_policy, execution_start_to_close_timeout=execution_timeout, input=format.input(input), tag_list=tag_list, task_start_to_close_timeout=decision_tasks_timeout, )['runId'] return WorkflowExecution(self.domain, workflow_id, run_id=run_id)
def start(self, workflow_type, workflow_id, child_policy=CHILD_POLICIES.TERMINATE, execution_timeout='300', task_timeout='300', control=None, input=None, tag_list=None, task_list=None): """Child workflow execution decision builder :param workflow_type: workflow type to start :type workflow_type: swf.models.workflow.WorkflowType :param workflow_id: unique id to recognize the workflow execution :type workflow_id: str :param child_policy: specifies the policy to use for the child workflow executions :type child_policy: CHILD_POLICIES.{TERMINATE | REQUEST_CANCEL | ABANDON} :param execution_timeout: specifies the total duration for this workflow execution :type execution_timeout: str :param input: The input provided to the child workflow execution :type input: str :param tag_list: list of tags to associate with the child workflow execution :type tag_list: list :param task_list: task list name :type task_list: str :param task_timeout: maximum duration of decision tasks for the child workflow execution :type task_timeout: str """ if input is not None: input = format.input(input) self.update_attributes({ 'childPolicy': child_policy, 'executionStartToCloseTimeout': execution_timeout, 'taskStartToCloseTimeout': task_timeout, 'control': control, 'input': input, 'tagList': tag_list, 'taskList': { 'name': task_list, }, 'workflowId': workflow_id, 'workflowType': { 'name': workflow_type.name, 'version': workflow_type.version, } })
def continue_as_new( self, child_policy=None, execution_timeout=None, task_timeout=None, input=None, tag_list=None, task_list=None, workflow_type_version=None, ): """Coninue as new workflow execution decision builder :param child_policy: specifies the policy to use for the child workflow executions of the new execution :type child_policy: CHILD_POLICIES.{TERMINATE | REQUEST_CANCEL | ABANDON} :param execution_timeout: specifies the total duration for this workflow execution :type execution_timeout: str :param input: The input provided to the new workflow execution :type input: Optional[dict] :param tag_list: list of tags to associate with the new workflow execution :type tag_list: list :param task_list: task list name :type task_list: str :param task_timeout: maximum duration of decision tasks for the new workflow execution :type task_timeout: str :param workflow_type_version: workflow type version the execution shold belong to :type workflow_type_version: str """ if input is not None: input = format.input(input) self.update_attributes( { "childPolicy": child_policy, "executionStartToCloseTimeout": execution_timeout, "taskStartToCloseTimeout": task_timeout, "input": input, "tagList": tag_list, "taskList": task_list, "workflowTypeVersion": workflow_type_version, } )
def schedule(self, activity_id, activity_type, control=None, heartbeat_timeout=None, input=None, duration_timeout=None, schedule_timeout=None, task_timeout=None, task_list=None, task_priority=None): """Schedule activity task decision builder :param activity_id: activity id of the activity task :type activity_id: String :param activity_type: type of the activity task to schedule :type activity_type: swf.models.activity.ActivityType :param control: data attached to the event that can be used by the decider in subsequent workflow tasks :type control: Optional[dict] :param heartbeat_timeout: Specifies the maximum time before which a worker processing a task of this type must report progress :type heartbeat_timeout: String :param input: input provided to the activity task :type input: Optional[dict] :param duration_timeout: Maximum duration for this activity task :type duration_timeout: String :param schedule_timeout: Specifies the maximum duration the activity task can wait to be assigned to a worker :type schedule_timeout: String :param task_timeout: Specifies the maximum duration a worker may take to process this activity task :type task_timeout: String :param task_list: Specifies the name of the task list in which to schedule the activity task :type :str :param task_priority: Specifies the numeric priority of the task to pass to SWF (defaults to None). :type task_priority: int|String """ if input is not None: input = format.input(input) if control is not None: control = format.control(control) if task_priority is not None: # NB: here we call int() so we raise early if a wrong task priority # is passed to this function. task_priority = str(int(task_priority)) self.update_attributes({ 'activityId': activity_id, 'activityType': { 'name': activity_type.name, 'version': activity_type.version, }, 'control': control, 'heartbeatTimeout': heartbeat_timeout, 'input': input, 'scheduleToCloseTimeout': duration_timeout, 'scheduleToStartTimeout': schedule_timeout, 'startToCloseTimeout': task_timeout, 'taskList': { 'name': task_list }, 'taskPriority': task_priority, })
def start( self, workflow_type, workflow_id, child_policy=CHILD_POLICIES.TERMINATE, execution_timeout="300", task_timeout="300", control=None, input=None, tag_list=None, task_list=None, ): """Child workflow execution decision builder :param workflow_type: workflow type to start :type workflow_type: swf.models.workflow.WorkflowType :param workflow_id: unique id to recognize the workflow execution :type workflow_id: str :param child_policy: specifies the policy to use for the child workflow executions :type child_policy: CHILD_POLICIES.{TERMINATE | REQUEST_CANCEL | ABANDON} :param execution_timeout: specifies the total duration for this workflow execution :type execution_timeout: str :param input: The input provided to the child workflow execution :type input: Optional[dict] :param tag_list: list of tags to associate with the child workflow execution :type tag_list: list :param task_list: task list name :type task_list: str :param task_timeout: maximum duration of decision tasks for the child workflow execution :type task_timeout: str :param control: data attached to the event that can be used by the decider in subsequent workflow tasks :type control: Optional[dict] """ if input is not None: input = format.input(input) if control is not None: control = format.control(control) self.update_attributes( { "childPolicy": child_policy, "executionStartToCloseTimeout": execution_timeout, "taskStartToCloseTimeout": task_timeout, "control": control, "input": input, "tagList": tag_list, "taskList": {"name": task_list,}, "workflowId": workflow_id, "workflowType": { "name": workflow_type.name, "version": workflow_type.version, }, } )
def standalone( context, workflow, domain, workflow_id, execution_timeout, tags, decision_tasks_timeout, input, input_file, nb_workers, nb_deciders, heartbeat, display_status, repair, force_activities, ): """ This command spawn a decider and an activity worker to execute a workflow with a single main process. """ disable_boto_connection_pooling() if force_activities and not repair: raise ValueError( "You should only use --force-activities with --repair.") workflow_class = get_workflow(workflow) if not workflow_id: workflow_id = workflow_class.name wf_input = {} if input or input_file: wf_input = get_or_load_input(input_file, input) if repair: repair_run_id = None if " " in repair: repair, repair_run_id = repair.split(" ", 1) # get the previous execution history, it will serve as "default history" # for activities that succeeded in the previous execution logger.info('retrieving history of previous execution: domain={} ' 'workflow_id={} run_id={}'.format(domain, repair, repair_run_id)) workflow_execution = get_workflow_execution(domain, repair, run_id=repair_run_id) previous_history = History(workflow_execution.history()) repair_run_id = workflow_execution.run_id previous_history.parse() # get the previous execution input if none passed if not input and not input_file: wf_input = previous_history.events[0].input if not tags: tags = workflow_execution.tag_list else: previous_history = None repair_run_id = None if not tags: get_tag_list = getattr(workflow_class, 'get_tag_list', None) if get_tag_list: tags = get_tag_list(workflow_class, *wf_input.get('args', ()), **wf_input.get('kwargs', {})) else: tags = getattr(workflow_class, 'tag_list', None) if tags == Workflow.INHERIT_TAG_LIST: tags = None task_list = create_unique_task_list(workflow_id) logger.info('using task list {}'.format(task_list)) decider_proc = multiprocessing.Process( target=decider.command.start, args=( [workflow], domain, task_list, ), kwargs={ 'nb_processes': nb_deciders, 'repair_with': previous_history, 'force_activities': force_activities, 'is_standalone': True, 'repair_workflow_id': repair or None, 'repair_run_id': repair_run_id, }, ) decider_proc.start() worker_proc = multiprocessing.Process( target=worker.command.start, args=( domain, task_list, ), kwargs={ 'nb_processes': nb_workers, 'heartbeat': heartbeat, }, ) worker_proc.start() print('starting workflow {}'.format(workflow), file=sys.stderr) ex = start_workflow.callback( workflow, domain, workflow_id, task_list, execution_timeout, tags, decision_tasks_timeout, format.input(wf_input), None, local=False, ) while True: time.sleep(2) ex = helpers.get_workflow_execution( domain, ex.workflow_id, ex.run_id, ) if display_status: print('status: {}'.format(ex.status), file=sys.stderr) if ex.status == ex.STATUS_CLOSED: print('execution {} finished'.format(ex.workflow_id), file=sys.stderr) break os.kill(worker_proc.pid, signal.SIGTERM) worker_proc.join() os.kill(decider_proc.pid, signal.SIGTERM) decider_proc.join()
def standalone(context, workflow, domain, workflow_id, execution_timeout, tags, decision_tasks_timeout, input, input_file, nb_workers, nb_deciders, heartbeat, display_status, repair, force_activities, ): """ This command spawn a decider and an activity worker to execute a workflow with a single main process. """ disable_boto_connection_pooling() if force_activities and not repair: raise ValueError( "You should only use --force-activities with --repair." ) workflow_class = get_workflow(workflow) if not workflow_id: workflow_id = workflow_class.name wf_input = {} if input or input_file: wf_input = get_or_load_input(input_file, input) if repair: repair_run_id = None if " " in repair: repair, repair_run_id = repair.split(" ", 1) # get the previous execution history, it will serve as "default history" # for activities that succeeded in the previous execution logger.info( 'retrieving history of previous execution: domain={} ' 'workflow_id={} run_id={}'.format(domain, repair, repair_run_id) ) workflow_execution = get_workflow_execution(domain, repair, run_id=repair_run_id) previous_history = History(workflow_execution.history()) repair_run_id = workflow_execution.run_id previous_history.parse() # get the previous execution input if none passed if not input and not input_file: wf_input = previous_history.events[0].input if not tags: tags = workflow_execution.tag_list else: previous_history = None repair_run_id = None if not tags: get_tag_list = getattr(workflow_class, 'get_tag_list', None) if get_tag_list: tags = get_tag_list(workflow_class, *wf_input.get('args', ()), **wf_input.get('kwargs', {})) else: tags = getattr(workflow_class, 'tag_list', None) if tags == Workflow.INHERIT_TAG_LIST: tags = None task_list = create_unique_task_list(workflow_id) logger.info('using task list {}'.format(task_list)) decider_proc = multiprocessing.Process( target=decider.command.start, args=( [workflow], domain, task_list, ), kwargs={ 'nb_processes': nb_deciders, 'repair_with': previous_history, 'force_activities': force_activities, 'is_standalone': True, 'repair_workflow_id': repair or None, 'repair_run_id': repair_run_id, }, ) decider_proc.start() worker_proc = multiprocessing.Process( target=worker.command.start, args=( domain, task_list, ), kwargs={ 'nb_processes': nb_workers, 'heartbeat': heartbeat, }, ) worker_proc.start() print('starting workflow {}'.format(workflow), file=sys.stderr) ex = start_workflow.callback( workflow, domain, workflow_id, task_list, execution_timeout, tags, decision_tasks_timeout, format.input(wf_input), None, local=False, ) while True: time.sleep(2) ex = helpers.get_workflow_execution( domain, ex.workflow_id, ex.run_id, ) if display_status: print('status: {}'.format(ex.status), file=sys.stderr) if ex.status == ex.STATUS_CLOSED: print('execution {} finished'.format(ex.workflow_id), file=sys.stderr) break os.kill(worker_proc.pid, signal.SIGTERM) worker_proc.join() os.kill(decider_proc.pid, signal.SIGTERM) decider_proc.join()