Skip to content

Commit d907396

Browse files
authored
fix: patch dataloader to propagate context to new fiber (#1760)
1 parent 44337aa commit d907396

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

instrumentation/graphql/lib/opentelemetry/instrumentation/graphql/instrumentation.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base
2727
require_relative 'tracers/graphql_trace'
2828
install_new_tracer(config)
2929
end
30+
31+
patch
3032
end
3133

3234
present do
@@ -41,6 +43,10 @@ def supports_new_tracer?
4143
Gem::Requirement.new('>= 2.0.19').satisfied_by?(gem_version)
4244
end
4345

46+
def dataloader_has_spawn_fiber?
47+
Gem::Requirement.new('>= 2.1.8').satisfied_by?(gem_version)
48+
end
49+
4450
## Supported configuration keys for the install config hash:
4551
#
4652
# The enable_platform_field key expects a boolean value,
@@ -96,6 +102,13 @@ def install_new_tracer(config = {})
96102
end
97103
end
98104
end
105+
106+
def patch
107+
return unless dataloader_has_spawn_fiber?
108+
109+
require_relative 'patches/dataloader'
110+
::GraphQL::Dataloader.prepend(Patches::Dataloader)
111+
end
99112
end
100113
end
101114
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
module OpenTelemetry
8+
module Instrumentation
9+
module GraphQL
10+
module Patches
11+
# Patches GraphQL::Dataloader to propagate context to new fiber
12+
module Dataloader
13+
def spawn_fiber(&block)
14+
ctx = OpenTelemetry::Context.current
15+
super do
16+
OpenTelemetry::Context.with_current(ctx, &block)
17+
end
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
require 'test_helper'
8+
9+
require_relative '../../../../lib/opentelemetry/instrumentation/graphql'
10+
require_relative '../../../../lib/opentelemetry/instrumentation/graphql/patches/dataloader'
11+
12+
describe OpenTelemetry::Instrumentation::GraphQL::Patches::Dataloader do
13+
let(:instrumentation) { OpenTelemetry::Instrumentation::GraphQL::Instrumentation.instance }
14+
let(:tracer) { OpenTelemetry.tracer_provider.tracer('test') }
15+
let(:exporter) { EXPORTER }
16+
let(:spans) { exporter.finished_spans }
17+
18+
before do
19+
instrumentation.instance_variable_set(:@installed, false)
20+
instrumentation.install({})
21+
end
22+
23+
if OpenTelemetry::Instrumentation::GraphQL::Instrumentation.instance.dataloader_has_spawn_fiber?
24+
describe '#spawn_fiber' do
25+
it 'set context in the child fiber' do
26+
tracer.in_span('parent') do
27+
fiber = GraphQL::Dataloader.new.spawn_fiber do
28+
tracer.in_span('child1') do
29+
# empty block
30+
end
31+
Fiber.yield
32+
tracer.in_span('child2') do
33+
# empty block
34+
end
35+
end
36+
fiber.resume
37+
fiber.resume
38+
end
39+
40+
parent_span = spans.find { |s| s.name == 'parent' }
41+
child1_span = spans.find { |s| s.name == 'child1' }
42+
child2_span = spans.find { |s| s.name == 'child2' }
43+
44+
_(parent_span.span_id).must_equal(child1_span.parent_span_id)
45+
_(parent_span.span_id).must_equal(child2_span.parent_span_id)
46+
end
47+
end
48+
end
49+
end

0 commit comments

Comments
 (0)