shahar1 opened a new pull request, #75596:
URL: https://github.com/apache/airflow/pull/75596

   `CloudLoggingTaskHandler.close()` flushed `self.io.transport`. That property 
is a lazy `cached_property`, so closing a handler that never emitted a record 
built a new `BackgroundThreadTransport` just to flush it. That starts a worker 
thread from inside `logging.shutdown()`, which runs while 
`logging.config.dictConfig()` holds the logging lock.
   
   This made `test_should_use_configured_log_name` flaky in the Airflow 2.11.1 
compat job ([failed 
run](https://github.com/apache/airflow/actions/runs/40065910461/job/121076899873)).
 The test's `finally:` block calls `settings.configure_logging()`, which closes 
the handler created by the test, and `Thread.start()` blocked in 
`_started.wait()` until pytest-timeout fired after 60s. Outside tests, every 
logging reconfiguration leaked one worker thread per unused handler.
   
   `close()` now reads the attrs slot directly and only flushes a transport 
that was actually built. A handler that sent records still has its transport in 
the slot and is still flushed.
   
   **Testing**
   - New regression test `test_close_does_not_build_unused_transport`: it fails 
without the production change and passes with it.
   - `providers/google/tests/unit/google/cloud/log/` on Airflow main: 118 
passed.
   - Airflow 2.11.1 on Python 3.11, with the provider installed from this 
branch:
     - The handler test module passes: 42 passed, 8 skipped, 10 DB tests 
deselected.
     - `test_should_use_configured_log_name` now starts 0 
`google.cloud.logging.Worker` threads, down from 1 per run.
     - A stress loop of handler creation plus `dictConfig` leaks 0 threads 
(before the change: 1000 threads over 1000 iterations).
   - I could not reproduce the 60s hang itself locally. A full Google provider 
unit run on 2.11.1 had no timeouts, so the fix removes the code path that 
blocked rather than the unidentified cause of the block.
   
   The slot read needs attrs >= 23.2. With older attrs, `close()` falls back to 
building the transport, which is the previous behaviour.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes — Claude Code (Opus 5.5, Sonnet 5.5 subagents)
   
   Generated-by: Claude Code (Opus 5.5, Sonnet 5.5 subagents) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   
   https://claude.ai/code/session_01RXok8FK5hAFPosJuVqdXaE


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