Skip to content

Commit 38726b6

Browse files
authored
read llm costs from cache, TTL to 24 hours (#981)
* read llm costs from cache, TTL to 7 days * read from DB even if error reading from cache, add error logs * return optional from db on price entry
1 parent 82867c1 commit 38726b6

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

app-server/src/db/prices.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ pub struct DBPriceEntry {
1111
pub additional_prices: Value,
1212
}
1313

14-
pub async fn get_price(pool: &PgPool, provider: &str, model: &str) -> anyhow::Result<DBPriceEntry> {
14+
pub async fn get_price(
15+
pool: &PgPool,
16+
provider: &str,
17+
model: &str,
18+
) -> anyhow::Result<Option<DBPriceEntry>> {
1519
let price = sqlx::query_as::<_, DBPriceEntry>(
1620
"SELECT
1721
provider,
@@ -32,7 +36,7 @@ pub async fn get_price(pool: &PgPool, provider: &str, model: &str) -> anyhow::Re
3236
)
3337
.bind(provider)
3438
.bind(model)
35-
.fetch_one(pool)
39+
.fetch_optional(pool)
3640
.await?;
3741

3842
Ok(price)

app-server/src/language_model/costs/mod.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use utils::calculate_cost;
1313

1414
mod utils;
1515

16+
const LLM_PRICES_CACHE_TTL_SECONDS: u64 = 60 * 60 * 24; // 24 hours
17+
1618
#[derive(Clone, Deserialize, Serialize)]
1719
pub struct LLMPriceEntry {
1820
_provider: String,
@@ -44,15 +46,30 @@ pub async fn estimate_output_cost(
4446
num_tokens: i64,
4547
) -> Option<f64> {
4648
let cache_key = format!("{LLM_PRICES_CACHE_KEY}:{provider}:{model}");
47-
let cache_res = cache.get::<LLMPriceEntry>(&cache_key).await.ok()?;
49+
let cache_res = cache.get::<LLMPriceEntry>(&cache_key).await;
4850

4951
let price_per_million_tokens = match cache_res {
50-
Some(price) => price.output_price_per_million,
51-
None => {
52-
let price = get_price(&db.pool, provider, model).await.ok()?;
52+
Ok(Some(price)) => price.output_price_per_million,
53+
Ok(None) | Err(_) => {
54+
let price = get_price(&db.pool, provider, model)
55+
.await
56+
.map_err(|e| {
57+
log::error!(
58+
"Error getting price from DB for provider: {}, model: {}: {:?}",
59+
provider,
60+
model,
61+
e
62+
);
63+
e
64+
})
65+
.unwrap_or_default()?;
5366
let price = LLMPriceEntry::from(price);
5467
let _ = cache
55-
.insert::<LLMPriceEntry>(&cache_key, price.clone())
68+
.insert_with_ttl::<LLMPriceEntry>(
69+
&cache_key,
70+
price.clone(),
71+
LLM_PRICES_CACHE_TTL_SECONDS,
72+
)
5673
.await;
5774
price.output_price_per_million
5875
}
@@ -68,16 +85,30 @@ pub async fn estimate_input_cost(
6885
input_tokens: InputTokens,
6986
) -> Option<f64> {
7087
let cache_key = format!("{LLM_PRICES_CACHE_KEY}:{provider}:{model}");
71-
// let cache_res = cache.get::<LLMPriceEntry>(&cache_key).await.ok()?;
72-
let cache_res = None;
88+
let cache_res = cache.get::<LLMPriceEntry>(&cache_key).await;
7389

7490
let price = match cache_res {
75-
Some(price) => price,
76-
None => {
77-
let price = get_price(&db.pool, provider, model).await.ok()?;
91+
Ok(Some(price)) => price,
92+
Ok(None) | Err(_) => {
93+
let price = get_price(&db.pool, provider, model)
94+
.await
95+
.map_err(|e| {
96+
log::error!(
97+
"Error getting price from DB for provider: {}, model: {}: {:?}",
98+
provider,
99+
model,
100+
e
101+
);
102+
e
103+
})
104+
.unwrap_or_default()?;
78105
let price = LLMPriceEntry::from(price);
79106
let _ = cache
80-
.insert::<LLMPriceEntry>(&cache_key, price.clone())
107+
.insert_with_ttl::<LLMPriceEntry>(
108+
&cache_key,
109+
price.clone(),
110+
LLM_PRICES_CACHE_TTL_SECONDS,
111+
)
81112
.await;
82113
price
83114
}

0 commit comments

Comments
 (0)