Skip to content

Commit 0d8b3e5

Browse files
committed
Catch Timeout exception when stopping endpoints instead of printing
stack trace [sc-45767]
1 parent 5dad1df commit 0d8b3e5

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Bug Fixes
2+
^^^^^^^^^
3+
4+
- A user-unfriendly Timeout stacktrace Exception may be displayed to the
5+
user when force deleting an endpoint in unusual circumstances. The
6+
stacktrace is now replaced with a suggestion to retry the delete command.

compute_endpoint/globus_compute_endpoint/endpoint/endpoint.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,14 @@ def stop_endpoint(
661661

662662
# Give parent process chance to clean itself up
663663
parent.terminate()
664-
parent.wait(timeout=grace_period_s)
664+
try:
665+
parent.wait(timeout=grace_period_s)
666+
except psutil.TimeoutExpired:
667+
log.warning(
668+
f"Encountered timeout attempting to stop endpoint {ep_name},"
669+
" Please try deleting the endpoint again with the --force flag"
670+
)
671+
sys.exit(-1)
665672

666673
# After grace period, give children 1 second, before pulling the plug
667674
terminated, alive = psutil.wait_procs(processes, timeout=grace_period_s)

compute_endpoint/tests/integration/endpoint/endpoint/test_endpoint.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import shutil
55
from unittest import mock
66

7+
import psutil
78
import pytest
89
import requests
910
import responses
@@ -157,6 +158,33 @@ def test_endpoint_teardown_execution(mocker, tmp_path, randomstring):
157158
assert tmp_file_content in info_txt
158159

159160

161+
def test_endpoint_psutil_timeout(conf_dir, mocker, ep_uuid):
162+
mocker.patch.object(shutil, "rmtree")
163+
164+
endpoint.Endpoint.configure_endpoint(conf_dir, None)
165+
166+
mock_gcc = mocker.Mock()
167+
mocker.patch(f"{_MOCK_BASE}Endpoint.get_funcx_client").return_value = mock_gcc
168+
169+
mock_gcc.get_endpoint_status.return_value = {"status": "online"}
170+
mocker.patch(
171+
f"{_MOCK_BASE}Endpoint.check_pidfile",
172+
return_value={"exists": "True", "active": True},
173+
)
174+
pid_path = endpoint.Endpoint.pid_path(conf_dir)
175+
pid_path.write_text("12345")
176+
177+
mock_psutil = mocker.patch(f"{_MOCK_BASE}psutil.Process")
178+
mock_psutil.return_value.wait.side_effect = psutil.TimeoutExpired(10)
179+
180+
with pytest.raises(SystemExit), mock.patch(f"{_MOCK_BASE}log") as mock_log:
181+
endpoint.Endpoint.delete_endpoint(
182+
conf_dir, ep_config=None, force=True, ep_uuid=ep_uuid
183+
)
184+
a, _k = mock_log.warning.call_args
185+
assert "Please try deleting the endpoint again" in a[0], "expecting rephrasing"
186+
187+
160188
@pytest.mark.parametrize("web_svc_ok", (True, False))
161189
@pytest.mark.parametrize("force", (True, False))
162190
def test_delete_endpoint(conf_dir, mocker, web_svc_ok, force, ep_uuid):

0 commit comments

Comments
 (0)