dkling-it opened a new pull request, #72391:
URL: https://github.com/apache/airflow/pull/72391

   
   related: #45227
   
   ### The problem
   
   `clear_orphaned_import_errors` needs the full set of files in a bundle, so 
it runs only
   after a bundle has been refreshed. While a bundle is inside its 
`refresh_interval`,
   `should_skip_refresh` returns `True` and the loop continues before reaching 
that cleanup.
   A Dag file deleted between two refreshes therefore keeps showing an import 
error in the UI
   for up to `[dag_processor] refresh_interval` seconds, 300 by default.
   
   The permanent form of #45227 reported against 2.x is already fixed by #58242 
and #63617.
   What is left is this window, in which the UI reports an error for a file 
that is gone.
   
   ### Why the tests did not catch it
   
   Every bundle fixture pins the interval to zero:
   
   ```python
   # airflow-core/tests/conftest.py
   "kwargs": {"path": str(path), "refresh_interval": 0},
   ```
   
   With that setting the refresh is never skipped, so 
`test_remove_file_clears_import_error`
   always takes the refreshed path. The new test configures a bundle with the 
production
   default of 300 and spies on `clear_orphaned_import_errors` to confirm the 
post-refresh
   cleanup really did not run.
   
   ### The change
   
   On the skip path, check only the paths that already have a stored import 
error instead of
   listing the bundle. There are normally none, so this costs one query and no 
filesystem
   access. The `refresh_interval` throttle is untouched, so nothing is 
refreshed or scanned
   more often than before.
   
   Entries inside an archive are left for the next refresh. They are detected 
with the
   existing `correct_maybe_zipped`, which keeps the guarantee from #63617 that 
zip import
   errors are not cleared while their archive is still present.
   
   Only import errors are reconciled here, not `deactivate_deleted_dags`. 
Stored import
   errors are normally zero rows, whereas checking Dag rows the same way would 
mean a
   `stat()` per Dag on every pass. Deleted Dags are still deactivated by the 
next refresh.
   
   On query volume: `_refresh_dag_bundles` already calls `get_bundle_state` 
once per bundle
   per check, before the skip test, so this goes from one round trip to two 
rather than
   adding one where there were none.
   
   If a path is briefly unreadable, say while a bundle checkout is being 
replaced, the error
   is cleared and then recreated by the next parse of the still failing file.
   
   ### Alternatives
   
   Lifting the orphan cleanup out of the skip, as suggested on the issue, needs 
a full bundle
   listing on every check. `bundle_refresh_check_interval` is 5s, so that is 
60x more
   directory walks at the default interval, which is the cost @uranusjr raised 
there.
   
   A CLI command to clear import errors was suggested when `airflow dags` was 
still the
   primary surface. `dag_list_import_errors` is now decorated 
`@deprecated_for_airflowctl`
   and the `airflowctl` side would need a new REST endpoint, so that is no 
longer a small
   change.
   
   ### Tests
   
   ```
   uv run --project airflow-core pytest airflow-core/tests/unit/dag_processing/ 
-q
   ```
   
   `test_remove_file_clears_import_error_with_non_zero_refresh_interval` fails 
with the
   `manager.py` change reverted and passes with it.
   `test_clear_import_errors_for_missing_files_keeps_zip_inner_file_errors` 
covers the
   archive case.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [ ] Yes (please specify the tool below)
   


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