@@ -105,6 +105,89 @@ where
105105 }
106106}
107107
108+ // Execute a chain of before middleware functions with batched GIL acquisition
109+ #[ inline]
110+ pub async fn execute_before_middleware_chain (
111+ input : & Request ,
112+ middlewares : & [ FunctionInfo ] ,
113+ ) -> Result < MiddlewareReturn > {
114+ let mut current_request = input. clone ( ) ;
115+
116+ // Check if all middlewares are sync to optimize GIL usage
117+ let all_sync = middlewares. iter ( ) . all ( |m| !m. is_async ) ;
118+
119+ if all_sync {
120+ // Execute all sync middlewares in a single GIL acquisition
121+ Python :: with_gil ( |py| -> Result < MiddlewareReturn > {
122+ for middleware in middlewares {
123+ let output = get_function_output ( middleware, py, & current_request) ?;
124+
125+ // Try response extraction first, then request
126+ match output. extract :: < Response > ( ) {
127+ Ok ( response) => return Ok ( MiddlewareReturn :: Response ( response) ) ,
128+ Err ( _) => match output. extract :: < Request > ( ) {
129+ Ok ( request) => current_request = request,
130+ Err ( e) => return Err ( e. into ( ) ) ,
131+ } ,
132+ }
133+ }
134+
135+ Ok ( MiddlewareReturn :: Request ( current_request) )
136+ } )
137+ } else {
138+ // Fall back to individual execution for mixed sync/async middlewares
139+ for middleware in middlewares {
140+ current_request = match execute_middleware_function ( & current_request, middleware) . await ? {
141+ MiddlewareReturn :: Request ( r) => r,
142+ MiddlewareReturn :: Response ( r) => return Ok ( MiddlewareReturn :: Response ( r) ) ,
143+ } ;
144+ }
145+
146+ Ok ( MiddlewareReturn :: Request ( current_request) )
147+ }
148+ }
149+
150+ // Execute a chain of after middleware functions with batched GIL acquisition
151+ #[ inline]
152+ pub async fn execute_after_middleware_chain (
153+ input : & Response ,
154+ middlewares : & [ FunctionInfo ] ,
155+ ) -> Result < MiddlewareReturn > {
156+ let mut current_response = input. clone ( ) ;
157+
158+ // Check if all middlewares are sync to optimize GIL usage
159+ let all_sync = middlewares. iter ( ) . all ( |m| !m. is_async ) ;
160+
161+ if all_sync {
162+ // Execute all sync middlewares in a single GIL acquisition
163+ Python :: with_gil ( |py| -> Result < MiddlewareReturn > {
164+ for middleware in middlewares {
165+ let output = get_function_output ( middleware, py, & current_response) ?;
166+
167+ // After middleware should return Response
168+ match output. extract :: < Response > ( ) {
169+ Ok ( response) => current_response = response,
170+ Err ( e) => return Err ( e. into ( ) ) ,
171+ }
172+ }
173+
174+ Ok ( MiddlewareReturn :: Response ( current_response) )
175+ } )
176+ } else {
177+ // Fall back to individual execution for mixed sync/async middlewares
178+ for middleware in middlewares {
179+ current_response = match execute_middleware_function ( & current_response, middleware) . await ? {
180+ MiddlewareReturn :: Response ( r) => r,
181+ MiddlewareReturn :: Request ( _) => {
182+ return Err ( anyhow:: anyhow!( "After middleware returned a request" ) )
183+ }
184+ } ;
185+ }
186+
187+ Ok ( MiddlewareReturn :: Response ( current_response) )
188+ }
189+ }
190+
108191#[ inline]
109192pub async fn execute_http_function (
110193 request : & Request ,
0 commit comments