def _add_command_tasks(self, *args, **kwargs): """ adds the child tasks to our "null" task Args: *args (): **kwargs (): Returns: """ cls = self.__class__ # check if the task is capable to handle multi elements or not # pass the process task_arguments to the class if not self.per_element or not self._is_expected_iterable( getattr(self.elements, "processed", None)): _task = cls(self.arguments, is_handle_task=False, *args, **kwargs) self._append_elements_to_title(_task) self._add_command(_task) self._add_view(_task) if self.job and getattr(self.job, "append_instances", False): if self.wait_for_task: instance = author.Instance(title=self.wait_for_task.id) _task.addChild(instance) self.addChild(_task) else: # add task per element for element in self.elements.processed: _task = cls(self.arguments, is_handle_task=False, *args, **kwargs) _task.arguments.set( self.elements_id, ArgumentValue(_task.elements.initial, element)) # second intercept to prevent the addition of per element command tasks # this is important to check against iterable attributes that are # unwrapped in this for loop [1, 2, 3] --> Task1, Task2, Task3 if _task.stop_traversal(): continue self._append_elements_to_title(_task) self._add_command(_task) self._add_view(_task) if self.job and getattr(self.job, "append_instances", False): if self.wait_for_task: instance = author.Instance(title=self.wait_for_task.id) _task.addChild(instance) if self.serial: self.wait_for_task = _task self.addChild(_task)
def _add_command_tasks(self, *args, **kwargs): """ adds the child tasks to our "null" task Args: *args (): **kwargs (): Returns: """ cls = self.__class__ # check if the task is capable to handle multi elements or not # pass the process task_arguments to the class if not self.per_element or not self._is_expected_iterable(self.elements.processed): _task = cls(self.arguments, is_handle_task=False, *args, **kwargs) self._append_elements_to_title(_task) self._add_command(_task) self._add_view(_task) if self.job and getattr(self.job, "append_instances", False): if self.wait_for_task: instance = author.Instance(title=self.wait_for_task.id) _task.addChild(instance) self.addChild(_task) else: # add task per element for element in self.elements.processed: _task = cls(self.arguments, is_handle_task=False, *args, **kwargs) _task.arguments.set(self.elements_id, ArgumentValue(_task.elements.initial, element)) self._append_elements_to_title(_task) self._add_command(_task) self._add_view(_task) if self.job and getattr(self.job, "append_instances", False): if self.wait_for_task: instance = author.Instance(title=self.wait_for_task.id) _task.addChild(instance) if self.serial: self.wait_for_task = _task self.addChild(_task)
def _append_instances(self, task=None, dependent_id=""): if not task: task = self.task if task.__class__ == author.Instance: return if task.subtasks: for idx, subtask in enumerate(task.subtasks): self._append_instances(subtask, dependent_id) if task.serialsubtasks: dependent_id = subtask.id elif dependent_id: instance = author.Instance(title=dependent_id) task.addChild(instance)
def test_all(): """This test covers setting all possible attributes of the Job, Task, Command, and Iterate objects. """ job = author.Job() job.title = "all attributes job" job.after = datetime.datetime(2012, 12, 14, 16, 24, 5) job.afterjids = [1234, 5678] job.paused = True job.tier = "express" job.projects = ["animation"] job.atleast = 2 job.atmost = 4 job.newAssignment("tempdir", "/tmp") job.newDirMap(src="X:/", dst="//fileserver/projects", zone="UNC") job.newDirMap(src="X:/", dst="/fileserver/projects", zone="NFS") job.etalevel = 5 job.tags = ["tag1", "tag2", "tag3"] job.priority = 10 job.service = "linux||mac" job.envkey = ["ej1", "ej2"] job.comment = "this is a great job" job.metadata = "show=rat shot=food" job.editpolicy = "canadians" job.addCleanup(author.Command(argv="/utils/cleanup this")) job.newCleanup(argv=["/utils/cleanup", "that"]) job.addPostscript(author.Command(argv=["/utils/post", "this"])) job.newPostscript(argv="/utils/post that") compTask = author.Task() compTask.title = "render comp" compTask.resumeblock = True compCommand = author.Command() compCommand.argv = "comp /tmp/*" compTask.addCommand(compCommand) job.addChild(compTask) for i in range(2): task = author.Task() task.title = "render layer %d" % i task.id = "id%d" % i task.chaser = "chase file%i" % i task.preview = "preview file%i" % i task.service = "services&&more" task.atleast = 7 task.atmost = 8 task.serialsubtasks = 0 task.addCleanup(author.Command(argv="/utils/cleanup file%i" % i)) command = author.Command() command.argv = "prman layer%d.rib" % i command.msg = "command message" command.service = "cmdservice&&more" command.tags = ["tagA", "tagB"] command.metrics = "metrics string" command.id = "cmdid%i" % i command.refersto = "refersto%i" % i command.expand = 0 command.atleast = 1 command.atmost = 5 command.samehost = 1 command.envkey = ["e1", "e2"] command.retryrc = [1, 3, 5, 7, 9] command.resumewhile = [ "/usr/utils/grep", "-q", "Checkpoint", "file.%d.exr" % i ] command.resumepin = bool(i) task.addCommand(command) compTask.addChild(task) iterate = author.Iterate() iterate.varname = "i" iterate.frm = 1 iterate.to = 10 iterate.addToTemplate( author.Task(title="process task", argv="process command")) iterate.addChild(author.Task(title="process task", argv="ls -l")) job.addChild(iterate) instance = author.Instance(title="id1") job.addChild(instance) print job.asTcl()
def jobs_to_task(jobs, parent_task=None, wait_for_task=None): """ converts a job dependency representation to a single task dependency Recursively adds a Job's main task to a given parent task. This allows you to use the usual tuple vs list syntax to describe a dependency. Args: jobs (:obj:`list` or `tuple` :obj:`Job`): serial/parallel job dependency representation Example: [Job1, Job2] - Job1's root task runs parallel to Job2's root task (Job1, Job2) - Job2's root task runs after Job1's root task [Job1, [Job2, Job3]] - Job1's root task runs parallel to Job2's root task & Job3's root task, but Job3's root task starts when Job2's root task finishes [Job1, (Job2, Job3)] - Job3's root task runs after Job2's root task, Job2's root task runs parallel to Job1's root task parent_task (:obj: `Task`): the parent task that will change recursively root_task (:obj: `Task`): the root task that will represent the main handle for the created dependency Returns: Task: the root path holding the generated dependency """ if not parent_task: root_task = author.Task({}, title="root", id=str(uuid.uuid4())) jobs_to_task(jobs, parent_task=root_task) return root_task if isinstance(jobs, tuple): _serialtask = author.Task({}, serialsubtasks=True, title="serial", id=str(uuid.uuid4())) parent_task.addChild(_serialtask) parent_task = _serialtask elif isinstance(jobs, list): _paralleltask = author.Task({}, title="parallel", id=str(uuid.uuid4())) parent_task.addChild(_paralleltask) parent_task = _paralleltask for job_or_jobs in jobs: if isinstance(job_or_jobs, (tuple, list)): last_task = jobs_to_task(job_or_jobs, parent_task=parent_task, wait_for_task=wait_for_task) if parent_task.title == "serial": wait_for_task = last_task else: # in case we use `append_instances=True` for dynamic expansions... # ensure we properly reference the root task of the prior job and append the instance # to all commandtasks that don't have any children if job_or_jobs.append_instances and wait_for_task: tasks = [ _ for _ in job_or_jobs.flat_hierarchy["tasks"] if _.attributeByName.get("cmds") and not _.subtasks ] for task in tasks: instance = author.Instance(title=wait_for_task.id) task.addChild(instance) # for some reason addChild() doesn't have an effect parent_task.subtasks.append(job_or_jobs.task) if parent_task.title == "serial": wait_for_task = job_or_jobs.task return parent_task