""" Pipe task runner ======================== This Pipe task runner enables data to flow through tasks. Popen object is being passed along in context. After all tasks finished, Popen object is removed from the context """ import io import subprocess from garcon import runner class Pipe(runner.BaseRunner): def execute(self, activity, context): """Execute pipe tasks. Args: activity_worker (ActivityWorker): The activity worker that owns this specific Activity Instance. context (dict): the local context of the activity (it does not include the execution context.) Most times the context will be empty since it is only filled with data that comes from the generators. """ result = dict() for current_task in self.tasks: task_context = dict(list(result.items()) + list(context.items())) resp = current_task(task_context, activity=activity) if resp is task_context: raise Exception('Updating context in task is forbidden.') result.update(resp or dict()) clean_result = dict() for key, item in result.items(): if isinstance(item, subprocess.Popen): if item.stdout is not None: item.stdout.close() elif isinstance(item, io.TextIOWrapper): # if this is a temporary file, do nothing to prevent an attempt # of serialization (this file is closed and to be deleted) pass else: clean_result.update({key: item}) return clean_result