Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion routstr/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def parse_env_var(cls, field_name: str, raw_value: str) -> Any: # type: ignore[
cors_origins: list[str] = Field(default_factory=lambda: ["*"], env="CORS_ORIGINS")
tor_proxy_url: str = Field(default="socks5://127.0.0.1:9050", env="TOR_PROXY_URL")
providers_refresh_interval_seconds: int = Field(
default=300, env="PROVIDERS_REFRESH_INTERVAL_SECONDS"
default=0, env="PROVIDERS_REFRESH_INTERVAL_SECONDS"
)
pricing_refresh_interval_seconds: int = Field(
default=120, env="PRICING_REFRESH_INTERVAL_SECONDS"
Expand Down
5 changes: 4 additions & 1 deletion routstr/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import httpx
import websockets
from fastapi import APIRouter
from fastapi import APIRouter, HTTPException

from .core.logging import get_logger
from .core.settings import settings
Expand Down Expand Up @@ -389,6 +389,9 @@ async def get_providers(
Return cached providers. If include_json, return provider+health; otherwise provider only.
Optional filter by pubkey.
"""
if settings.providers_refresh_interval_seconds == 0:
raise HTTPException(status_code=404, detail="Provider discovery is disabled")

cache = await get_cache()
if not cache:
await refresh_providers_cache(pubkey=pubkey)
Expand Down
61 changes: 33 additions & 28 deletions tests/integration/test_performance_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import statistics
import time
from typing import Any, Dict, List
from unittest.mock import patch

import psutil
import pytest
Expand Down Expand Up @@ -105,42 +106,46 @@ async def test_endpoint_response_times(
("GET", "/v1/wallet/info", authenticated_client, None),
]

# Warm up
for _ in range(10):
await integration_client.get("/")
# Enable provider discovery for this test
with patch(
"routstr.core.settings.settings.providers_refresh_interval_seconds", 300
):
# Warm up
for _ in range(10):
await integration_client.get("/")

# Test each endpoint
for method, path, client, data in endpoints:
response_times = []
# Test each endpoint
for method, path, client, data in endpoints:
response_times = []

for i in range(100):
start = time.time()
for i in range(100):
start = time.time()

if method == "GET":
response = await client.get(path)
else:
response = await client.post(path, json=data)
if method == "GET":
response = await client.get(path)
else:
response = await client.post(path, json=data)

duration = time.time() - start
response_times.append(duration * 1000) # Convert to ms
duration = time.time() - start
response_times.append(duration * 1000) # Convert to ms

assert response.status_code in [200, 201]
assert response.status_code in [200, 201]

if i % 10 == 0:
metrics.record_system_metrics()
if i % 10 == 0:
metrics.record_system_metrics()

# Verify 95th percentile < 500ms
p95 = sorted(response_times)[int(len(response_times) * 0.95)]
assert p95 < 500, (
f"{method} {path} p95 response time {p95}ms exceeds 500ms limit"
)
# Verify 95th percentile < 500ms
p95 = sorted(response_times)[int(len(response_times) * 0.95)]
assert p95 < 500, (
f"{method} {path} p95 response time {p95}ms exceeds 500ms limit"
)

print(f"\n{method} {path}:")
print(f" Mean: {statistics.mean(response_times):.2f}ms")
print(f" P95: {p95:.2f}ms")
print(
f" P99: {sorted(response_times)[int(len(response_times) * 0.99)]:.2f}ms"
)
print(f"\n{method} {path}:")
print(f" Mean: {statistics.mean(response_times):.2f}ms")
print(f" P95: {p95:.2f}ms")
print(
f" P99: {sorted(response_times)[int(len(response_times) * 0.99)]:.2f}ms"
)


@pytest.mark.integration
Expand Down
11 changes: 10 additions & 1 deletion tests/integration/test_provider_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Tests GET /v1/providers/ endpoint for listing and managing providers.
"""

from typing import Any
from typing import Any, Generator
from unittest.mock import patch

import pytest
Expand All @@ -19,6 +19,15 @@ def _clear_providers_cache() -> None:
_PROVIDERS_CACHE.clear()


@pytest.fixture(autouse=True)
def _enable_provider_discovery() -> Generator[None, Any, Any]:
"""Enable provider discovery for all tests in this module"""
with patch(
"routstr.core.settings.settings.providers_refresh_interval_seconds", 300
):
yield


@pytest.mark.integration
@pytest.mark.asyncio
async def test_providers_endpoint_default_response(
Expand Down
Loading