Skip to content

Commit 8d9a04e

Browse files
committed
graphql: added caching for validation phase
1 parent 5c585db commit 8d9a04e

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

graphql/src/execution/query.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ use graph::data::graphql::DocumentExt as _;
22
use graph::data::value::Object;
33
use graphql_parser::Pos;
44
use graphql_tools::validation::rules::*;
5+
use graphql_tools::validation::utils::ValidationError;
56
use graphql_tools::validation::validate::{validate, ValidationPlan};
67
use lazy_static::lazy_static;
78
use std::collections::{BTreeMap, HashMap, HashSet};
89
use std::hash::{Hash, Hasher};
910
use std::iter::FromIterator;
10-
use std::sync::Arc;
11+
use std::sync::{Arc, Mutex, PoisonError};
1112
use std::time::Instant;
1213
use std::{collections::hash_map::DefaultHasher, convert::TryFrom};
1314

@@ -23,6 +24,11 @@ use crate::schema::ast::{self as sast};
2324
use crate::values::coercion;
2425
use crate::{execution::get_field, schema::api::ErrorPolicy};
2526

27+
lazy_static! {
28+
static ref GRAPHQL_VALIDATION_CACHE: Mutex<HashMap<u64, Vec<ValidationError>>> =
29+
Mutex::new(HashMap::<u64, Vec<ValidationError>>::new());
30+
}
31+
2632
lazy_static! {
2733
static ref GRAPHQL_VALIDATION_PLAN: ValidationPlan = ValidationPlan::from(
2834
if std::env::var("ENABLE_GRAPHQL_VALIDATIONS").ok().is_none() {
@@ -145,17 +151,25 @@ impl Query {
145151
max_complexity: Option<u64>,
146152
max_depth: u8,
147153
) -> Result<Arc<Self>, Vec<QueryExecutionError>> {
148-
let validation_errors = validate(
149-
&schema.document(),
150-
&query.document,
151-
&GRAPHQL_VALIDATION_PLAN,
152-
);
154+
let mut validation_cache = GRAPHQL_VALIDATION_CACHE
155+
.lock()
156+
.unwrap_or_else(PoisonError::into_inner);
157+
let validation_errors = validation_cache.entry(query.shape_hash).or_insert_with(|| {
158+
validate(
159+
&schema.document(),
160+
&query.document,
161+
&GRAPHQL_VALIDATION_PLAN,
162+
)
163+
});
153164

154165
if validation_errors.len() > 0 {
155166
return Err(validation_errors
156167
.into_iter()
157168
.map(|e| {
158-
QueryExecutionError::ValidationError(e.locations.first().cloned(), e.message)
169+
QueryExecutionError::ValidationError(
170+
e.locations.first().cloned(),
171+
e.message.clone(),
172+
)
159173
})
160174
.collect());
161175
}

0 commit comments

Comments
 (0)