This is an automated email from the ASF dual-hosted git repository.

tvalentyn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new dd463fa934d Fix flaky AsyncWrapper reset_state test on Python 3.14 
(#39521)
dd463fa934d is described below

commit dd463fa934d1d8f3d3b459476d90ca55853e10e2
Author: Bruno Volpato <[email protected]>
AuthorDate: Tue Jul 28 06:58:28 2026 -0400

    Fix flaky AsyncWrapper reset_state test on Python 3.14 (#39521)
---
 sdks/python/apache_beam/transforms/async_dofn_test.py | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/sdks/python/apache_beam/transforms/async_dofn_test.py 
b/sdks/python/apache_beam/transforms/async_dofn_test.py
index f9e07d57be9..de5298f0a2c 100644
--- a/sdks/python/apache_beam/transforms/async_dofn_test.py
+++ b/sdks/python/apache_beam/transforms/async_dofn_test.py
@@ -489,7 +489,7 @@ class AsyncTest(unittest.TestCase):
       self.assertEqual(bag_states['key' + str(i)].items, [])
 
   @staticmethod
-  def _run_reset_state_concurrent_teardown(use_asyncio):
+  def _run_reset_state_concurrent_teardown(use_asyncio, reset_started):
     dofn = BasicDofn(sleep_time=0.5)
     async_dofn = async_lib.AsyncWrapper(dofn, use_asyncio=use_asyncio)
     async_dofn.setup()
@@ -502,15 +502,26 @@ class AsyncTest(unittest.TestCase):
 
     # Verify that calling reset_state() while background tasks are actively 
running
     # completes cleanly without causing lock-ordering deadlocks.
+    reset_started.set()
     async_lib.AsyncWrapper.reset_state()
 
   def test_reset_state_concurrent_teardown(self):
     # Verify concurrent teardown safety in a separate process to prevent any 
potential
     # regressions from freezing the main pytest process at exit.
+    reset_started = multiprocessing.Event()
     p = multiprocessing.Process(
         target=AsyncTest._run_reset_state_concurrent_teardown,
-        args=(self.use_asyncio, ))
+        args=(self.use_asyncio, reset_started))
     p.start()
+
+    # Python 3.14 uses forkserver by default on POSIX. Wait for child startup
+    # before measuring reset_state() so import and process startup time cannot
+    # be mistaken for a teardown deadlock.
+    if not reset_started.wait(timeout=30.0):
+      p.terminate()
+      p.join()
+      self.fail("child process did not reach reset_state() before timeout")
+
     p.join(timeout=10.0)
 
     if p.is_alive():

Reply via email to