Commit
·
082b2ad
1
Parent(s):
4d76348
fixed the timeout
Browse files
proxy.py
CHANGED
|
@@ -78,7 +78,15 @@ async def proxy_handler(request):
|
|
| 78 |
target_url += f"?{query_string}"
|
| 79 |
|
| 80 |
# Forward request to FastMCP
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
try:
|
| 83 |
# Copy headers
|
| 84 |
headers = dict(request.headers)
|
|
@@ -98,11 +106,31 @@ async def proxy_handler(request):
|
|
| 98 |
)
|
| 99 |
await response.prepare(request)
|
| 100 |
|
| 101 |
-
#
|
| 102 |
-
async
|
| 103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
-
await response.write_eof()
|
| 106 |
return response
|
| 107 |
else:
|
| 108 |
# For regular responses, read entire body
|
|
|
|
| 78 |
target_url += f"?{query_string}"
|
| 79 |
|
| 80 |
# Forward request to FastMCP
|
| 81 |
+
# For SSE connections: total=None disables overall timeout (keeps connection alive)
|
| 82 |
+
# Still use socket timeouts for safety (sock_connect, sock_read)
|
| 83 |
+
async with ClientSession(
|
| 84 |
+
timeout=ClientTimeout(
|
| 85 |
+
total=None, # No total timeout for long-lived SSE connections
|
| 86 |
+
sock_connect=30, # 30 seconds for initial connection
|
| 87 |
+
sock_read=300 # 5 minutes for individual socket reads
|
| 88 |
+
)
|
| 89 |
+
) as session:
|
| 90 |
try:
|
| 91 |
# Copy headers
|
| 92 |
headers = dict(request.headers)
|
|
|
|
| 106 |
)
|
| 107 |
await response.prepare(request)
|
| 108 |
|
| 109 |
+
# Background task to send keep-alive pings (prevents timeout)
|
| 110 |
+
async def send_keepalive():
|
| 111 |
+
try:
|
| 112 |
+
while True:
|
| 113 |
+
await asyncio.sleep(30) # Send ping every 30 seconds
|
| 114 |
+
await response.write(b":\n\n") # SSE comment (ignored by client)
|
| 115 |
+
except asyncio.CancelledError:
|
| 116 |
+
pass
|
| 117 |
+
|
| 118 |
+
keepalive_task = asyncio.create_task(send_keepalive())
|
| 119 |
+
|
| 120 |
+
try:
|
| 121 |
+
# Stream chunks from FastMCP to client
|
| 122 |
+
async for chunk in resp.content.iter_any():
|
| 123 |
+
await response.write(chunk)
|
| 124 |
+
|
| 125 |
+
await response.write_eof()
|
| 126 |
+
finally:
|
| 127 |
+
# Cancel keep-alive task when streaming completes
|
| 128 |
+
keepalive_task.cancel()
|
| 129 |
+
try:
|
| 130 |
+
await keepalive_task
|
| 131 |
+
except asyncio.CancelledError:
|
| 132 |
+
pass
|
| 133 |
|
|
|
|
| 134 |
return response
|
| 135 |
else:
|
| 136 |
# For regular responses, read entire body
|
server.py
CHANGED
|
@@ -113,6 +113,8 @@ def extract_api_key_from_request():
|
|
| 113 |
mcp = FastMCP(
|
| 114 |
name="FleetMind Dispatch Coordinator",
|
| 115 |
version="1.0.0"
|
|
|
|
|
|
|
| 116 |
)
|
| 117 |
|
| 118 |
# ============================================================================
|
|
|
|
| 113 |
mcp = FastMCP(
|
| 114 |
name="FleetMind Dispatch Coordinator",
|
| 115 |
version="1.0.0"
|
| 116 |
+
# Note: request_timeout not supported in FastMCP 2.13.1
|
| 117 |
+
# Timeout handling is done in proxy.py instead
|
| 118 |
)
|
| 119 |
|
| 120 |
# ============================================================================
|