|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
import json
|
|
import json
|
|
|
import os
|
|
import os
|
|
|
import threading
|
|
import threading
|
|
|
|
|
+from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeoutError
|
|
|
from typing import Any
|
|
from typing import Any
|
|
|
|
|
|
|
|
from mcp import ClientSession
|
|
from mcp import ClientSession
|
|
@@ -11,6 +12,7 @@ from mcp.client.sse import sse_client
|
|
|
|
|
|
|
|
|
|
|
|
|
CRYPTO_MCP_SSE_URL = os.getenv("CRYPTO_MCP_SSE_URL", "http://localhost:8505/mcp/sse")
|
|
CRYPTO_MCP_SSE_URL = os.getenv("CRYPTO_MCP_SSE_URL", "http://localhost:8505/mcp/sse")
|
|
|
|
|
+CRYPTO_MCP_CALL_TIMEOUT_SECONDS = float(os.getenv("CRYPTO_MCP_CALL_TIMEOUT_SECONDS", "5"))
|
|
|
|
|
|
|
|
|
|
|
|
|
async def get_price(symbol: str, base_url: str | None = None) -> dict[str, Any]:
|
|
async def get_price(symbol: str, base_url: str | None = None) -> dict[str, Any]:
|
|
@@ -38,7 +40,14 @@ def get_price_sync(symbol: str, base_url: str | None = None) -> dict[str, Any]:
|
|
|
try:
|
|
try:
|
|
|
asyncio.get_running_loop()
|
|
asyncio.get_running_loop()
|
|
|
except RuntimeError:
|
|
except RuntimeError:
|
|
|
- return asyncio.run(get_price(symbol, base_url=base_url))
|
|
|
|
|
|
|
+ try:
|
|
|
|
|
+ with ThreadPoolExecutor(max_workers=1) as pool:
|
|
|
|
|
+ future = pool.submit(asyncio.run, get_price(symbol, base_url=base_url))
|
|
|
|
|
+ return future.result(timeout=CRYPTO_MCP_CALL_TIMEOUT_SECONDS)
|
|
|
|
|
+ except FuturesTimeoutError:
|
|
|
|
|
+ return {"error": "TIMEOUT", "symbol": symbol}
|
|
|
|
|
+ except Exception as exc:
|
|
|
|
|
+ return {"error": str(exc), "symbol": symbol}
|
|
|
|
|
|
|
|
result: dict[str, Any] = {}
|
|
result: dict[str, Any] = {}
|
|
|
error: list[BaseException] = []
|
|
error: list[BaseException] = []
|
|
@@ -51,7 +60,9 @@ def get_price_sync(symbol: str, base_url: str | None = None) -> dict[str, Any]:
|
|
|
|
|
|
|
|
thread = threading.Thread(target=_runner, daemon=True)
|
|
thread = threading.Thread(target=_runner, daemon=True)
|
|
|
thread.start()
|
|
thread.start()
|
|
|
- thread.join()
|
|
|
|
|
|
|
+ thread.join(CRYPTO_MCP_CALL_TIMEOUT_SECONDS)
|
|
|
|
|
+ if thread.is_alive():
|
|
|
|
|
+ return {"error": "TIMEOUT", "symbol": symbol}
|
|
|
if error:
|
|
if error:
|
|
|
- raise error[0]
|
|
|
|
|
|
|
+ return {"error": str(error[0]), "symbol": symbol}
|
|
|
return result
|
|
return result
|