Skip to content

Commit

Permalink
feat: cache charts for 24 hours
Browse files Browse the repository at this point in the history
  • Loading branch information
d-loose committed Dec 10, 2024
1 parent 13a7908 commit 5e1f85a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/db/categories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use sqlx::{PgConnection, Postgres, QueryBuilder};
Copy,
PartialEq,
Eq,
Hash,
sqlx::Type,
strum::EnumString,
strum::Display,
Expand Down
2 changes: 1 addition & 1 deletion src/db/vote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl Vote {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::FromRepr)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::FromRepr)]
#[repr(i32)]
pub enum Timeframe {
Unspecified,
Expand Down
37 changes: 30 additions & 7 deletions src/grpc/charts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use crate::{
},
ratings::{Chart, ChartData, Rating, RatingsBand},
};
use cached::{proc_macro::cached, Return};
use tonic::{Request, Response, Status};
use tracing::error;
use tracing::{error, info};

#[derive(Copy, Clone, Debug)]
pub struct ChartService;
Expand Down Expand Up @@ -41,16 +42,23 @@ impl chart_server::Chart for ChartService {
};

let timeframe = Timeframe::from_repr(timeframe).unwrap_or(Timeframe::Unspecified);
let result = VoteSummary::get_for_timeframe(timeframe, category, conn!()).await;

match result {
Ok(summaries) if summaries.is_empty() => {
let chart = get_chart_cached(category, timeframe).await;

match chart {
Ok(chart) if chart.data.is_empty() => {
Err(Status::not_found("Cannot find data for given timeframe."))
}

Ok(summaries) => {
let chart = Chart::new(timeframe, summaries);
let ordered_chart_data = chart.data.into_iter().map(|cd| cd.into()).collect();
Ok(chart) => {
if chart.was_cached {
info!(
"Using cached chart data for category '{:?}' in timeframe '{:?}'",
category, timeframe
);
}

let ordered_chart_data = chart.value.data.into_iter().map(|cd| cd.into()).collect();

let payload = GetChartResponse {
timeframe: timeframe as i32,
Expand All @@ -69,6 +77,21 @@ impl chart_server::Chart for ChartService {
}
}

#[cached(
time = 86400, // 24 hours
sync_writes = true,
result = true,
with_cached_flag = true
)]
async fn get_chart_cached(
category: Option<Category>,
timeframe: Timeframe,
) -> Result<Return<Chart>, Box<dyn std::error::Error>> {
let summaries = VoteSummary::get_for_timeframe(timeframe, category, conn!()).await?;

Ok(Return::new(Chart::new(timeframe, summaries)))
}

impl From<ChartData> for PbChartData {
fn from(value: ChartData) -> Self {
Self {
Expand Down
1 change: 1 addition & 0 deletions src/ratings/charts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
};
use std::cmp::Ordering;

#[derive(Debug, Clone)]
pub struct Chart {
pub timeframe: Timeframe,
pub data: Vec<ChartData>,
Expand Down

0 comments on commit 5e1f85a

Please sign in to comment.