.. _doot.control.tracker.network: ============================ doot.control.tracker.network ============================ .. py:module:: doot.control.tracker.network .. autoapi-nested-parse:: The network of task relations. Uses an nx.Digraph internally. Is build 'backwards', as this preserves the meaning of graph.pred[x] = [y] as y.depends_on[x] and graph.succ[x] = [y] as y.required_for[x] Type Aliases ------------ .. autoapisummary:: doot.control.tracker.network.Abstract Classes ------- .. autoapisummary:: doot.control.tracker.network._Expansion_m doot.control.tracker.network._Validation_m doot.control.tracker.network.TrackNetwork Module Contents =============== .. py:data:: Abstract :type: TypeAlias :value: T .. doot.control.tracker.network._Expansion_m: .. py:class:: _Expansion_m .. py:attribute:: _tracker :type: doot.control.tracker._interface.WorkflowTracker_i .. py:attribute:: pred :type: collections.abc.Mapping .. py:attribute:: succ :type: collections.abc.Mapping .. py:attribute:: nodes :type: collections.abc.Mapping .. py:attribute:: edges :type: collections.abc.Mapping .. py:attribute:: _graph :type: Any .. py:attribute:: non_expanded :type: set .. py:method:: build_network(*, sources: jgdv.Maybe[Literal[True] | list[Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i]] = None) -> None for each task queued (ie: connected to the root node) expand its dependencies and add into the _graph, until no more nodes to expand. then connect concrete _tracker._registry.artifacts to abstract _tracker._registry.artifacts. passing sources=True forces build of any non_expanded nodes that have an edge # TODO _graph could be built in total, or on demand .. py:method:: connect(left: Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i, right: jgdv.Maybe[Literal[False] | Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i] = None, **kwargs) -> None Connect a task node to another. left -> right If given left, None, connect left -> API.ROOT if given left, False, just add the node (This preserves graph.pred[x] as the nodes x is dependent on) .. py:method:: _add_node(name: Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i) -> None idempotent .. py:method:: _expand_task_node(name: Concrete[doot.workflow._interface.TaskName_p]) -> set[Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i] expand a task node, instantiating and connecting to its dependencies and dependents, *without* expanding those new nodes. returns a list of the new nodes tasknames .. py:method:: _generate_successor_nodes(spec: Concrete[doot.workflow.TaskSpec]) -> list[Concrete[doot.workflow._interface.TaskName_p]] instantiate and connect a job's head task for a spec S, find the tasks T that have registered a relation of T < S. (S would not know about these blockers). For these T, link instantiated nodes that match constraints and link them to S, or if no nodes exist, create and link them. .. py:method:: _generate_blockers(name: doot.workflow._interface.TaskName_p) -> set[Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i] .. py:method:: _expand_artifact(artifact: doot.workflow._interface.Artifact_i) -> set[Concrete[doot.workflow._interface.TaskName_p] | doot.workflow._interface.Artifact_i] expand _tracker._registry.artifacts, instantiating related tasks, and connecting the task to its abstract/concrete related _tracker._registry.artifacts .. doot.control.tracker.network._Validation_m: .. py:class:: _Validation_m .. py:attribute:: _tracker :type: doot.control.tracker._interface.WorkflowTracker_i .. py:attribute:: _graph :type: Any .. py:attribute:: nodes :type: collections.abc.Mapping .. py:attribute:: edges :type: collections.abc.Mapping .. py:attribute:: pred :type: collections.abc.Mapping .. py:attribute:: succ :type: collections.abc.Mapping .. py:method:: validate_network(*, strict: bool = True) -> bool Finalise and ensure consistence of the task _graph. run tests to check the dependency graph is acceptable .. py:method:: concrete_edges(name: Concrete[doot.workflow._interface.TaskName_p | doot.workflow.TaskArtifact]) -> jgdv.structs.chainguard.ChainGuard get the concrete edges of a task. ie: the ones in the task _graph, not the abstract ones in the spec. .. py:method:: report_tree() -> None Use networkx + plt's graph drawing to inspect the constructed graph .. _doot.control.tracker.network.TrackNetwork: .. py:class:: TrackNetwork(*, tracker: doot.control.tracker._interface.WorkflowTracker_p) The _graph of concrete tasks and their dependencies .. py:attribute:: _tracker :type: doot.control.tracker._interface.WorkflowTracker_p .. py:attribute:: _graph :type: networkx.DiGraph[Concrete[doot.workflow._interface.TaskName_p] | doot.workflow.TaskArtifact] .. py:attribute:: non_expanded :type: set[doot.workflow._interface.TaskName_p | doot.workflow._interface.Artifact_i] .. py:property:: nodes :type: dict .. py:property:: edges :type: dict .. py:property:: pred :type: dict .. py:property:: adj :type: dict .. py:property:: succ :type: dict