10000 run server in separate process · Guro/python-sdk@7b35ab8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7b35ab8

Browse files
committed
run server in separate process
1 parent 8d90a3a commit 7b35ab8

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

tests/shared/test_sse.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ async def handle_call_tool(name: str, args: dict):
6464

6565

6666
# Test fixtures
67-
@pytest.fixture
68-
async def server_app()-> Starlette:
67+
def make_server_app()-> Starlette:
6968
"""Create test Starlette app with SSE transport"""
7069
sse = SseServerTransport("/messages/")
7170
server = TestServer()
@@ -93,43 +92,46 @@ def space_around_test():
9392
yield
9493
time.sleep(0.1)
9594

96-
@pytest.fixture()
97-
def server(server_app: Starlette, server_port: int):
98-
proc = multiprocessing.Process(target=uvicorn.run, daemon=True, kwargs={
99-
"app": server_app,
100-
"host": "127.0.0.1",
101-
"port": server_port,
102-
"log_level": "error"
103-
})
95+
def run_server(server_port: int):
96+
app = make_server_app()
97+
server = uvicorn.Server(config=uvicorn.Config(app=app, host="127.0.0.1", port=server_port, log_level="error"))
10498
print(f'starting server on {server_port}')
105-
proc.start()
99+
server.run()
106100

107101
# Give server time to start
108102
while not server.started:
109103
print('waiting for server to start')
110104
time.sleep(0.5)
111105

112-
try:
113-
yield
114-
finally:
115-
print('killing server')
116-
# Signal the server to stop
117-
server.should_exit = True
118-
119-
# Force close the server's main socket
120-
if hasattr(server.servers, "servers"):
121-
for s in server.servers:
122-
print(f'closing {s}')
123-
s.close()
124-
125-
# Wait for thread to finish
126-
proc.terminate()
127-
proc.join(timeout=2)
128-
if proc.is_alive():
129-
print("Warning: Server thread did not exit cleanly")
130-
# Optionally, you could add more aggressive cleanup here
131-
import _thread
132-
_thread.interrupt_main()
106+
@pytest.fixture()
107+
def server(server_port: int):
108+
proc = multiprocessing.Process(target=run_server, kwargs={"server_port": server_port}, daemon=True)
109+
print('starting process')
110+
proc.start()
111+
112+
# Wait for server to be running
113+
max_attempts = 20
114+
attempt = 0
115+
print('waiting for server to start')
116+
while attempt < max_attempts:
117+
try:
118+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
119+
s.connect(('127.0.0.1', server_port))
120+
break
121+
except ConnectionRefusedError:
122+
time.sleep(0.1)
123+
attempt += 1
124+
else:
125+
raise RuntimeError("Server failed to start after {} attempts".format(max_attempts))
126+
127+
yield
128+
129+
print('killing server')
130+
# Signal the server to stop
131+
proc.kill()
132+
proc.join(timeout=2)
133+
if proc.is_alive():
134+
print("server process failed to terminate")
133135

134136
@pytest.fixture()
135137
async def http_client(server, server_url) -> AsyncGenerator[httpx.AsyncClient, None]:

0 commit comments

Comments
 (0)
0