From 81aab319f9ee83c60f7aa8ecaf68ce51ca00598b Mon Sep 17 00:00:00 2001 From: Andrey Ermilov Date: Thu, 16 Sep 2021 11:16:29 +0300 Subject: [PATCH] issue-25: Add Cacheable --- examples/examples/axum.rs | 2 +- hitbox-axum/Cargo.toml | 2 ++ hitbox-axum/src/cacheable.rs | 51 ++++++++++++++++++++++++++++++ hitbox-axum/src/layer.rs | 61 ++---------------------------------- hitbox-axum/src/lib.rs | 5 ++- hitbox-axum/src/service.rs | 38 ++++++++++++++++++++++ 6 files changed, 98 insertions(+), 61 deletions(-) create mode 100644 hitbox-axum/src/cacheable.rs create mode 100644 hitbox-axum/src/service.rs diff --git a/examples/examples/axum.rs b/examples/examples/axum.rs index 569ceb4..ca49d07 100644 --- a/examples/examples/axum.rs +++ b/examples/examples/axum.rs @@ -11,7 +11,7 @@ use axum::response::Html; async fn main() { let app = Router::new() .route( - "/", + "/:user_id/index.html", get(handler.layer(CacheLayer::new())), ); diff --git a/hitbox-axum/Cargo.toml b/hitbox-axum/Cargo.toml index cca80e9..8b4de0d 100644 --- a/hitbox-axum/Cargo.toml +++ b/hitbox-axum/Cargo.toml @@ -18,3 +18,5 @@ tower-layer = "0.3.1" tower-service = "0.3.1" serde = "1" serde_json = "1" +axum = "0.2" +sha2 = "0.9" diff --git a/hitbox-axum/src/cacheable.rs b/hitbox-axum/src/cacheable.rs new file mode 100644 index 0000000..f973a65 --- /dev/null +++ b/hitbox-axum/src/cacheable.rs @@ -0,0 +1,51 @@ +use axum::http::Request; +use hitbox::cache::Cacheable; +use hitbox::CacheError; + +pub struct Wrapper { + pub request: Request, +} + +impl Wrapper { + pub fn into_inner(self) -> Request { + self.request + } +} + +impl Cacheable for Wrapper { + fn cache_key(&self) -> Result { + let path = self.request.uri().path(); + let method = self.request.method(); + let query = self.request.uri().query().unwrap_or_default(); + Ok(format!("{}:{}:{}", path, method, query)) + } + + fn cache_key_prefix(&self) -> String { + todo!() + } + + fn cache_ttl(&self) -> u32 { + todo!() + } + + fn cache_stale_ttl(&self) -> u32 { + todo!() + } + + fn cache_version(&self) -> u32 { + todo!() + } +} + +mod tests { + use axum::http::Request; + use crate::Wrapper; + use hitbox::cache::Cacheable; + + #[test] + fn test_cache_key() { + let request = Request::new(String::from("Hello world")); + let wrapper = Wrapper { request }; + assert_eq!(wrapper.cache_key().unwrap(), String::from("/:GET:")) + } +} diff --git a/hitbox-axum/src/layer.rs b/hitbox-axum/src/layer.rs index 8a8ef04..93b8bde 100644 --- a/hitbox-axum/src/layer.rs +++ b/hitbox-axum/src/layer.rs @@ -1,9 +1,5 @@ -use tower_service::Service; -use std::task::{Poll, Context}; use tower_layer::Layer; -use std::fmt; -use hitbox::{Cacheable, CacheError}; -use serde::Serialize; +use crate::service::CacheService; #[derive(Debug, Clone)] pub struct CacheLayer {} @@ -18,59 +14,6 @@ impl Layer for CacheLayer { type Service = CacheService; fn layer(&self, service: S) -> Self::Service { - CacheService { service } + CacheService::new(service) } } - -#[derive(Clone)] -pub struct CacheService { - service: S, -} - -impl Service for CacheService -where - S: Service, - // Request: fmt::Debug + Serialize, - Request: fmt::Debug, -{ - type Response = S::Response; - type Error = S::Error; - type Future = S::Future; - - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.service.poll_ready(cx) - } - - fn call(&mut self, request: Request) -> Self::Future { - // let wrapper = Wrapper(request); - // let cache_key = wrapper.cache_key(); - // println!("request = {:?}", request); - // println!("cache_key = {:?}", cache_key); - // self.service.call(wrapper.into_inner()) - // let a = serde_json::to_string(&request); - // dbg!(&a); - self.service.call(request) - } -} - -// #[derive(Serialize, Clone)] -// pub struct Wrapper(Request); -// -// impl Wrapper { -// pub fn into_inner(self) -> Request { -// self.0 -// } -// } -// -// impl Cacheable for Wrapper -// where -// Request: Serialize -// { -// fn cache_key(&self) -> Result { -// Ok(serde_json::to_string(&self).unwrap()) -// } -// -// fn cache_key_prefix(&self) -> String { -// todo!() -// } -// } diff --git a/hitbox-axum/src/lib.rs b/hitbox-axum/src/lib.rs index e8bd6e9..74f3141 100644 --- a/hitbox-axum/src/lib.rs +++ b/hitbox-axum/src/lib.rs @@ -1,3 +1,6 @@ mod layer; +mod service; +mod cacheable; -pub use layer::CacheLayer; \ No newline at end of file +pub use layer::CacheLayer; +pub use cacheable::Wrapper; \ No newline at end of file diff --git a/hitbox-axum/src/service.rs b/hitbox-axum/src/service.rs new file mode 100644 index 0000000..df2254c --- /dev/null +++ b/hitbox-axum/src/service.rs @@ -0,0 +1,38 @@ +use tower_service::Service; +use axum::http::{Request, Response}; +use std::task::{Poll, Context}; +use crate::Wrapper; +use hitbox::{Cacheable, CacheError}; + +#[derive(Clone)] +pub struct CacheService { + service: S, +} + +impl CacheService { + pub fn new(service: S) -> CacheService { + CacheService { service } + } +} + +impl Service> for CacheService +where + S: Service, Response = Response> + Clone + Send + 'static, + S::Future: Send + 'static, + ReqBody: Send + 'static, + ResBody: Send + 'static, +{ + type Response = S::Response; + type Error = S::Error; + type Future = S::Future; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.service.poll_ready(cx) + } + + fn call(&mut self, mut request: Request) -> Self::Future { + let wrapper = Wrapper { request }; + // let cache_key = wrapper.cache_key(); + self.service.call(wrapper.into_inner()) + } +}