Skip to content
This repository has been archived by the owner on Nov 28, 2024. It is now read-only.

Commit

Permalink
fix: cache control headers (tailcallhq#465)
Browse files Browse the repository at this point in the history
  • Loading branch information
amitksingh1490 authored Oct 11, 2023
1 parent 61f80ad commit 1774b06
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 5 deletions.
2 changes: 1 addition & 1 deletion benches/impl_path_string_for_evaluation_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ fn assert_test(eval_ctx: &EvaluationContext<'_, MockGraphqlContext>) {
}

fn bench_main(c: &mut Criterion) {
let mut req_ctx = RequestContext { req_headers: TEST_HEADERS.clone(), ..Default::default() };
let mut req_ctx = RequestContext::default().req_headers(TEST_HEADERS.clone());

req_ctx.server.vars = TEST_VARS.clone();

Expand Down
53 changes: 52 additions & 1 deletion src/http/request_context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::{Arc, Mutex};

use derive_setters::Setters;
use hyper::HeaderMap;

Expand All @@ -9,6 +11,7 @@ pub struct RequestContext {
pub http_client: DefaultHttpClient,
pub server: Server,
pub req_headers: HeaderMap,
min_max_age: Arc<Mutex<Option<u64>>>,
}

impl Default for RequestContext {
Expand All @@ -19,12 +22,31 @@ impl Default for RequestContext {

impl RequestContext {
pub fn new(http_client: DefaultHttpClient, server: Server) -> Self {
Self { req_headers: HeaderMap::new(), http_client, server }
Self { req_headers: HeaderMap::new(), http_client, server, min_max_age: Arc::new(Mutex::new(None)) }
}

pub async fn execute(&self, req: reqwest::Request) -> anyhow::Result<Response> {
Ok(self.http_client.execute(req).await?)
}
fn set_min_max_age_conc(&self, min_max_age: u64) {
*self.min_max_age.lock().unwrap() = Some(min_max_age);
}
pub fn get_min_max_age(&self) -> Option<u64> {
*self.min_max_age.lock().unwrap()
}

pub fn set_min_max_age(&self, max_age: u64) {
let min_max_age_lock = self.get_min_max_age();
match min_max_age_lock {
Some(min_max_age) if max_age < min_max_age => {
self.set_min_max_age_conc(max_age);
}
None => {
self.set_min_max_age_conc(max_age);
}
_ => {}
}
}
}

impl From<&ServerContext> for RequestContext {
Expand All @@ -33,3 +55,32 @@ impl From<&ServerContext> for RequestContext {
Self::new(http_client, server_ctx.server.clone())
}
}

#[cfg(test)]
mod test {

use crate::http::RequestContext;

#[test]
fn test_update_max_age_less_than_existing() {
let req_ctx = RequestContext::default();
req_ctx.set_min_max_age(120);
req_ctx.set_min_max_age(60);
assert_eq!(req_ctx.get_min_max_age(), Some(60));
}

#[test]
fn test_update_max_age_greater_than_existing() {
let req_ctx = RequestContext::default();
req_ctx.set_min_max_age(60);
req_ctx.set_min_max_age(120);
assert_eq!(req_ctx.get_min_max_age(), Some(60));
}

#[test]
fn test_update_max_age_no_existing_value() {
let req_ctx = RequestContext::default();
req_ctx.set_min_max_age(120);
assert_eq!(req_ctx.get_min_max_age(), Some(120));
}
}
10 changes: 8 additions & 2 deletions src/http/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ async fn graphql_request(req: Request<Body>, server_ctx: &ServerContext) -> Resu
let bytes = hyper::body::to_bytes(req.into_body()).await?;
let request: async_graphql_hyper::GraphQLRequest = serde_json::from_slice(&bytes)?;
let req_ctx = Arc::new(RequestContext::from(server_ctx).req_headers(headers));
let response = request.data(req_ctx.clone()).execute(&server_ctx.schema).await;
// Todo: Handle Cache-Control headers
let mut response = request.data(req_ctx.clone()).execute(&server_ctx.schema).await;

if server_ctx.server.enable_cache_control() {
if let Some(ttl) = req_ctx.get_min_max_age() {
response = response.set_cache_control(ttl as i32);
}
}

response.to_response()
}
fn not_found() -> Result<Response<Body>> {
Expand Down
12 changes: 11 additions & 1 deletion src/lambda/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use thiserror::Error;

use super::ResolverContextLike;
use crate::config::group_by::GroupBy;
use crate::http::{DefaultHttpClient, HttpDataLoader};
use crate::http::{max_age, DefaultHttpClient, HttpDataLoader};
#[cfg(feature = "unsafe-js")]
use crate::javascript;
use crate::json::JsonLike;
Expand Down Expand Up @@ -114,6 +114,11 @@ impl Expression {
.await
.map_err(|e| EvaluationError::IOException(e.to_string()))?
.unwrap_or_default();
if ctx.req_ctx.server.enable_cache_control() && resp.status.is_success() {
if let Some(max_age) = max_age(&resp) {
ctx.req_ctx.set_min_max_age(max_age.as_secs());
}
}
return Ok(resp.body);
}

Expand All @@ -130,6 +135,11 @@ impl Expression {
.validate(&res.body)
.map_err(EvaluationError::from)?;
}
if ctx.req_ctx.server.enable_cache_control() && res.status.is_success() {
if let Some(max_age) = max_age(&res) {
ctx.req_ctx.set_min_max_age(max_age.as_secs());
}
}
Ok(res.body)
}
Operation::JS(input, script) => {
Expand Down

0 comments on commit 1774b06

Please sign in to comment.