amoghrajesh commented on code in PR #70298:
URL: https://github.com/apache/airflow/pull/70298#discussion_r3987980089


##########
registry/src/css/tokens.css:
##########
@@ -96,6 +97,8 @@
   --color-rose-600: #e11d48;
   --color-teal-400: #2dd4bf;
   --color-teal-500: #14b8a6;
+  --color-teal-600: #0d9488;

Review Comment:
   Handled in ef2d05c5bf



##########
registry/src/provider-version.njk:
##########
@@ -403,6 +427,9 @@ eleventyComputed:
               {% if module.supports_durable_execution %}
               <span class="durable-badge" title="Reconnects to an 
already-running job on retry instead of resubmitting. Requires durable=True 
(default) and depends on operator configuration.">Durable</span>
               {% endif %}
+              {% if module.supports_deferrable %}
+              <span class="deferrable-badge" title="Frees the worker slot 
while waiting. If the Triggerer crashes, another one picks it up using the same 
trigger class and arguments. Requires deferrable=True.">Deferrable</span>

Review Comment:
   Handled in ef2d05c5bf



##########
dev/registry/extract_parameters.py:
##########
@@ -463,7 +499,7 @@ def discover_classes_from_provider(
     """Discover classes from a single provider by importing its modules at 
runtime.
 
     Reads the provider.yaml to find which modules/classes to inspect, imports 
them,
-    and returns metadata for each discovered class with all 12 Module fields.
+    and returns metadata for each discovered class with all 13 Module fields.

Review Comment:
   Handled in ef2d05c5bf



##########
dev/registry/extract_parameters.py:
##########
@@ -432,6 +433,41 @@ def is_durable_capable(cls: type, resumable_mixin: type | 
None) -> bool:
     return "execute_resumable" in source
 
 
+# Hand verified set that contains classes where self.defer()/self.deferrable 
is reachable only
+# through a helper method one call away from execute() (e.g. 
TriggerDagRunOperator
+# delegates to _trigger_dag_af_2()), so the source grep below can't find it.
+# Add an entry only after confirming self.defer() is genuinely reachable.
+_DEFERRABLE_EXCEPTIONS = {
+    
"airflow.providers.standard.operators.trigger_dagrun.TriggerDagRunOperator",
+}
+
+
+def supports_deferrable(cls: type) -> bool:
+    """Return True if the class's resolved execute() actually references 
deferral.
+
+    Checking for a `deferrable` constructor parameter isn't enough: a subclass 
can
+    inherit the parameter while overriding execute() with code that never 
reads it,
+    and an operator that always defers unconditionally has no parameter
+    to find at all. Resolving execute() via getattr and checking its own 
source for
+    self.deferrable or self.defer answers "does this code path use deferral"
+    directly, instead of proxying through whether a setting merely exists 
somewhere
+    in the class hierarchy.
+    """
+    qualified_name = f"{cls.__module__}.{cls.__qualname__}"
+    if qualified_name in _DEFERRABLE_EXCEPTIONS:
+        return True
+
+    execute = getattr(cls, "execute", None)
+    if execute is None:
+        return False
+    try:
+        source = inspect.getsource(execute)
+    except (OSError, TypeError):
+        return False
+
+    return "self.deferrable" in source or "self.defer" in source

Review Comment:
   Handled in ef2d05c5bf



-- 
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