Exemplo n.º 1
0
 async def start_task(self, desc: TaskDescription,
                      reason: str) -> Optional[RunningTask]:
     existing = first(lambda x: x.descriptor.id == desc.id and x.is_active,
                      self.tasks.values())
     if existing:
         if desc.on_surpass == TaskSurpassBehaviour.Skip:
             log.info(
                 f"Task {desc.name} has been triggered. Since the last job is not finished, "
                 f"the execution will be skipped, as defined by the task")
             return None
         elif desc.on_surpass == TaskSurpassBehaviour.Replace:
             log.info(
                 f"New task {desc.name} should replace existing run: {existing.id}."
             )
             existing.end()
             await self.store_running_task_state(existing)
             return await self.start_task_directly(desc, reason)
         elif desc.on_surpass == TaskSurpassBehaviour.Parallel:
             log.info(
                 f"New task {desc.name} will race with existing run {existing.id}."
             )
             return await self.start_task_directly(desc, reason)
         elif desc.on_surpass == TaskSurpassBehaviour.Wait:
             log.info(
                 f"New task {desc.name} with reason {reason} will run when existing run {existing.id} is done."
             )
             self.start_when_done[desc.id] = desc
             return None
         else:
             raise AttributeError(
                 f"Surpass behaviour not handled: {desc.on_surpass}")
     else:
         return await self.start_task_directly(desc, reason)
Exemplo n.º 2
0
 async def delete_job(self, job_id: str) -> Optional[Job]:
     job: Optional[Job] = first(lambda j: j.id == job_id, self.jobs)
     if job:
         self.jobs.remove(job)
         return job
     else:
         return None
Exemplo n.º 3
0
 async def start_task_by_descriptor_id(self,
                                       uid: str) -> Optional[RunningTask]:
     td = first(lambda t: t.id == uid, self.task_descriptions)
     if td:
         return await self.start_task(td, "direct")
     else:
         raise NameError(f"No task with such id: {uid}")
Exemplo n.º 4
0
    def prop_name_kind(
        path: str
    ) -> Tuple[str, ResolvedProperty,
               Optional[str]]:  # prop_name, prop, merge_name
        merge_name = first(lambda name: path.startswith(name + "."),
                           merge_names)
        # remove merge_name and section part (if existent) from the path
        lookup = Section.without_section(
            path[len(merge_name) + 1:] if merge_name else path)  # noqa: E203
        resolved = model.property_by_path(lookup)

        def synthetic_path(synth: SyntheticProperty) -> str:
            before, after = path.rsplit(resolved.prop.name, 1)
            return f'{before}{".".join(synth.path)}{after}'

        def escape_part(path_part: str) -> str:
            return f"`{path_part}`" if path_part.lower(
            ) in escape_aql_parts else path_part

        prop_name = synthetic_path(
            resolved.prop.synthetic) if resolved.prop.synthetic else path

        # make sure the path does not contain any aql keywords
        prop_name = ".".join(escape_part(pn) for pn in prop_name.split("."))

        return prop_name, resolved, merge_name
Exemplo n.º 5
0
 def find_term(self, fn: Callable[[Term], bool]) -> Optional[Term]:
     if fn(self):
         return self
     if isinstance(self, CombinedTerm):
         return self.left.find_term(fn) or self.right.find_term(fn)
     elif isinstance(self, NotTerm):
         return self.term.find_term(fn)
     elif isinstance(self, MergeTerm):
         return (
             self.pre_filter.find_term(fn) or
             (self.post_filter.find_term(fn) if self.post_filter else None)
             or first(
                 lambda mq: first(lambda p: p.term.find_term(fn), mq.query.
                                  parts), self.merge))
     else:
         return None
Exemplo n.º 6
0
 def property_by_path(self, path_: str) -> ResolvedProperty:
     path = PropertyPath.from_path(path_)
     found: Optional[ResolvedProperty] = first(
         lambda prop: prop.path.same_as(path), self.__property_kind_by_path)
     # if the path is not known according to known model: it could be anything.
     return found if found else ResolvedProperty(path, Property.any_prop(),
                                                 AnyKind())
Exemplo n.º 7
0
 def handle_command_results(self, results: Dict[TaskCommand, Any]) -> None:
     found = first(
         lambda r: isinstance(r, ExecuteOnCLI) and r.command == self.execute
         .command, results.keys())
     if found:
         log.info(
             f"Result of command {self.execute.command} is {results[found]}"
         )
         self.execution_done = True
Exemplo n.º 8
0
 async def find() -> AnyT:
     result = first(
         lambda m: isinstance(m, t) and m.message_type == message_type,
         all_events)  # type: ignore
     if result:
         return result  # type: ignore
     elif utc() > stop_at:
         raise TimeoutError()
     else:
         await asyncio.sleep(0.1)
         return await find()
Exemplo n.º 9
0
    def ack_for(self, message_type: str,
                subscriber: Subscriber) -> Optional[Message]:
        """
        Return the ack received ack for the given message_type of the given subscriber or None.
        """
        def relevant_ack(message: Message) -> bool:
            return (isinstance(message, (ActionDone, ActionError))
                    and message.message_type == message_type
                    and message.subscriber_id == subscriber.id)

        return first(relevant_ack, self.received_messages)
Exemplo n.º 10
0
 async def add_job(self, job: Job) -> None:
     descriptions = list(self.task_descriptions)
     existing = first(lambda td: td.id == job.id, descriptions)
     if existing:
         if not existing.mutable:
             raise AttributeError(f"There is an existing job with this {job.id} which can not be deleted!")
         log.info(f"Job with id {job.id} already exists. Update this job.")
         descriptions.remove(existing)
     # store in database
     await self.job_db.update(job)
     descriptions.append(job)
     self.task_descriptions = descriptions
     await self.update_trigger(job)
Exemplo n.º 11
0
 def handle_command_results(self, results: Dict[TaskCommand, Any]) -> None:
     found = first(
         lambda r: isinstance(r, ExecuteOnCLI) and r.command == self.execute
         .command, results.keys())
     if found:
         result = results[found]
         if isinstance(result, Exception):
             log.warning(
                 f"Command {self.execute.command} failed with error: {result}"
             )
         else:
             log.info(
                 f"Result of command {self.execute.command} is {result}")
         self.execution_done = True
Exemplo n.º 12
0
 async def delete_job(self, job_id: str) -> Optional[Job]:
     job: Job = first(lambda td: td.id == job_id and isinstance(td, Job), self.task_descriptions)  # type: ignore
     if job:
         if not job.mutable:
             raise AttributeError(f"Can not delete job: {job.id} - it is defined in a system file!")
         # delete all running tasks of this job
         for task in list(filter(lambda x: x.descriptor.id == job.id, self.tasks.values())):
             log.info(f"Job: {job_id}: delete running task: {task.id}")
             await self.delete_running_task(task)
         await self.job_db.delete(job_id)
         descriptions = list(self.task_descriptions)
         descriptions.remove(job)
         self.task_descriptions = descriptions
         await self.update_trigger(job, register=False)
     return job
Exemplo n.º 13
0
    def prop_name_kind(
        path: str
    ) -> Tuple[str, ResolvedProperty,
               Optional[str]]:  # prop_name, prop, merge_name
        merge_name = first(lambda name: path.startswith(name + "."),
                           merge_names)
        # remove merge_name and section part (if existent) from the path
        lookup = Section.without_section(
            path[len(merge_name) + 1:] if merge_name else path)  # noqa: E203
        resolved = model.property_by_path(lookup)

        def synthetic_path(synth: SyntheticProperty) -> str:
            before, after = path.rsplit(resolved.prop.name, 1)
            return f'{before}{".".join(synth.path)}{after}'

        prop_name = synthetic_path(
            resolved.prop.synthetic) if resolved.prop.synthetic else path

        return prop_name, resolved, merge_name
Exemplo n.º 14
0
 def step_by_name(self, name: str) -> Optional[Step]:
     return first(lambda x: x.name == name, self.steps)