11use dashmap:: DashMap ;
22use ntex:: web:: HttpResponse ;
33use redis:: Commands ;
4- use sonic_rs:: json;
54
65use crate :: {
7- plugins:: traits:: {
8- ControlFlow , OnExecuteEnd , OnExecuteEndPayload , OnExecuteStart , OnExecuteStartPayload ,
9- OnSchemaReload , OnSchemaReloadPayload ,
10- } ,
6+ plugins:: traits:: { ControlFlow , OnExecuteControlFlow , OnExecutePayload , OnSchemaReloadPayload , RouterPlugin } ,
117 utils:: consts:: TYPENAME_FIELD_NAME ,
128} ;
139
@@ -26,20 +22,15 @@ impl ResponseCachePlugin {
2622 }
2723}
2824
29- pub struct ResponseCacheContext {
30- key : String ,
31- }
32-
33- impl OnExecuteStart for ResponseCachePlugin {
34- fn on_execute_start ( & self , payload : OnExecuteStartPayload ) -> ControlFlow {
25+ impl RouterPlugin for ResponseCachePlugin {
26+ fn on_execute < ' exec > (
27+ & ' static self ,
28+ payload : OnExecutePayload < ' exec > ,
29+ ) -> OnExecuteControlFlow < ' exec > {
3530 let key = format ! (
3631 "response_cache:{}:{:?}" ,
3732 payload. query_plan, payload. variable_values
3833 ) ;
39- payload
40- . router_http_request
41- . extensions_mut ( )
42- . insert ( ResponseCacheContext { key : key. clone ( ) } ) ;
4334 if let Ok ( mut conn) = self . redis_client . get_connection ( ) {
4435 let cached_response: Option < Vec < u8 > > = conn. get ( & key) . ok ( ) ;
4536 if let Some ( cached_response) = cached_response {
@@ -50,61 +41,47 @@ impl OnExecuteStart for ResponseCachePlugin {
5041 ) ;
5142 }
5243 }
53- ControlFlow :: Continue
54- }
55- }
44+ return ControlFlow :: OnEnd ( Box :: new ( move |payload| {
45+ // Do not cache if there are errors
46+ if !payload. errors . is_empty ( ) {
47+ return ( ) ;
48+ }
5649
57- impl OnExecuteEnd for ResponseCachePlugin {
58- fn on_execute_end ( & self , payload : OnExecuteEndPayload ) -> ControlFlow {
59- // Do not cache if there are errors
60- if !payload. errors . is_empty ( ) {
61- return ControlFlow :: Continue ;
62- }
63- if let Some ( key) = payload
64- . router_http_request
65- . extensions ( )
66- . get :: < ResponseCacheContext > ( )
67- . map ( |ctx| & ctx. key )
68- {
69- if let Ok ( mut conn) = self . redis_client . get_connection ( ) {
70- if let Ok ( serialized) = sonic_rs:: to_vec ( & payload. data ) {
71- // Decide on the ttl somehow
72- // Get the type names
73- let mut max_ttl = 0 ;
50+ if let Ok ( mut conn) = self . redis_client . get_connection ( ) {
51+ if let Ok ( serialized) = sonic_rs:: to_vec ( & payload. data ) {
52+ // Decide on the ttl somehow
53+ // Get the type names
54+ let mut max_ttl = 0 ;
7455
75- // Imagine this code is traversing the response data to find type names
76- if let Some ( obj) = payload. data . as_object ( ) {
77- if let Some ( typename) = obj
78- . iter ( )
79- . position ( |( k, _) | k == & TYPENAME_FIELD_NAME )
80- . and_then ( |idx| obj[ idx] . 1 . as_str ( ) )
81- {
82- if let Some ( ttl) = self . ttl_per_type . get ( typename) . map ( |v| * v) {
83- max_ttl = max_ttl. max ( ttl) ;
56+ // Imagine this code is traversing the response data to find type names
57+ if let Some ( obj) = payload. data . as_object ( ) {
58+ if let Some ( typename) = obj
59+ . iter ( )
60+ . position ( |( k, _) | k == & TYPENAME_FIELD_NAME )
61+ . and_then ( |idx| obj[ idx] . 1 . as_str ( ) )
62+ {
63+ if let Some ( ttl) = self . ttl_per_type . get ( typename) . map ( |v| * v) {
64+ max_ttl = max_ttl. max ( ttl) ;
65+ }
8466 }
8567 }
86- }
8768
88- // If no ttl found, default to 60 seconds
89- if max_ttl == 0 {
90- max_ttl = 60 ;
91- }
69+ // If no ttl found, default to 60 seconds
70+ if max_ttl == 0 {
71+ max_ttl = 60 ;
72+ }
9273
93- // Insert the ttl into extensions for client awareness
94- payload
95- . extensions
96- . insert ( "response_cache_ttl" . to_string ( ) , json ! ( max_ttl) ) ;
74+ // Insert the ttl into extensions for client awareness
75+ payload
76+ . extensions
77+ . insert ( "response_cache_ttl" . to_string ( ) , sonic_rs :: json!( max_ttl) ) ;
9778
98- // Set the cache with the decided ttl
99- let _: ( ) = conn. set_ex ( key, serialized, max_ttl) . unwrap_or ( ( ) ) ;
79+ // Set the cache with the decided ttl
80+ let _: ( ) = conn. set_ex ( key, serialized, max_ttl) . unwrap_or ( ( ) ) ;
81+ }
10082 }
101- }
102- }
103- ControlFlow :: Continue
83+ } ) ) ;
10484 }
105- }
106-
107- impl OnSchemaReload for ResponseCachePlugin {
10885 fn on_schema_reload ( & self , payload : OnSchemaReloadPayload ) {
10986 // Visit the schema and update ttl_per_type based on some directive
11087 payload
0 commit comments