graphql-metrics 4.0.2 → 4.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2af911e9031c446b604b9c296caef2c89f00cb968ecf15350a6a196d6cab08d7
4
- data.tar.gz: 94e65ae882fd6222bf3b4ed9395f32dfc395ec00c85e061a458cb5fe54b9dc67
3
+ metadata.gz: 37973ad72745f698107a0877761b9b6fd8f065da661f044eec8b59cfe8c8be0b
4
+ data.tar.gz: 06d1bc48ac6640e982ef7c258306e99b0fde8808c8f57eddf1e0ef95baceabfa
5
5
  SHA512:
6
- metadata.gz: aa3ffe4208e67594c3e65786a0a0477cdcee71506dea37988db388433eb155175d87f92e30082931e5e8c493937876e9a5a4043327b74e9e17bc474d58bd4ed9
7
- data.tar.gz: e876e9f5907cff0863a6ead3e319f34ab238b1904d0f72c8874420fdf50b5cb2941cb0f77fcfbefac35968c2bb86ec6364c5e338842dcee591eb165ee2ed14d6
6
+ metadata.gz: 25a8e51676bd6d62e9c6dd039a0b23388c7f60fbcb994ccaa171d7e1956dfb0cb0fb8d4fbb826468357bcd4cbc96a118659cde38f81f4c6303870c4b2dc7516c
7
+ data.tar.gz: a2a47c0f7a88c5f9e01e5be0bf464e3c6ff4b3a4ebf88d3c221c18e9ee6d1f65d8cf4dfe9492599d4cd386b0fa3efe33ba2887d94d2512fdcdcd6160b1743aea
@@ -1,3 +1,8 @@
1
+ 4.0.3
2
+ -----
3
+ - [32](https://github.com/Shopify/graphql-metrics/pull/32) Split validate and analyze_query tracer events (encompasses #30).
4
+ - [30](https://github.com/Shopify/graphql-metrics/pull/30) Handle queries that have already been parsed (thank you @jturkel).
5
+
1
6
  4.0.2
2
7
  -----
3
8
  - [25](https://github.com/Shopify/graphql-metrics/pull/25) Safely handle interrupted runtime metrics.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql-metrics (4.0.1)
4
+ graphql-metrics (4.0.3)
5
5
  concurrent-ruby (~> 1.1.0)
6
6
  graphql (>= 1.10.8)
7
7
 
data/README.md CHANGED
@@ -54,8 +54,8 @@ parsing and validation runtime metrics will not be added to the `metrics` hash.
54
54
  ### Define your own analyzer subclass
55
55
 
56
56
  ```ruby
57
- class CaptureAllMetricsAnalyzer < GraphQL::Metrics::Analyzer
58
- ANALYZER_NAMESPACE = :capture_all_metrics_analyzer_namespace
57
+ class SimpleAnalyzer < GraphQL::Metrics::Analyzer
58
+ ANALYZER_NAMESPACE = :simple_analyzer_namespace
59
59
 
60
60
  def initialize(query_or_multiplex)
61
61
  super
@@ -78,6 +78,8 @@ parsing and validation runtime metrics will not be added to the `metrics` hash.
78
78
  # parsing_duration: 0.0008190000080503523,
79
79
  # validation_start_time_offset: 0.0030819999519735575,
80
80
  # validation_duration: 0.01704599999357015,
81
+ # analysis_start_time_offset: 0.0010339999571442604,
82
+ # analysis_duration: 0.0008190000080503523,
81
83
  # }
82
84
  #
83
85
  # You can use these metrics to track high-level query performance, along with any other details you wish to
@@ -221,10 +223,11 @@ your application as intended, here's a breakdown of the order of execution of th
221
223
 
222
224
  When used as instrumentation, an analyzer and tracing, the order of execution is:
223
225
 
224
- * Tracer.setup_tracing_before_lexing
226
+ * Tracer.setup_tracing
225
227
  * Tracer.capture_parsing_time
226
228
  * Instrumentation.before_query (context setup)
227
- * Tracer.capture_validation_time (twice, once for `analyze_query`, then `analyze_multiplex`)
229
+ * Tracer.capture_validation_time
230
+ * Tracer.capture_analysis_time
228
231
  * Analyzer#initialize (bit more context setup, instance vars setup)
229
232
  * Analyzer#result
230
233
  * Tracer.trace_field (n times)
@@ -28,6 +28,8 @@ module GraphQL
28
28
  PARSING_DURATION = :parsing_duration
29
29
  VALIDATION_START_TIME_OFFSET = :validation_start_time_offset
30
30
  VALIDATION_DURATION = :validation_duration
31
+ ANALYSIS_START_TIME_OFFSET = :analysis_start_time_offset
32
+ ANALYSIS_DURATION = :analysis_duration
31
33
  INLINE_FIELD_TIMINGS = :inline_field_timings
32
34
  LAZY_FIELD_TIMINGS = :lazy_field_timings
33
35
 
@@ -50,7 +50,7 @@ module GraphQL
50
50
  field_name: node.name,
51
51
  return_type_name: visitor.type_definition.graphql_name,
52
52
  parent_type_name: visitor.parent_type_definition.graphql_name,
53
- deprecated: visitor.field_definition.deprecation_reason.present?,
53
+ deprecated: !visitor.field_definition.deprecation_reason.nil?,
54
54
  path: visitor.response_path,
55
55
  }
56
56
 
@@ -45,6 +45,8 @@ module GraphQL
45
45
  parsing_duration: ns[GraphQL::Metrics::PARSING_DURATION],
46
46
  validation_start_time_offset: ns[GraphQL::Metrics::VALIDATION_START_TIME_OFFSET],
47
47
  validation_duration: ns[GraphQL::Metrics::VALIDATION_DURATION],
48
+ analysis_start_time_offset: ns[GraphQL::Metrics::ANALYSIS_START_TIME_OFFSET],
49
+ analysis_duration: ns[GraphQL::Metrics::ANALYSIS_DURATION],
48
50
  }
49
51
 
50
52
  analyzer.extract_fields
@@ -4,9 +4,10 @@ module GraphQL
4
4
  module Metrics
5
5
  class Tracer
6
6
  # NOTE: These constants come from the graphql ruby gem.
7
- GRAPHQL_GEM_LEXING_KEY = 'lex'
7
+ GRAPHQL_GEM_EXECUTE_MULTIPLEX_KEY = 'execute_multiplex'
8
8
  GRAPHQL_GEM_PARSING_KEY = 'parse'
9
- GRAPHQL_GEM_VALIDATION_KEYS = ['validate', 'analyze_query']
9
+ GRAPHQL_GEM_VALIDATION_KEY = 'validate'
10
+ GRAPHQL_GEM_ANALYZE_KEY = 'analyze_query'
10
11
  GRAPHQL_GEM_TRACING_FIELD_KEYS = [
11
12
  GRAPHQL_GEM_TRACING_FIELD_KEY = 'execute_field',
12
13
  GRAPHQL_GEM_TRACING_LAZY_FIELD_KEY = 'execute_field_lazy'
@@ -22,21 +23,21 @@ module GraphQL
22
23
  # NOTE: Not all tracing events are handled here, but those that are are handled in this case statement in
23
24
  # chronological order.
24
25
  case key
25
- when GRAPHQL_GEM_LEXING_KEY
26
- return setup_tracing_before_lexing(&block)
26
+ when GRAPHQL_GEM_EXECUTE_MULTIPLEX_KEY
27
+ return setup_tracing(&block)
27
28
  when GRAPHQL_GEM_PARSING_KEY
28
29
  return capture_parsing_time(&block)
29
- when *GRAPHQL_GEM_VALIDATION_KEYS
30
+ when GRAPHQL_GEM_VALIDATION_KEY
30
31
  context = possible_context
31
-
32
- return yield unless context.query.valid?
33
32
  return capture_validation_time(context, &block)
33
+ when GRAPHQL_GEM_ANALYZE_KEY
34
+ context = possible_context
35
+ return capture_analysis_time(context, &block)
36
+
34
37
  when *GRAPHQL_GEM_TRACING_FIELD_KEYS
35
38
  return yield if data[:query].context[SKIP_FIELD_AND_ARGUMENT_METRICS]
36
39
  return yield unless GraphQL::Metrics.timings_capture_enabled?(data[:query].context)
37
40
 
38
- pre_context = nil
39
-
40
41
  context_key = case key
41
42
  when GRAPHQL_GEM_TRACING_FIELD_KEY
42
43
  GraphQL::Metrics::INLINE_FIELD_TIMINGS
@@ -52,15 +53,28 @@ module GraphQL
52
53
 
53
54
  private
54
55
 
56
+ PreContext = Struct.new(
57
+ :query_start_time,
58
+ :query_start_time_monotonic,
59
+ :parsing_start_time_offset,
60
+ :parsing_duration
61
+ ) do
62
+ def reset_parsing_timings
63
+ self[:parsing_start_time_offset] = nil
64
+ self[:parsing_duration] = nil
65
+ end
66
+ end
67
+
55
68
  def pre_context
56
69
  # NOTE: This is used to store timings from lexing, parsing, validation, before we have a context to store
57
70
  # values in. Uses thread-safe Concurrent::ThreadLocalVar to store a set of values per thread.
58
- @pre_context ||= Concurrent::ThreadLocalVar.new(OpenStruct.new)
71
+ @pre_context ||= Concurrent::ThreadLocalVar.new(PreContext.new)
72
+ @pre_context.value
59
73
  end
60
74
 
61
- def setup_tracing_before_lexing
62
- pre_context.value.query_start_time = GraphQL::Metrics.current_time
63
- pre_context.value.query_start_time_monotonic = GraphQL::Metrics.current_time_monotonic
75
+ def setup_tracing
76
+ pre_context.query_start_time = GraphQL::Metrics.current_time
77
+ pre_context.query_start_time_monotonic = GraphQL::Metrics.current_time_monotonic
64
78
 
65
79
  yield
66
80
  end
@@ -68,24 +82,41 @@ module GraphQL
68
82
  def capture_parsing_time
69
83
  timed_result = GraphQL::Metrics.time { yield }
70
84
 
71
- pre_context.value.parsing_start_time_offset = timed_result.start_time
72
- pre_context.value.parsing_duration = timed_result.duration
85
+ pre_context.parsing_start_time_offset = timed_result.start_time
86
+ pre_context.parsing_duration = timed_result.duration
73
87
 
74
88
  timed_result.result
75
89
  end
76
90
 
77
91
  def capture_validation_time(context)
78
- timed_result = GraphQL::Metrics.time(pre_context.value.query_start_time_monotonic) { yield }
92
+ if pre_context.parsing_duration.nil?
93
+ pre_context.parsing_start_time_offset = 0
94
+ pre_context.parsing_duration = 0
95
+ end
96
+
97
+ timed_result = GraphQL::Metrics.time(pre_context.query_start_time_monotonic) { yield }
79
98
 
80
99
  ns = context.namespace(CONTEXT_NAMESPACE)
81
- previous_validation_duration = ns[GraphQL::Metrics::VALIDATION_DURATION] || 0
82
100
 
83
- ns[QUERY_START_TIME] = pre_context.value.query_start_time
84
- ns[QUERY_START_TIME_MONOTONIC] = pre_context.value.query_start_time_monotonic
85
- ns[PARSING_START_TIME_OFFSET] = pre_context.value.parsing_start_time_offset
86
- ns[PARSING_DURATION] = pre_context.value.parsing_duration
101
+ ns[QUERY_START_TIME] = pre_context.query_start_time
102
+ ns[QUERY_START_TIME_MONOTONIC] = pre_context.query_start_time_monotonic
103
+ ns[PARSING_START_TIME_OFFSET] = pre_context.parsing_start_time_offset
104
+ ns[PARSING_DURATION] = pre_context.parsing_duration
87
105
  ns[VALIDATION_START_TIME_OFFSET] = timed_result.time_since_offset
88
- ns[VALIDATION_DURATION] = timed_result.duration + previous_validation_duration
106
+ ns[VALIDATION_DURATION] = timed_result.duration
107
+
108
+ pre_context.reset_parsing_timings
109
+
110
+ timed_result.result
111
+ end
112
+
113
+ def capture_analysis_time(context)
114
+ ns = context.namespace(CONTEXT_NAMESPACE)
115
+
116
+ timed_result = GraphQL::Metrics.time(ns[QUERY_START_TIME_MONOTONIC]) { yield }
117
+
118
+ ns[ANALYSIS_START_TIME_OFFSET] = timed_result.time_since_offset
119
+ ns[ANALYSIS_DURATION] = timed_result.duration
89
120
 
90
121
  timed_result.result
91
122
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module Metrics
5
- VERSION = "4.0.2"
5
+ VERSION = "4.0.3"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.2
4
+ version: 4.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Butcher
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-11 00:00:00.000000000 Z
11
+ date: 2020-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql