@@ -15,8 +15,6 @@ use serde_json;
1515
1616use rivet_runner_protocol as protocol;
1717use std:: {
18- borrow:: Cow ,
19- collections:: HashMap as StdHashMap ,
2018 net:: SocketAddr ,
2119 sync:: Arc ,
2220 time:: { Duration , Instant } ,
@@ -134,44 +132,13 @@ pub struct RouteConfig {
134132pub enum RoutingOutput {
135133 /// Return the data to route to.
136134 Route ( RouteConfig ) ,
137- /// Return a custom response.
138- Response ( StructuredResponse ) ,
139135 /// Return a custom serve handler.
140136 CustomServe ( Arc < dyn CustomServeTrait > ) ,
141137}
142138
143- #[ derive( Clone , Debug ) ]
144- pub struct StructuredResponse {
145- pub status : StatusCode ,
146- pub message : Cow < ' static , str > ,
147- pub docs : Option < Cow < ' static , str > > ,
148- }
149-
150- impl StructuredResponse {
151- pub fn build_response ( & self ) -> Result < Response < ResponseBody > > {
152- let mut body = StdHashMap :: new ( ) ;
153- body. insert ( "message" , self . message . clone ( ) . into_owned ( ) ) ;
154-
155- if let Some ( docs) = & self . docs {
156- body. insert ( "docs" , docs. clone ( ) . into_owned ( ) ) ;
157- }
158-
159- let body_json = serde_json:: to_string ( & body) ?;
160- let bytes = Bytes :: from ( body_json) ;
161-
162- let response = Response :: builder ( )
163- . status ( self . status )
164- . header ( hyper:: header:: CONTENT_TYPE , "application/json" )
165- . body ( ResponseBody :: Full ( Full :: new ( bytes) ) ) ?;
166-
167- Ok ( response)
168- }
169- }
170-
171139#[ derive( Clone ) ]
172140enum ResolveRouteOutput {
173141 Target ( RouteTarget ) ,
174- Response ( StructuredResponse ) ,
175142 CustomServe ( Arc < dyn CustomServeTrait > ) ,
176143}
177144
@@ -347,6 +314,7 @@ pub struct ProxyState {
347314 cache_key_fn : CacheKeyFn ,
348315 middleware_fn : MiddlewareFn ,
349316 route_cache : RouteCache ,
317+ // We use moka::Cache instead of scc::HashMap because it automatically handles TTL and capacity
350318 rate_limiters : Cache < ( Id , std:: net:: IpAddr ) , Arc < Mutex < RateLimiter > > > ,
351319 in_flight_counters : Cache < ( Id , std:: net:: IpAddr ) , Arc < Mutex < InFlightCounter > > > ,
352320 in_flight_requests : Cache < protocol:: RequestId , ( ) > ,
@@ -478,15 +446,6 @@ impl ProxyState {
478446 Err ( errors:: NoRouteTargets . build ( ) )
479447 }
480448 }
481- RoutingOutput :: Response ( response) => {
482- tracing:: debug!(
483- hostname = %hostname_only,
484- path = %path,
485- status = ?response. status,
486- "Routing returned custom response"
487- ) ;
488- Ok ( ResolveRouteOutput :: Response ( response) )
489- }
490449 RoutingOutput :: CustomServe ( handler) => {
491450 tracing:: debug!(
492451 hostname = %hostname_only,
@@ -660,6 +619,7 @@ impl ProxyState {
660619
661620 // Release request ID
662621 self . in_flight_requests . invalidate ( & request_id) . await ;
622+ metrics:: IN_FLIGHT_REQUEST_COUNT . set ( self . in_flight_requests . entry_count ( ) as i64 ) ;
663623 }
664624
665625 /// Generate a unique request ID that is not currently in flight
@@ -668,11 +628,19 @@ impl ProxyState {
668628
669629 for attempt in 0 ..MAX_TRIES {
670630 let request_id = protocol:: util:: generate_request_id ( ) ;
631+ let mut inserted = false ;
671632
672633 // Check if this ID is already in use
673- if self . in_flight_requests . get ( & request_id) . await . is_none ( ) {
674- // Insert the ID and return it
675- self . in_flight_requests . insert ( request_id, ( ) ) . await ;
634+ self . in_flight_requests
635+ . entry ( request_id)
636+ . or_insert_with ( async {
637+ inserted = true ;
638+ } )
639+ . await ;
640+
641+ if inserted {
642+ metrics:: IN_FLIGHT_REQUEST_COUNT . set ( self . in_flight_requests . entry_count ( ) as i64 ) ;
643+
676644 return Ok ( request_id) ;
677645 }
678646
@@ -769,10 +737,6 @@ impl ProxyService {
769737
770738 // Resolve target
771739 let target = target_res?;
772- if let ResolveRouteOutput :: Response ( response) = & target {
773- // Return the custom response
774- return response. build_response ( ) ;
775- }
776740
777741 let actor_id = if let ResolveRouteOutput :: Target ( target) = & target {
778742 target. actor_id
@@ -1088,9 +1052,6 @@ impl ProxyService {
10881052 }
10891053 . build ( ) ) ;
10901054 }
1091- ResolveRouteOutput :: Response ( _) => {
1092- unreachable ! ( )
1093- }
10941055 ResolveRouteOutput :: CustomServe ( mut handler) => {
10951056 let req_headers = req. headers ( ) . clone ( ) ;
10961057 let req_method = req. method ( ) . clone ( ) ;
@@ -1554,20 +1515,6 @@ impl ProxyService {
15541515 Ok ( ResolveRouteOutput :: Target ( new_target) ) => {
15551516 target = new_target;
15561517 }
1557- Ok ( ResolveRouteOutput :: Response ( response) ) => {
1558- tracing:: debug!(
1559- status=?response. status,
1560- message=?response. message,
1561- docs=?response. docs,
1562- "got response instead of websocket target" ,
1563- ) ;
1564-
1565- // Close the WebSocket connection with the response message
1566- let _ = client_ws
1567- . close ( Some ( str_to_close_frame ( response. message . as_ref ( ) ) ) )
1568- . await ;
1569- return ;
1570- }
15711518 Ok ( ResolveRouteOutput :: CustomServe ( _) ) => {
15721519 let err = errors:: WebSocketTargetChanged . build ( ) ;
15731520 tracing:: warn!(
@@ -1907,7 +1854,6 @@ impl ProxyService {
19071854 . instrument ( tracing:: info_span!( "handle_ws_task_target" ) ) ,
19081855 ) ;
19091856 }
1910- ResolveRouteOutput :: Response ( _) => unreachable ! ( ) ,
19111857 ResolveRouteOutput :: CustomServe ( mut handler) => {
19121858 tracing:: debug!( %req_path, "Spawning task to handle WebSocket communication" ) ;
19131859 let mut request_context = request_context. clone ( ) ;
@@ -2090,19 +2036,6 @@ impl ProxyService {
20902036 handler = new_handler;
20912037 continue ;
20922038 }
2093- Ok ( ResolveRouteOutput :: Response ( response) ) => {
2094- ws_handle
2095- . send ( to_hyper_close ( Some ( str_to_close_frame (
2096- response. message . as_ref ( ) ,
2097- ) ) ) )
2098- . await ?;
2099-
2100- // Flush to ensure close frame is sent
2101- ws_handle. flush ( ) . await ?;
2102-
2103- // Keep TCP connection open briefly to allow client to process close
2104- tokio:: time:: sleep ( WEBSOCKET_CLOSE_LINGER ) . await ;
2105- }
21062039 Ok ( ResolveRouteOutput :: Target ( _) ) => {
21072040 let err = errors:: WebSocketTargetChanged . build ( ) ;
21082041 tracing:: warn!(
@@ -2666,16 +2599,6 @@ pub fn is_ws_hibernate(err: &anyhow::Error) -> bool {
26662599 }
26672600}
26682601
2669- fn str_to_close_frame ( err : & str ) -> CloseFrame {
2670- // NOTE: reason cannot be more than 123 bytes as per the WS protocol spec
2671- let reason = rivet_util:: safe_slice ( err, 0 , 123 ) . into ( ) ;
2672-
2673- CloseFrame {
2674- code : CloseCode :: Error ,
2675- reason,
2676- }
2677- }
2678-
26792602fn err_to_close_frame ( err : anyhow:: Error , ray_id : Option < Id > ) -> CloseFrame {
26802603 let rivet_err = err
26812604 . chain ( )
0 commit comments