예제 #1
0
    def get_all_task_runs(self) -> List["TaskRunView"]:
        """
        Get all task runs for this flow run in a single query. Finished task run data
        is cached so future lookups do not query the backend.

        Returns:
            A list of TaskRunView objects
        """
        if len(self.get_task_run_ids()) > 1000:
            raise ValueError(
                "Refusing to `get_all_task_runs` for a flow with more than 1000 tasks. "
                "Please load the tasks you are interested in individually.")

        # Run a single query instead of querying for each task run separately
        task_run_data = TaskRunView._query_for_task_runs(
            where={
                "flow_run_id": {
                    "_eq": self.flow_run_id
                },
                "id": {
                    "_nin": list(self._cached_task_runs.keys())
                },
            })

        new_task_runs = [
            TaskRunView._from_task_run_data(data) for data in task_run_data
        ]

        task_runs = new_task_runs + list(self._cached_task_runs.values())

        for task_run in new_task_runs:
            self._cache_task_run_if_finished(task_run)

        return task_runs
예제 #2
0
    def from_flow_run_id(
        cls,
        flow_run_id: str,
        load_static_tasks: bool = False,
        _cached_task_runs: Iterable["TaskRunView"] = None,
    ) -> "FlowRunView":
        """
        Get an instance of this class filled with information by querying for the given
        flow run id

        Args:
            - flow_run_id: the flow run id to lookup
            - load_static_tasks: Pre-populate the task runs with results from flow tasks
                that are unmapped.
            - _cached_task_runs: Pre-populate the task runs with an existing iterable of
                task runs

        Returns:
            A populated `FlowRunView` instance
        """
        flow_run_data = cls._query_for_flow_run(
            where={"id": {
                "_eq": flow_run_id
            }})

        if load_static_tasks:
            task_run_data = TaskRunView._query_for_task_runs(where={
                "map_index": {
                    "_eq": -1
                },
                "flow_run_id": {
                    "_eq": flow_run_id
                },
            }, )
            task_runs = [
                TaskRunView._from_task_run_data(data) for data in task_run_data
            ]

        else:
            task_runs = []

        # Combine with the provided `_cached_task_runs` iterable
        task_runs = task_runs + list(_cached_task_runs or [])

        return cls._from_flow_run_data(flow_run_data, task_runs=task_runs)
예제 #3
0
    def get_task_run(
        self,
        task_slug: str = None,
        task_run_id: str = None,
        map_index: int = None,
    ) -> "TaskRunView":
        """
        Get information about a task run from this flow run. Lookup is available by one
        of the arguments. If the task information is not available locally already,
        we will query the database for it. If multiple arguments are provided, we will
        validate that they are consistent with each other.

        All retrieved task runs that are finished will be cached to avoid re-querying in
        repeated calls

        Args:
            - task_slug: A task slug string to use for the lookup
            - task_run_id: A task run uuid to use for the lookup
            - map_index: If given a slug of a mapped task, an index may be provided to
                get the the task run for that child task instead of the parent. This
                value will only be used for a consistency check if passed with a
                `task_run_id`

        Returns:
            A cached or newly constructed TaskRunView instance
        """

        if task_run_id is not None:
            # Load from the cache if available or query for results
            result = (self._cached_task_runs[task_run_id]
                      if task_run_id in self._cached_task_runs else
                      TaskRunView.from_task_run_id(task_run_id))

            if task_slug is not None and result.task_slug != task_slug:
                raise ValueError(
                    "Both `task_slug` and `task_run_id` were provided but the task "
                    "found using `task_run_id` has a different slug! "
                    f"`task_slug == {task_slug!r}` and "
                    f"`result.task_slug == {result.task_slug!r}`")

            if map_index is not None and result.map_index != map_index:
                raise ValueError(
                    "Both `map_index` and `task_run_id` were provided but the task "
                    "found using `task_run_id` has a different map index! "
                    f"`map_index == {map_index}` and "
                    f"`result.map_index == {result.map_index}`")

            self._cache_task_run_if_finished(result)
            return result

        if task_slug is not None:

            # Default to loading the parent task
            if map_index is None:
                map_index = -1

            # Check the cache
            task_run_id = self._slug_index_to_cached_id.get(
                (task_slug, map_index))
            if task_run_id:
                return self._cached_task_runs[task_run_id]

            result = TaskRunView.from_task_slug(task_slug=task_slug,
                                                flow_run_id=self.flow_run_id,
                                                map_index=map_index)
            self._cache_task_run_if_finished(result)
            return result

        raise ValueError(
            "One of `task_run_id`, `task`, or `task_slug` must be provided!")