1 1 use super::remote_joins::types::{JoinNode, RemoteJoinType}; 2 - use super::ExecuteOrExplainResponse; 2 + use super::{ ExecuteOrExplainResponse, HttpContext } ; 3 3 use crate::execute::ndc::client as ndc_client; 4 4 use crate::execute::plan::{ApolloFederationSelect, NodeQueryPlan, ProcessResponseAs}; 5 5 use crate::execute::remote_joins::types::{JoinId, JoinLocations, RemoteJoin}; skipped 11 lines 17 17 use lang_graphql::ast::common as ast; 18 18 19 19 pub async fn execute_explain( 20 - http_client: &reqwest::Client, 20 + http_context: &HttpContext, 21 21 schema: &Schema<GDS>, 22 22 session: &Session, 23 23 request: RawRequest, 24 24 ) -> types::ExplainResponse { 25 - execute_explain_internal(http_client , schema, session, request) 25 + execute_explain_internal(http_context , schema, session, request) 26 26 .await 27 27 .unwrap_or_else(|e| types::ExplainResponse::error(e.to_graphql_error(None))) 28 28 } 29 29 30 30 /// Explains a GraphQL query 31 31 pub async fn execute_explain_internal( 32 - http_client: &reqwest::Client, 32 + http_context: &HttpContext, 33 33 schema: &gql::schema::Schema<GDS>, 34 34 session: &Session, 35 35 raw_request: gql::http::RawRequest, 36 36 ) -> Result<types::ExplainResponse, error::Error> { 37 37 let query_response = super::execute_request_internal( 38 - http_client, 38 + http_context, 39 39 schema, 40 40 session, 41 41 raw_request, skipped 13 lines 55 55 56 56 /// Produce an /explain plan for a given GraphQL query. 57 57 pub(crate) async fn explain_query_plan( 58 - http_client: &reqwest::Client, 58 + http_context: &HttpContext, 59 59 query_plan: plan::QueryPlan<'_, '_, '_>, 60 60 ) -> Result<types::Step, error::Error> { 61 61 let mut parallel_root_steps = vec![]; skipped 2 lines 64 64 match node { 65 65 NodeQueryPlan::NDCQueryExecution(ndc_query_execution) => { 66 66 let sequence_steps = get_execution_steps( 67 - http_client, 67 + http_context, 68 68 alias, 69 69 &ndc_query_execution.process_response_as, 70 70 ndc_query_execution.execution_tree.remote_executions, skipped 5 lines 76 76 } 77 77 NodeQueryPlan::RelayNodeSelect(Some(ndc_query_execution)) => { 78 78 let sequence_steps = get_execution_steps( 79 - http_client, 79 + http_context, 80 80 alias, 81 81 &ndc_query_execution.process_response_as, 82 82 ndc_query_execution.execution_tree.remote_executions, skipped 9 lines 92 92 let mut parallel_steps = Vec::new(); 93 93 for ndc_query_execution in parallel_ndc_query_executions { 94 94 let sequence_steps = get_execution_steps( 95 - http_client, 95 + http_context, 96 96 alias.clone(), 97 97 &ndc_query_execution.process_response_as, 98 98 ndc_query_execution.execution_tree.remote_executions, skipped 44 lines 143 143 144 144 /// Produce an /explain plan for a given GraphQL mutation. 145 145 pub(crate) async fn explain_mutation_plan( 146 - http_client: &reqwest::Client, 146 + http_context: &HttpContext, 147 147 mutation_plan: plan::MutationPlan<'_, '_, '_>, 148 148 ) -> Result<types::Step, error::Error> { 149 149 let mut root_steps = vec![]; skipped 7 lines 157 157 for (_, mutation_group) in mutation_plan.nodes { 158 158 for (alias, ndc_mutation_execution) in mutation_group { 159 159 let sequence_steps = get_execution_steps( 160 - http_client, 160 + http_context, 161 161 alias, 162 162 &ndc_mutation_execution.process_response_as, 163 163 ndc_mutation_execution.join_locations, skipped 18 lines 182 182 } 183 183 184 184 async fn get_execution_steps<'s>( 185 - http_client: &reqwest::Client, 185 + http_context: &HttpContext, 186 186 alias: gql::ast::common::Alias, 187 187 process_response_as: &ProcessResponseAs<'s>, 188 188 join_locations: JoinLocations<(RemoteJoin<'s, '_>, JoinId)>, skipped 3 lines 192 192 let mut sequence_steps = match process_response_as { 193 193 ProcessResponseAs::CommandResponse { .. } => { 194 194 // A command execution node 195 - let data_connector_explain = 196 - fetch_explain_from_data_connector(http_client, ndc_request.clone(), data_connector) 197 - .await; 195 + let data_connector_explain = fetch_explain_from_data_connector ( 196 + http_context, 197 + ndc_request.clone(), 198 + data_connector, 199 + ) 200 + .await; 198 201 NonEmpty::new(Box::new(types::Step::CommandSelect( 199 202 types::CommandSelectIR { 200 203 command_name: alias.to_string(), skipped 4 lines 205 208 } 206 209 ProcessResponseAs::Array { .. } | ProcessResponseAs::Object { .. } => { 207 210 // A model execution node 208 - let data_connector_explain = 209 - fetch_explain_from_data_connector(http_client, ndc_request.clone(), data_connector) 210 - .await; 211 + let data_connector_explain = fetch_explain_from_data_connector ( 212 + http_context, 213 + ndc_request.clone(), 214 + data_connector, 215 + ) 216 + .await; 211 217 NonEmpty::new(Box::new(types::Step::ModelSelect(types::ModelSelectIR { 212 218 model_name: alias.to_string(), 213 219 ndc_request, skipped 1 lines 215 221 }))) 216 222 } 217 223 }; 218 - if let Some(join_steps) = get_join_steps(alias.to_string(), join_locations, http_client ).await { 224 + if let Some(join_steps) = get_join_steps(alias.to_string(), join_locations, http_context ).await 225 + { 219 226 sequence_steps.push(Box::new(types::Step::Sequence(join_steps))); 220 227 sequence_steps.push(Box::new(types::Step::HashJoin)); 221 228 }; skipped 8 lines 230 237 async fn get_join_steps( 231 238 _root_field_name: String, 232 239 join_locations: JoinLocations<(RemoteJoin<'async_recursion, 'async_recursion>, JoinId)>, 233 - http_client: &reqwest::Client, 240 + http_context: &HttpContext, 234 241 ) -> Option<NonEmpty<Box<types::Step>>> { 235 242 let mut sequence_join_steps = vec![]; 236 243 for (alias, location) in join_locations.locations { skipped 3 lines 240 247 query_request.variables = Some(vec![]); 241 248 let ndc_request = types::NDCRequest::Query(query_request); 242 249 let data_connector_explain = fetch_explain_from_data_connector( 243 - http_client, 250 + http_context, 244 251 ndc_request.clone(), 245 252 remote_join.target_data_connector, 246 253 ) skipped 18 lines 265 272 }, 266 273 ))) 267 274 }; 268 - if let Some(rest_join_steps) = get_join_steps(alias, location.rest, http_client ).await { 275 + if let Some(rest_join_steps) = get_join_steps(alias, location.rest, http_context ).await { 269 276 sequence_steps.push(Box::new(types::Step::Sequence(rest_join_steps))); 270 277 sequence_steps.push(Box::new(types::Step::HashJoin)); 271 278 }; skipped 34 lines 306 313 } 307 314 308 315 async fn fetch_explain_from_data_connector( 309 - http_client: &reqwest::Client, 316 + http_context: &HttpContext, 310 317 ndc_request: types::NDCRequest, 311 318 data_connector: &resolved::data_connector::DataConnectorLink, 312 319 ) -> types::NDCExplainResponse { skipped 8 lines 321 328 base_path: data_connector.url.get_url(ast::OperationType::Query), 322 329 user_agent: None, 323 330 // This is isn't expensive, reqwest::Client is behind an Arc 324 - client: http_client .clone(), 331 + client: http_context . client .clone(), 325 332 headers: data_connector.headers.0.clone(), 333 + response_size_limit: http_context.ndc_response_size_limit, 326 334 }; 327 335 { 328 336 // TODO: use capabilities from the data connector context skipped 72 lines