diff --git a/src/core/app_context.rs b/src/core/app_context.rs index fa9b255a44..347cbc2801 100644 --- a/src/core/app_context.rs +++ b/src/core/app_context.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use async_graphql::dynamic::{self, DynamicRequest}; +use async_graphql::Response; use async_graphql_value::ConstValue; use dashmap::DashMap; @@ -29,7 +30,7 @@ pub struct AppContext { pub endpoints: EndpointSet, pub auth_ctx: Arc, pub dedupe_handler: Arc>, - pub dedupe_operation_handler: DedupeResult, Error>, + pub dedupe_operation_handler: DedupeResult, Error>, pub operation_plans: DashMap>, } diff --git a/src/core/http/request_handler.rs b/src/core/http/request_handler.rs index ab1c7de0b1..8b52fe6780 100644 --- a/src/core/http/request_handler.rs +++ b/src/core/http/request_handler.rs @@ -55,11 +55,8 @@ fn not_found() -> Result> { } fn create_request_context(req: &Request, app_ctx: &AppContext) -> RequestContext { - let upstream = app_ctx.blueprint.upstream.clone(); - let allowed = upstream.allowed_headers; - let allowed_headers = create_allowed_headers(req.headers(), &allowed); - - let _allowed = app_ctx.blueprint.server.get_experimental_headers(); + let allowed_headers = + create_allowed_headers(req.headers(), &app_ctx.blueprint.upstream.allowed_headers); RequestContext::from(app_ctx).allowed_headers(allowed_headers) } @@ -132,17 +129,15 @@ pub async fn graphql_request( async fn execute_query( app_ctx: &Arc, req_ctx: &Arc, - mut request: T, + request: T, req: Parts, ) -> anyhow::Result> { let mut response = if app_ctx.blueprint.server.enable_jit { - let is_query = request.is_query(); let operation_id = request.operation_id(&req.headers); request .execute(&JITExecutor::new( app_ctx.clone(), req_ctx.clone(), - is_query, operation_id, )) .await @@ -157,7 +152,7 @@ async fn execute_query( } fn create_allowed_headers(headers: &HeaderMap, allowed: &BTreeSet) -> HeaderMap { - let mut new_headers = HeaderMap::new(); + let mut new_headers = HeaderMap::with_capacity(allowed.len()); for (k, v) in headers.iter() { if allowed .iter() diff --git a/src/core/jit/exec_const.rs b/src/core/jit/exec_const.rs index aa2bd0a75f..c407934655 100644 --- a/src/core/jit/exec_const.rs +++ b/src/core/jit/exec_const.rs @@ -80,7 +80,7 @@ impl ConstValueExecutor { let response = exe.execute(synth).await; // Cache the response if we know the output is always the same - if is_const { + if is_const && self.response.is_none() { self.response = Some(response.clone()); } diff --git a/src/core/jit/graphql_executor.rs b/src/core/jit/graphql_executor.rs index 9249580aae..0d6952b90d 100644 --- a/src/core/jit/graphql_executor.rs +++ b/src/core/jit/graphql_executor.rs @@ -19,7 +19,6 @@ use crate::core::merge_right::MergeRight; pub struct JITExecutor { app_ctx: Arc, req_ctx: Arc, - is_query: bool, operation_id: OperationId, } @@ -27,11 +26,11 @@ impl JITExecutor { pub fn new( app_ctx: Arc, req_ctx: Arc, - is_query: bool, operation_id: OperationId, ) -> Self { - Self { app_ctx, req_ctx, is_query, operation_id } + Self { app_ctx, req_ctx, operation_id } } + #[inline(always)] async fn exec( &self, @@ -40,12 +39,10 @@ impl JITExecutor { ) -> Response { let is_introspection_query = self.app_ctx.blueprint.server.get_enable_introspection() && exec.plan.is_introspection_query; - let jit_resp = exec .execute(&self.req_ctx, &jit_request) .await .into_async_graphql(); - if is_introspection_query { let async_req = async_graphql::Request::from(jit_request).only_introspection(); let async_resp = self.app_ctx.execute(async_req).await; @@ -54,6 +51,7 @@ impl JITExecutor { jit_resp } } + #[inline(always)] async fn dedupe_and_exec( &self, @@ -117,7 +115,7 @@ impl Executor for JITExecutor { async move { let jit_request = jit::Request::from(request); - let exec = if let Some(op) = self.app_ctx.operation_plans.get(&hash) { + let mut exec = if let Some(op) = self.app_ctx.operation_plans.get(&hash) { ConstValueExecutor::from(op.value().clone()) } else { let exec = match ConstValueExecutor::try_new(&jit_request, &self.app_ctx) { @@ -128,9 +126,9 @@ impl Executor for JITExecutor { exec }; - if let Some(ref response) = exec.response { - response.clone().into_async_graphql() - } else if self.is_query && exec.plan.is_dedupe { + if let Some(response) = std::mem::take(&mut exec.response) { + response.into_async_graphql() + } else if exec.plan.is_query() && exec.plan.is_dedupe { self.dedupe_and_exec(exec, jit_request).await } else { self.exec(exec, jit_request).await