uranusjr commented on code in PR #70805:
URL: https://github.com/apache/airflow/pull/70805#discussion_r3827704844


##########
task-sdk/src/airflow/sdk/coordinators/_subprocess.py:
##########
@@ -385,23 +432,146 @@ class SubprocessCoordinator(BaseCoordinator):
     :param task_startup_timeout: Maximum time the coordinator waits for the
         subprocess to connect to both servers, in seconds. The default is 10
         seconds.
+    :param dag_bundle_name: Locate artifacts through a configured Dag bundle 
rather
+        than an explicit root. Mutually exclusive with the subclass's explicit 
root;
+        if neither is set, the task's own bundle is used. A named bundle 
resolves to
+        the version current when the task starts; the task's own bundle uses 
the
+        run's version. Either way the resolved version is pinned for the whole 
task.
     """
 
     task_startup_timeout: float = 10.0
+    dag_bundle_name: str | None = None
+
+    _artifact_source: _ArtifactSource = attrs.field(init=False)
+    # The subclass's explicit root, recorded at construction so the base can
+    # resolve roots without knowing the subclass field name.
+    _configured_roots: list[pathlib.Path] = attrs.field(init=False, 
factory=list)
+    _active_bundle_info: BundleInfo | None = attrs.field(init=False, 
default=None)
+    _active_scan_roots: tuple[pathlib.Path, ...] | None = 
attrs.field(init=False, default=None)
+
+    @property
+    def _explicit_artifact_roots(self) -> tuple[str, Sequence[pathlib.Path]]:
+        """
+        The subclass's explicit-root kwarg name and its configured value.
+
+        The name is only used in error messages. An empty value — the default, 
for a
+        subclass that does not override this — selects task-bundle mode rather 
than
+        failing at execute time.
+        """
+        return "root", ()
+
+    def __attrs_post_init__(self) -> None:
+        self._classify_artifact_source()
+
+    def _classify_artifact_source(self) -> None:
+        """
+        Classify and validate how this coordinator locates artifacts 
(construction time).
+
+        Rejects setting both an explicit root and ``dag_bundle_name``, fails 
fast
+        when ``dag_bundle_name`` names a bundle that is not configured, and 
records
+        the resulting :class:`_ArtifactSource` and explicit root.
+        """
+        root_kwarg, configured = self._explicit_artifact_roots
+        if configured and self.dag_bundle_name is not None:
+            raise ValueError(
+                f"Set at most one of {root_kwarg!r} or 'dag_bundle_name': 
{root_kwarg!r} for an "
+                f"explicit path, 'dag_bundle_name' for a configured Dag 
bundle, or leave both "
+                f"unset to scan the task's own bundle."
+            )
+        if configured:
+            source = _ArtifactSource.EXPLICIT_ROOT
+            self._configured_roots = list(configured)
+        elif self.dag_bundle_name is not None:
+            source = _ArtifactSource.NAMED_BUNDLE
+            if not 
DagBundlesManager.is_bundle_configured(self.dag_bundle_name):
+                raise ValueError(
+                    f"Coordinator 'dag_bundle_name' references unconfigured 
Dag bundle "
+                    f"{self.dag_bundle_name!r}."
+                )
+        else:
+            source = _ArtifactSource.TASK_BUNDLE
+
+        self._artifact_source = source
+        log.debug(
+            "Coordinator artifact source selected",
+            mode=source.name,
+            dag_bundle_name=self.dag_bundle_name,
+            configured_roots=[str(root) for root in self._configured_roots],
+        )
+
+    def _init_root_source(
+        self, logger: FilteringBoundLogger
+    ) -> tuple[list[pathlib.Path], BaseDagBundle | None]:
+        """
+        Resolve the directories to scan for artifacts, dispatched on the 
classified mode.
+
+        Returns ``(roots, bundle)``: an explicit root yields no bundle 
(``None``);
+        a Dag-bundle mode returns the materialized path and the resolved 
bundle so
+        :meth:`execute_task` can hold a version lock over it. *logger* is the 
task
+        logger, so materialization failures surface in the task log.
+        """
+        if self._artifact_source is _ArtifactSource.EXPLICIT_ROOT:
+            return self._configured_roots, None
+
+        if self._artifact_source is _ArtifactSource.NAMED_BUNDLE:
+            # NAMED_BUNDLE implies dag_bundle_name is set.
+            target = BundleInfo(name=cast("str", self.dag_bundle_name))
+        else:
+            if self._active_bundle_info is None:
+                raise RuntimeError("_init_root_source requires an active task; 
call it during execute_task.")

Review Comment:
   This guard only exists because bundle info is stored on the instance instead 
of being passed in. `_init_root_source` is not supposed to be overridden or 
manually called by a subclass, so we can simply pass the bundle info into this 
function as an argument instead. 
   
   This is separate from the `_get_scan_roots` compatibility question. No 
external contract constrains this method's signature, so keeping the subclass 
hook stable doesn't require the bundle to be stashed too.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to