Skip to content

Commit 78b8b7e

Browse files
committed
tries cancelling pending task in webserver test
1 parent af00a22 commit 78b8b7e

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

ngwidgets/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.29.2"
1+
__version__ = "0.29.3"

ngwidgets/test_base_webserver.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
@author: wf
66
"""
7-
7+
import asyncio
88
import json
99
import sys
1010
import threading
@@ -77,8 +77,8 @@ def stop(self) -> None:
7777
try:
7878
app.shutdown()
7979
except Exception as e:
80-
if self.debug:
81-
self.warn(f"Expected shutdown exception: {e}")
80+
if self.debug and "CancelledError" not in str(e):
81+
self.warn(f"Shutdown exception: {e}")
8282

8383
# Initialize the timer for timeout
8484
end_time = start_time + self.shutdown_timeout
@@ -102,7 +102,35 @@ def stop(self) -> None:
102102
self.warn(
103103
f"Server shutdown completed in {shutdown_time_taken:.2f} seconds."
104104
)
105+
def cancel_pending_tasks(self):
106+
"""Cancel pending async tasks to prevent loop closed errors - wait for graceful completion first"""
107+
if not self.thread.is_alive():
108+
return
109+
110+
try:
111+
loop = getattr(self.ws, '_loop', None)
112+
if not loop or loop.is_closed():
113+
return
114+
115+
pending = [t for t in asyncio.all_tasks(loop) if not t.done()]
116+
if not pending:
117+
return
118+
119+
# Wait for graceful completion first
120+
grace_period = min(2.0, self.shutdown_timeout * 0.4)
121+
end_time = time.time() + grace_period
122+
123+
while pending and time.time() < end_time:
124+
pending = [t for t in pending if not t.done()]
125+
time.sleep(0.1)
126+
127+
# Cancel remaining tasks
128+
for task in pending:
129+
if not task.done():
130+
task.cancel()
105131

132+
except Exception as ex:
133+
self.warn(f"cancel pending tasks failed: {ex}")
106134

107135
class BaseWebserverTest(Basetest):
108136
"""

ngwidgets/webserver_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def tearDown(self):
7474
"""
7575
super().tearDown()
7676
# Stop the server using the ThreadedServerRunner
77+
self.server_runner.cancel_pending_tasks()
7778
self.server_runner.stop()
7879

7980
def get_response(self, path: str, expected_status_code: int = 200) -> Any:

tests/test_webserver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def testApi(self):
3838
for path in paths:
3939
response = self.get_response(path)
4040
yaml_str = response.text
41-
projects = Projects.from_yaml(yaml_str)
41+
projects = Projects.from_yaml(yaml_str) # @UndefinedVariable
4242
if debug:
4343
for project in projects.projects:
4444
print(project)

0 commit comments

Comments
 (0)