Merge pull request #76 from ecschoye/fix/provider-warmup-cold-start
fix: add provider warmup to prevent cold-start timeout on first channel message
This commit is contained in:
commit
026a917544
4 changed files with 35 additions and 0 deletions
|
|
@ -428,6 +428,13 @@ pub async fn start_channels(config: Config) -> Result<()> {
|
||||||
config.api_key.as_deref(),
|
config.api_key.as_deref(),
|
||||||
&config.reliability,
|
&config.reliability,
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
|
// Warm up the provider connection pool (TLS handshake, DNS, HTTP/2 setup)
|
||||||
|
// so the first real message doesn't hit a cold-start timeout.
|
||||||
|
if let Err(e) = provider.warmup().await {
|
||||||
|
tracing::warn!("Provider warmup failed (non-fatal): {e}");
|
||||||
|
}
|
||||||
|
|
||||||
let model = config
|
let model = config
|
||||||
.default_model
|
.default_model
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,20 @@ impl OpenRouterProvider {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Provider for OpenRouterProvider {
|
impl Provider for OpenRouterProvider {
|
||||||
|
async fn warmup(&self) -> anyhow::Result<()> {
|
||||||
|
// Hit a lightweight endpoint to establish TLS + HTTP/2 connection pool.
|
||||||
|
// This prevents the first real chat request from timing out on cold start.
|
||||||
|
if let Some(api_key) = self.api_key.as_ref() {
|
||||||
|
self.client
|
||||||
|
.get("https://openrouter.ai/api/v1/auth/key")
|
||||||
|
.header("Authorization", format!("Bearer {api_key}"))
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn chat_with_system(
|
async fn chat_with_system(
|
||||||
&self,
|
&self,
|
||||||
system_prompt: Option<&str>,
|
system_prompt: Option<&str>,
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,14 @@ impl ReliableProvider {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Provider for ReliableProvider {
|
impl Provider for ReliableProvider {
|
||||||
|
async fn warmup(&self) -> anyhow::Result<()> {
|
||||||
|
if let Some((name, provider)) = self.providers.first() {
|
||||||
|
tracing::info!(provider = name, "Warming up provider connection pool");
|
||||||
|
provider.warmup().await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn chat_with_system(
|
async fn chat_with_system(
|
||||||
&self,
|
&self,
|
||||||
system_prompt: Option<&str>,
|
system_prompt: Option<&str>,
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,10 @@ pub trait Provider: Send + Sync {
|
||||||
model: &str,
|
model: &str,
|
||||||
temperature: f64,
|
temperature: f64,
|
||||||
) -> anyhow::Result<String>;
|
) -> anyhow::Result<String>;
|
||||||
|
|
||||||
|
/// Warm up the HTTP connection pool (TLS handshake, DNS, HTTP/2 setup).
|
||||||
|
/// Default implementation is a no-op; providers with HTTP clients should override.
|
||||||
|
async fn warmup(&self) -> anyhow::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue