Skip to content

Commit

Permalink
Merge branch 'chore/cache-op' into pref/small-improvements
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/core/jit/graphql_executor.rs
  • Loading branch information
tusharmath committed Oct 20, 2024
2 parents bf4b284 + 78891c5 commit bb910bb
Show file tree
Hide file tree
Showing 26 changed files with 171 additions and 352 deletions.
98 changes: 49 additions & 49 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 0 additions & 17 deletions src/core/ir/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,6 @@ impl IR {
}
}
}

/// Checks if the IR will always evaluate to a Constant Value
pub fn is_const(&self) -> bool {
match self {
IR::Dynamic(dynamic_value) => dynamic_value.is_const(),
IR::IO(_) => false,
IR::Cache(_) => false,
IR::Path(ir, _) => ir.is_const(),
IR::ContextPath(_) => false,
IR::Protect(ir) => ir.is_const(),
IR::Map(map) => map.input.is_const(),
IR::Pipe(ir, ir1) => ir.is_const() && ir1.is_const(),
IR::Discriminate(_, ir) => ir.is_const(),
IR::Entity(hash_map) => hash_map.values().all(|ir| ir.is_const()),
IR::Service(_) => true,
}
}
}

impl<'a, Ctx: ResolverContextLike + Sync> CacheKey<EvalContext<'a, Ctx>> for IO {
Expand Down
46 changes: 16 additions & 30 deletions src/core/jit/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ impl Builder {
selection: &SelectionSet,
type_condition: &str,
fragments: &HashMap<&str, &FragmentDefinition>,
parent_id: Option<FieldId>,
) -> Vec<Field<Value>> {
let mut fields = vec![];

Expand Down Expand Up @@ -199,12 +198,8 @@ impl Builder {
let id = FieldId::new(self.field_id.next());

// Recursively gather child fields for the selection set
let child_fields = self.iter(
&gql_field.selection_set.node,
type_of.name(),
fragments,
Some(id.clone()),
);
let child_fields =
self.iter(&gql_field.selection_set.node, type_of.name(), fragments);

let ir = match field_def {
QueryField::Field((field_def, _)) => field_def.resolver.clone(),
Expand All @@ -214,7 +209,6 @@ impl Builder {
// Create the field with its child fields in `selection`
let field = Field {
id,
parent_id: parent_id.clone(),
selection: child_fields,
name: field_name.to_string(),
output_name: gql_field
Expand All @@ -236,7 +230,6 @@ impl Builder {
} else if field_name == "__typename" {
let typename_field = Field {
id: FieldId::new(self.field_id.next()),
parent_id: parent_id.clone(),
name: field_name.to_string(),
output_name: field_name.to_string(),
ir: None,
Expand All @@ -261,7 +254,6 @@ impl Builder {
&fragment.selection_set.node,
fragment.type_condition.node.on.node.as_str(),
fragments,
parent_id.clone(),
));
}
}
Expand All @@ -272,12 +264,7 @@ impl Builder {
.map(|cond| cond.node.on.node.as_str())
.unwrap_or(type_condition);

fields.extend(self.iter(
&fragment.selection_set.node,
type_of,
fragments,
parent_id.clone(),
));
fields.extend(self.iter(&fragment.selection_set.node, type_of, fragments));
}
}
}
Expand Down Expand Up @@ -333,7 +320,7 @@ impl Builder {
let name = self
.get_type(operation.ty)
.ok_or(BuildError::RootOperationTypeNotDefined { operation: operation.ty })?;
let fields = self.iter(&operation.selection_set.node, name, &fragments, None);
let fields = self.iter(&operation.selection_set.node, name, &fragments);

let is_introspection_query = operation.selection_set.node.items.iter().any(|f| {
if let Selection::Field(Positioned { node: gql_field, .. }) = &f.node {
Expand Down Expand Up @@ -383,9 +370,8 @@ mod tests {
}
"#,
);
println!("{:#?}", plan.selection);
assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[tokio::test]
Expand Down Expand Up @@ -413,7 +399,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -427,7 +413,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand Down Expand Up @@ -455,7 +441,7 @@ mod tests {
);

assert!(!plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand Down Expand Up @@ -483,7 +469,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -504,7 +490,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -521,7 +507,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -542,7 +528,7 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -562,7 +548,7 @@ mod tests {
);

assert!(!plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand Down Expand Up @@ -656,13 +642,13 @@ mod tests {
.build(Some("GetPosts"))
.unwrap();
assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);

let plan = Builder::new(&blueprint, document.clone())
.build(Some("CreateNewPost"))
.unwrap();
assert!(!plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}

#[test]
Expand All @@ -679,6 +665,6 @@ mod tests {
);

assert!(plan.is_query());
insta::assert_debug_snapshot!(plan.into_nested());
insta::assert_debug_snapshot!(plan.selection);
}
}
18 changes: 8 additions & 10 deletions src/core/jit/common/jp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use crate::core::jit::builder::Builder;
use crate::core::jit::store::Store;
use crate::core::jit::synth::Synth;
use crate::core::jit::transform::InputResolver;
use crate::core::jit::{OperationPlan, Variables};
use crate::core::jit::{transform, OperationPlan, Variables};
use crate::core::json::{JsonLike, JsonObjectLike};
use crate::core::valid::Validator;
use crate::core::Transform;

/// NOTE: This is a bit of a boilerplate reducing module that is used in tests
/// and benchmarks.
Expand Down Expand Up @@ -92,15 +93,12 @@ impl<'a, Value: Deserialize<'a> + Clone + 'a + JsonLike<'a> + std::fmt::Debug> J
async_graphql::parser::parse_query(query).unwrap(),
);

let mut plan = builder.build(None).unwrap();
plan = plan.filter_skipped(variables);
let plan = OperationPlan::new(
&plan.root_name,
plan.selection,
plan.operation_type,
plan.index,
plan.is_introspection_query,
);
let plan = builder.build(None).unwrap();
let plan = transform::Skip::new(variables)
.transform(plan)
.to_result()
.unwrap();

let input_resolver = InputResolver::new(plan);
let plan = input_resolver.resolve_input(variables).unwrap();

Expand Down
4 changes: 2 additions & 2 deletions src/core/jit/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ mod test {
#[test]
fn test_field() {
let plan = setup("query {posts {id title}}").unwrap();
let field = plan.as_nested();
let field = &plan.selection;
let env = RequestContext::new(plan.clone());
let ctx = Context::<ConstValue, ConstValue>::new(&field[0], &env);
let expected = <Context<_, _> as ResolverContextLike>::field(&ctx).unwrap();
Expand All @@ -146,7 +146,7 @@ mod test {
fn test_is_query() {
let plan = setup("query {posts {id title}}").unwrap();
let env = RequestContext::new(plan.clone());
let ctx = Context::new(&plan.as_nested()[0], &env);
let ctx = Context::new(&plan.selection[0], &env);
assert!(ctx.is_query());
}
}
2 changes: 1 addition & 1 deletion src/core/jit/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ where
}

async fn init(&mut self) {
join_all(self.request.plan().as_nested().iter().map(|field| async {
join_all(self.request.plan().selection.iter().map(|field| async {
let ctx = Context::new(field, self.request);
// TODO: with_args should be called on inside iter_field on any level, not only
// for root fields
Expand Down
2 changes: 1 addition & 1 deletion src/core/jit/graphql_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Executor for JITExecutor {

if let Some(response) = std::mem::take(&mut exec.response) {
response.into_async_graphql()
} else if exec.plan.is_query() && exec.plan.dedupe {
} 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
Expand Down
Loading

1 comment on commit bb910bb

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running 30s test @ http://localhost:8000/graphql

4 threads and 100 connections

Thread Stats Avg Stdev Max +/- Stdev
Latency 10.02ms 4.34ms 194.09ms 91.66%
Req/Sec 2.55k 397.85 3.97k 83.08%

304166 requests in 30.02s, 1.52GB read

Requests/sec: 10131.74

Transfer/sec: 52.00MB

Please sign in to comment.