diff --git a/python/restate/server.py b/python/restate/server.py index 70e3aba..195ea5f 100644 --- a/python/restate/server.py +++ b/python/restate/server.py @@ -228,7 +228,7 @@ async def app(scope: Scope, receive: Receive, send: Send): loop = asyncio.get_running_loop() try: loop.add_signal_handler(signal.SIGTERM, _on_sigterm) - except (NotImplementedError, RuntimeError): + except (NotImplementedError, RuntimeError, ValueError): pass # Windows or non-main thread sigterm_installed = True try: diff --git a/tests/server.py b/tests/server.py new file mode 100644 index 0000000..83bd314 --- /dev/null +++ b/tests/server.py @@ -0,0 +1,63 @@ +# +# Copyright (c) 2023-2025 - Restate Software, Inc., Restate GmbH +# +# This file is part of the Restate SDK for Python, +# which is released under the MIT license. +# +# You can find a copy of the license in file LICENSE in the root +# directory of this repository or package, or at +# https://github.com/restatedev/sdk-typescript/blob/main/LICENSE +# +import asyncio +from unittest.mock import Mock + +import pytest + +from restate.endpoint import Endpoint + + +@pytest.fixture(scope="session") +def anyio_backend(): + return "asyncio" + + +pytestmark = [pytest.mark.anyio] + + +async def test_signal_handler_rejection_does_not_fail_request(monkeypatch: pytest.MonkeyPatch): + loop = asyncio.get_running_loop() + monkeypatch.setattr( + loop, + "add_signal_handler", + Mock(side_effect=ValueError("add_signal_handler() can only be called from the main thread")), + ) + + app = Endpoint().app() + sent = [] + + async def receive(): + return {"type": "http.request", "body": b"", "more_body": False} + + async def send(message): + sent.append(message) + + await app( + { + "type": "http", + "asgi": {"version": "3.0"}, + "http_version": "1.1", + "method": "GET", + "scheme": "http", + "path": "/restate/health", + "raw_path": b"/restate/health", + "query_string": b"", + "headers": [], + "client": ("127.0.0.1", 1234), + "server": ("127.0.0.1", 9080), + }, + receive, + send, + ) + + response_starts = [message for message in sent if message["type"] == "http.response.start"] + assert [message["status"] for message in response_starts] == [200]