perf: optimize gateway cold start from ~6.9s to ~460ms (#3918)
Channel lazy load: discover_enabled() only imports enabled channel modules instead of all 18 modules with heavy SDKs (telegram, discord, slack, etc). discover_all() now delegates to discover_enabled(). Lazy OpenAI client: defer AsyncOpenAI() + httpx construction to _ensure_client() with asyncio.Lock double-checked locking. openai and httpx imports moved from module-level into _ensure_client(). Minor: lazy Nanobot/RunResult and CronService exports via __getattr__. Benchmark: 6910ms → 460ms (-93.3%)
This commit is contained in:
@@ -180,7 +180,7 @@ async def test_manager_loads_plugin_from_dict_config():
|
||||
)
|
||||
|
||||
with patch(
|
||||
"nanobot.channels.registry.discover_all",
|
||||
"nanobot.channels.registry.discover_enabled",
|
||||
return_value={"fakeplugin": _FakePlugin},
|
||||
):
|
||||
mgr = ChannelManager.__new__(ChannelManager)
|
||||
@@ -210,7 +210,7 @@ async def test_manager_propagates_groq_transcription_api_base_to_channels():
|
||||
)
|
||||
|
||||
with patch(
|
||||
"nanobot.channels.registry.discover_all",
|
||||
"nanobot.channels.registry.discover_enabled",
|
||||
return_value={"fakeplugin": _FakePlugin},
|
||||
):
|
||||
mgr = ChannelManager.__new__(ChannelManager)
|
||||
@@ -246,7 +246,7 @@ async def test_manager_propagates_openai_transcription_api_base_to_channels():
|
||||
)
|
||||
|
||||
with patch(
|
||||
"nanobot.channels.registry.discover_all",
|
||||
"nanobot.channels.registry.discover_enabled",
|
||||
return_value={"fakeplugin": _FakePlugin},
|
||||
):
|
||||
mgr = ChannelManager.__new__(ChannelManager)
|
||||
@@ -498,10 +498,8 @@ async def test_manager_skips_disabled_plugin():
|
||||
providers=SimpleNamespace(groq=SimpleNamespace(api_key="")),
|
||||
)
|
||||
|
||||
with patch(
|
||||
"nanobot.channels.registry.discover_all",
|
||||
return_value={"fakeplugin": _FakePlugin},
|
||||
):
|
||||
ep = _make_entry_point("fakeplugin", _FakePlugin)
|
||||
with patch(_EP_TARGET, return_value=[ep]):
|
||||
mgr = ChannelManager.__new__(ChannelManager)
|
||||
mgr.config = fake_config
|
||||
mgr.bus = MessageBus()
|
||||
|
||||
@@ -85,17 +85,18 @@ class TestIsLocalEndpoint:
|
||||
class TestLocalKeepaliveConfig:
|
||||
"""Verify that local endpoints get keepalive_expiry=0."""
|
||||
|
||||
def test_local_spec_disables_keepalive(self):
|
||||
async def test_local_spec_disables_keepalive(self):
|
||||
spec = _make_spec(is_local=True)
|
||||
spec.env_key = ""
|
||||
spec.default_api_base = "http://localhost:11434/v1"
|
||||
provider = OpenAICompatProvider(
|
||||
api_key="test", api_base="http://localhost:11434/v1", spec=spec,
|
||||
)
|
||||
await provider._ensure_client()
|
||||
pool = provider._client._client._transport._pool
|
||||
assert pool._keepalive_expiry == 0
|
||||
|
||||
def test_lan_ip_disables_keepalive(self):
|
||||
async def test_lan_ip_disables_keepalive(self):
|
||||
"""A generic 'openai' spec with a LAN IP should still disable keepalive."""
|
||||
spec = _make_spec(is_local=False)
|
||||
spec.env_key = ""
|
||||
@@ -103,16 +104,18 @@ class TestLocalKeepaliveConfig:
|
||||
provider = OpenAICompatProvider(
|
||||
api_key="test", api_base="http://192.168.8.188:1234/v1", spec=spec,
|
||||
)
|
||||
await provider._ensure_client()
|
||||
pool = provider._client._client._transport._pool
|
||||
assert pool._keepalive_expiry == 0
|
||||
|
||||
def test_cloud_keeps_default_keepalive(self):
|
||||
async def test_cloud_keeps_default_keepalive(self):
|
||||
spec = _make_spec(is_local=False)
|
||||
spec.env_key = ""
|
||||
spec.default_api_base = "https://api.openai.com/v1"
|
||||
provider = OpenAICompatProvider(
|
||||
api_key="test", api_base=None, spec=spec,
|
||||
)
|
||||
await provider._ensure_client()
|
||||
pool = provider._client._client._transport._pool
|
||||
# Default httpx keepalive is 5.0s
|
||||
assert pool._keepalive_expiry == 5.0
|
||||
|
||||
@@ -29,7 +29,7 @@ def test_openai_compat_provider_sets_timeout_on_local_http_client() -> None:
|
||||
with (
|
||||
patch("nanobot.providers.openai_compat_provider.AsyncOpenAI") as mock_async_openai,
|
||||
patch(
|
||||
"nanobot.providers.openai_compat_provider.httpx.AsyncClient",
|
||||
"httpx.AsyncClient",
|
||||
return_value=sentinel.http_client,
|
||||
) as mock_http_client,
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user