Open chrisbutcher opened 3 years ago
cc: @eapache @RobertWSaunders
This explanation makes sense to me, though it raises one other question: I consistently see execute_multiplex
running after lex and parse, and you seem to consistently see it running before. What's going on here?
@eapache In those instances, are you passing .multiplex
an already-parsed GraphQL::Query or a document string? This is my best guess as to why the order might differ.
This is in core, which instantiates a GraphQL::Query
instance with the string, and then calls .result
on it. AFAICT this intentionally lexes/parses before it enters the multiplexer: https://github.com/rmosolgo/graphql-ruby/blob/5c3a8ec6f45319f40cb59f2ffb5961bb1071aa80/lib/graphql/query.rb#L198-L200
This may be a genuine inconsistency within the graphql-ruby gem depending on the entrypoint you use?
On second thought: Problems 1 and 2 might not actually be problems?
While it's true that the pre_context
is not aware of mulitplexes (and multiple queries, contexts), we do run parse
, lex
and validate
in that order, each time we run validate
, we're using the values for parsing and lexing time that we last stored.
So long as graphql-ruby never runs something like parse
(query 1), lex
(query 1), parse
(query 2), lex
(query 2), validate
(query 1), validate
(query 2), and always does parse 1, lex 1, validate 1, parse n, lex n, validate n; we're ok?
Maybe the real problem is that if you pass a multiplex an unparsed document string and an already parsed query object (as one of our existing tests does), you don't always get a validate
event that is preceded by a parse
/lex
events for the same query.
If that's true, maybe we just need to clear the pre_context
after validate
makes use of any values within?
tldr after sync:
parse
, lex
and validate
run in that order (without interleaving across queries in a multiplex) Problems #1 and #2
as described above are not real.Problem #3
should be addressed by 1) still providing query execution time that includes the one-and-only execute_query_lazy
call, shared between queries in a multiplex, and 2) emit a separate metric per query that exclude lazy execution time, by recording an "end" time after the yield in capture_query_start_time
(again, to be renamed appropriately).pre_context
and context.pre_context
immediately after obtaining values we need from it during validate
, so we don't have a problem where a mixture of pre-parsed and parsed queries get incorrect values in validate
, having assumed that lex/parse
ran prior for the same query.
Edit: Problems
#1 and #2
appear to be non-problems. See below.As demonstrated in this PR, and in the below multiplex scenario walkthrough, timings for parsing, lexing and query duration are wrong when executing multiplexes.
There are last-write wins problems in lexing/parsing timings in the Tracer, and query durations are inaccurate because we wait until
Instrumentation.after_query
to calculate them.The queries being executed in the throwaway PR are:
#1
: This value will be overwritten by any later documents in the multiplex which are lexed.#2
: This value will be overwritten by any later documents in the multiplex which are parsed.#1
#2
#1

: This nth query will store the first query's lex and parse times.QueryOne
)QueryTwo
)execute_query
tracer event fired.#3
: Waiting untilInstrumentation.after_query
produces inaccurate query execution times. We should calculatequery_duration
in the Tracer instead, after theyield
incapture_query_start_time
(and rename that method for accuracy).execute_query
tracer event fired.#3
.