freddy 1.5.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +31 -0
- data/.rubocop.yml +9 -28
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/Gemfile +3 -4
- data/README.md +49 -18
- data/freddy.gemspec +12 -18
- data/lib/freddy/adapters/bunny_adapter.rb +21 -4
- data/lib/freddy/adapters.rb +3 -28
- data/lib/freddy/consumers/respond_to_consumer.rb +3 -13
- data/lib/freddy/consumers/response_consumer.rb +2 -4
- data/lib/freddy/consumers/tap_into_consumer.rb +41 -25
- data/lib/freddy/consumers.rb +1 -1
- data/lib/freddy/delivery.rb +46 -13
- data/lib/freddy/encoding.rb +27 -0
- data/lib/freddy/payload.rb +4 -34
- data/lib/freddy/producers/reply_producer.rb +12 -5
- data/lib/freddy/producers/send_and_forget_producer.rb +9 -12
- data/lib/freddy/producers/send_and_wait_response_producer.rb +19 -33
- data/lib/freddy/producers.rb +1 -1
- data/lib/freddy/request_manager.rb +1 -9
- data/lib/freddy/tracing.rb +37 -0
- data/lib/freddy/version.rb +5 -0
- data/lib/freddy.rb +27 -20
- data/spec/.rubocop.yml +26 -0
- data/spec/freddy/error_response_spec.rb +6 -6
- data/spec/freddy/freddy_spec.rb +23 -0
- data/spec/freddy/payload_spec.rb +25 -16
- data/spec/integration/concurrency_spec.rb +8 -12
- data/spec/integration/tap_into_with_group_spec.rb +34 -0
- data/spec/integration/tracing_spec.rb +15 -32
- data/spec/spec_helper.rb +5 -13
- metadata +44 -17
- data/.npmignore +0 -8
- data/.travis.yml +0 -13
- data/lib/freddy/adapters/march_hare_adapter.rb +0 -64
- data/lib/freddy/trace_carrier.rb +0 -28
- data/spec/freddy/trace_carrier_spec.rb +0 -56
data/lib/freddy/producers.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
class Freddy
|
4
4
|
class RequestManager
|
5
5
|
def initialize(logger)
|
6
|
-
@requests =
|
6
|
+
@requests = {}
|
7
7
|
@logger = logger
|
8
8
|
end
|
9
9
|
|
@@ -22,13 +22,5 @@ class Freddy
|
|
22
22
|
def delete(correlation_id)
|
23
23
|
@requests.delete(correlation_id)
|
24
24
|
end
|
25
|
-
|
26
|
-
class ConcurrentHash < Hash
|
27
|
-
# CRuby hash does not need any locks. Only adding when using JRuby.
|
28
|
-
if RUBY_PLATFORM == 'java'
|
29
|
-
require 'jruby/synchronized'
|
30
|
-
include JRuby::Synchronized
|
31
|
-
end
|
32
|
-
end
|
33
25
|
end
|
34
26
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Freddy
|
4
|
+
module Tracing
|
5
|
+
# NOTE: Make sure you finish the span youself.
|
6
|
+
def self.span_for_produce(exchange, routing_key, payload, correlation_id: nil, timeout_in_seconds: nil)
|
7
|
+
destination = exchange.name
|
8
|
+
destination_kind = exchange.type == :direct ? 'queue' : 'topic'
|
9
|
+
|
10
|
+
attributes = {
|
11
|
+
'payload.type' => (payload[:type] || 'unknown').to_s,
|
12
|
+
OpenTelemetry::SemanticConventions::Trace::MESSAGING_SYSTEM => 'rabbitmq',
|
13
|
+
OpenTelemetry::SemanticConventions::Trace::MESSAGING_RABBITMQ_ROUTING_KEY => routing_key,
|
14
|
+
OpenTelemetry::SemanticConventions::Trace::MESSAGING_DESTINATION => destination,
|
15
|
+
OpenTelemetry::SemanticConventions::Trace::MESSAGING_DESTINATION_KIND => destination_kind,
|
16
|
+
OpenTelemetry::SemanticConventions::Trace::MESSAGING_OPERATION => 'send'
|
17
|
+
}
|
18
|
+
|
19
|
+
attributes['freddy.timeout_in_seconds'] = timeout_in_seconds if timeout_in_seconds
|
20
|
+
|
21
|
+
if correlation_id
|
22
|
+
attributes[OpenTelemetry::SemanticConventions::Trace::MESSAGING_CONVERSATION_ID] = correlation_id
|
23
|
+
end
|
24
|
+
|
25
|
+
Freddy.tracer.start_span(
|
26
|
+
".#{routing_key} send",
|
27
|
+
kind: OpenTelemetry::Trace::SpanKind::PRODUCER,
|
28
|
+
attributes: attributes
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.inject_tracing_information_to_properties!(properties)
|
33
|
+
properties[:headers] ||= {}
|
34
|
+
OpenTelemetry.propagation.inject(properties[:headers])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/freddy.rb
CHANGED
@@ -3,9 +3,11 @@
|
|
3
3
|
require 'json'
|
4
4
|
require 'thread/pool'
|
5
5
|
require 'securerandom'
|
6
|
-
require '
|
6
|
+
require 'opentelemetry'
|
7
|
+
require 'opentelemetry/semantic_conventions'
|
8
|
+
require_relative './freddy/version'
|
7
9
|
|
8
|
-
Dir[File.dirname(__FILE__)
|
10
|
+
Dir["#{File.dirname(__FILE__)}/freddy/*.rb"].sort.each(&method(:require))
|
9
11
|
|
10
12
|
class Freddy
|
11
13
|
FREDDY_TOPIC_EXCHANGE_NAME = 'freddy-topic'
|
@@ -26,22 +28,15 @@ class Freddy
|
|
26
28
|
# @return [Freddy]
|
27
29
|
#
|
28
30
|
# @example
|
29
|
-
# Freddy.build(Logger.new(
|
30
|
-
def self.build(logger = Logger.new(
|
31
|
-
OpenTracing.global_tracer ||= OpenTracing::Tracer.new
|
32
|
-
|
31
|
+
# Freddy.build(Logger.new($stdout), user: 'thumper', pass: 'howdy')
|
32
|
+
def self.build(logger = Logger.new($stdout), max_concurrency: DEFAULT_MAX_CONCURRENCY, **config)
|
33
33
|
connection = Adapters.determine.connect(config)
|
34
34
|
new(connection, logger, max_concurrency)
|
35
35
|
end
|
36
36
|
|
37
|
-
# @
|
38
|
-
def self.
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
# @deprecated Use OpenTracing ScopeManager instead
|
43
|
-
def self.trace=(trace)
|
44
|
-
OpenTracing.scope_manager.activate(trace) if OpenTracing.active_span != trace
|
37
|
+
# @private
|
38
|
+
def self.tracer
|
39
|
+
@tracer ||= OpenTelemetry.tracer_provider.tracer('freddy', Freddy::VERSION)
|
45
40
|
end
|
46
41
|
|
47
42
|
def initialize(connection, logger, max_concurrency)
|
@@ -70,7 +65,7 @@ class Freddy
|
|
70
65
|
# Received message as a ruby hash with symbolized keys
|
71
66
|
# @yieldparam [#success, #error] handler
|
72
67
|
# Handler for responding to messages. Use handler#success for successful
|
73
|
-
#
|
68
|
+
# response and handler#error for error response.
|
74
69
|
#
|
75
70
|
# @return [#shutdown]
|
76
71
|
#
|
@@ -104,13 +99,22 @@ class Freddy
|
|
104
99
|
# consuming them. It is useful for general messages that two or more clients
|
105
100
|
# are interested.
|
106
101
|
#
|
107
|
-
# @param [String]
|
102
|
+
# @param [String] pattern_or_patterns
|
108
103
|
# the destination pattern. Use `#` wildcard for matching 0 or more words.
|
109
104
|
# Use `*` to match exactly one word.
|
110
105
|
# @param [Hash] options
|
111
106
|
# @option options [String] :group
|
112
107
|
# only one of the listeners in given group will receive a message. All
|
113
108
|
# listeners will receive a message if the group is not specified.
|
109
|
+
# @option options [Boolean] :durable
|
110
|
+
# Should the consumer queue be durable? Default is `false`. This option can
|
111
|
+
# be used only in combination with option `:group`.
|
112
|
+
# @option options [Boolean] :on_exception
|
113
|
+
# Defines consumer's behaviour when the callback fails to process a message
|
114
|
+
# and raises an exception. Can be one of `:ack`, `:reject` or `:requeue`.
|
115
|
+
# `:ack` simply acknowledges the message and re-raises the exception. `:reject`
|
116
|
+
# rejects the message without requeueing it. `:requeue` rejects the message with
|
117
|
+
# `requeue` flag.
|
114
118
|
#
|
115
119
|
# @yield [message] Yields received message to the block
|
116
120
|
#
|
@@ -120,12 +124,12 @@ class Freddy
|
|
120
124
|
# freddy.tap_into 'notifications.*' do |message|
|
121
125
|
# puts "Notification showed #{message.inspect}"
|
122
126
|
# end
|
123
|
-
def tap_into(
|
124
|
-
@logger.debug "Tapping into messages that match #{
|
127
|
+
def tap_into(pattern_or_patterns, options = {}, &callback)
|
128
|
+
@logger.debug "Tapping into messages that match #{pattern_or_patterns}"
|
125
129
|
|
126
130
|
Consumers::TapIntoConsumer.consume(
|
127
131
|
thread_pool: Thread.pool(@prefetch_buffer_size),
|
128
|
-
|
132
|
+
patterns: Array(pattern_or_patterns),
|
129
133
|
channel: @connection.create_channel(prefetch: @prefetch_buffer_size),
|
130
134
|
options: options,
|
131
135
|
&callback
|
@@ -148,15 +152,18 @@ class Freddy
|
|
148
152
|
# @option options [Integer] :timeout (0)
|
149
153
|
# discards the message after given seconds if nobody consumes it. Message
|
150
154
|
# won't be discarded if timeout it set to 0 (default).
|
151
|
-
#
|
155
|
+
# @option options [String] :compress (nil)
|
156
|
+
# - 'zlib' - compresses the payload with zlib
|
152
157
|
# @return [void]
|
153
158
|
#
|
154
159
|
# @example
|
155
160
|
# freddy.deliver 'Metrics', user_id: 5, metric: 'signed_in'
|
156
161
|
def deliver(destination, payload, options = {})
|
157
162
|
timeout = options.fetch(:timeout, 0)
|
163
|
+
compression_algorithm = options.fetch(:compress, nil)
|
158
164
|
opts = {}
|
159
165
|
opts[:expiration] = (timeout * 1000).to_i if timeout.positive?
|
166
|
+
opts[:content_encoding] = compression_algorithm if compression_algorithm
|
160
167
|
|
161
168
|
@send_and_forget_producer.produce(destination, payload, opts)
|
162
169
|
end
|
data/spec/.rubocop.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
inherit_from: ../.rubocop.yml
|
3
|
+
|
4
|
+
RSpec/ExampleLength:
|
5
|
+
Enabled: no
|
6
|
+
|
7
|
+
RSpec/MultipleExpectations:
|
8
|
+
Enabled: no
|
9
|
+
|
10
|
+
RSpec/MessageSpies:
|
11
|
+
Enabled: no
|
12
|
+
|
13
|
+
RSpec/VerifiedDoubles:
|
14
|
+
Enabled: no
|
15
|
+
|
16
|
+
RSpec/InstanceVariable:
|
17
|
+
Enabled: no
|
18
|
+
|
19
|
+
RSpec/NestedGroups:
|
20
|
+
Enabled: no
|
21
|
+
|
22
|
+
RSpec/DescribeClass:
|
23
|
+
Enabled: no
|
24
|
+
|
25
|
+
RSpec/MultipleMemoizedHelpers:
|
26
|
+
Enabled: no
|
@@ -13,10 +13,10 @@ describe Freddy::ErrorResponse do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe '#message' do
|
16
|
-
subject { error.message }
|
16
|
+
subject(:message) { error.message }
|
17
17
|
|
18
18
|
it 'uses error type as a message' do
|
19
|
-
|
19
|
+
expect(message).to eq('SomeError')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -31,10 +31,10 @@ describe Freddy::ErrorResponse do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe '#message' do
|
34
|
-
subject { error.message }
|
34
|
+
subject(:message) { error.message }
|
35
35
|
|
36
36
|
it 'uses error type as a message' do
|
37
|
-
|
37
|
+
expect(message).to eq('SomeError: extra info')
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
@@ -49,10 +49,10 @@ describe Freddy::ErrorResponse do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
describe '#message' do
|
52
|
-
subject { error.message }
|
52
|
+
subject(:message) { error.message }
|
53
53
|
|
54
54
|
it 'uses default error message as a message' do
|
55
|
-
|
55
|
+
expect(message).to eq('Use #response to get the error response')
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
data/spec/freddy/freddy_spec.rb
CHANGED
@@ -49,6 +49,29 @@ describe Freddy do
|
|
49
49
|
expect(processed_after_timeout).to be(true)
|
50
50
|
end
|
51
51
|
end
|
52
|
+
|
53
|
+
context 'with compress' do
|
54
|
+
it 'compresses the payload' do
|
55
|
+
expect(Freddy::Encoding).to receive(:compress).with(anything, 'zlib').and_call_original
|
56
|
+
|
57
|
+
freddy.tap_into(destination) { |msg| @tapped_message = msg }
|
58
|
+
freddy.deliver(destination, payload, compress: 'zlib')
|
59
|
+
default_sleep
|
60
|
+
|
61
|
+
wait_for { @tapped_message }
|
62
|
+
expect(@tapped_message).to eq(payload)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'without compress' do
|
67
|
+
it 'does not compress the payload' do
|
68
|
+
freddy.tap_into(destination) { |msg| @tapped_message = msg }
|
69
|
+
deliver
|
70
|
+
|
71
|
+
wait_for { @tapped_message }
|
72
|
+
expect(@tapped_message).to eq(payload)
|
73
|
+
end
|
74
|
+
end
|
52
75
|
end
|
53
76
|
|
54
77
|
context 'when making a synchronized request' do
|
data/spec/freddy/payload_spec.rb
CHANGED
@@ -2,19 +2,28 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Freddy::Payload do
|
4
4
|
describe '#dump' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
5
|
+
context 'with a given Ruby engine' do
|
6
|
+
let(:ts) do
|
7
|
+
RUBY_ENGINE == 'jruby' ? '{"time":"2016-01-04T20:18:00Z"}' : '{"time":"2016-01-04T20:18:00.000000Z"}'
|
8
|
+
end
|
9
|
+
let(:ts_array) do
|
10
|
+
RUBY_ENGINE == 'jruby' ? '{"time":["2016-01-04T20:18:00Z"]}' : '{"time":["2016-01-04T20:18:00.000000Z"]}'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'serializes time objects as iso8601 format strings' do
|
14
|
+
expect(dump(time: Time.utc(2016, 1, 4, 20, 18)))
|
15
|
+
.to eq(ts)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'serializes time objects in an array as iso8601 format strings' do
|
19
|
+
expect(dump(time: [Time.utc(2016, 1, 4, 20, 18)]))
|
20
|
+
.to eq(ts_array)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'serializes time objects in a nested hash as iso8601 format strings' do
|
24
|
+
expect(dump(x: { time: Time.utc(2016, 1, 4, 20, 18) }))
|
25
|
+
.to eq("{\"x\":#{ts}}")
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
29
|
it 'serializes date objects as iso8601 format strings' do
|
@@ -33,17 +42,17 @@ describe Freddy::Payload do
|
|
33
42
|
end
|
34
43
|
|
35
44
|
it 'serializes datetime objects as iso8601 format strings' do
|
36
|
-
expect(dump(datetime: DateTime.new(2016, 1, 4, 20, 18)))
|
45
|
+
expect(dump(datetime: DateTime.new(2016, 1, 4, 20, 18)))
|
37
46
|
.to eq('{"datetime":"2016-01-04T20:18:00+00:00"}')
|
38
47
|
end
|
39
48
|
|
40
49
|
it 'serializes datetime objects in an array as iso8601 format strings' do
|
41
|
-
expect(dump(datetime: [DateTime.new(2016, 1, 4, 20, 18)]))
|
50
|
+
expect(dump(datetime: [DateTime.new(2016, 1, 4, 20, 18)]))
|
42
51
|
.to eq('{"datetime":["2016-01-04T20:18:00+00:00"]}')
|
43
52
|
end
|
44
53
|
|
45
54
|
it 'serializes datetime objects in a nested hash as iso8601 format strings' do
|
46
|
-
expect(dump(x: { datetime: DateTime.new(2016, 1, 4, 20, 18) }))
|
55
|
+
expect(dump(x: { datetime: DateTime.new(2016, 1, 4, 20, 18) }))
|
47
56
|
.to eq('{"x":{"datetime":"2016-01-04T20:18:00+00:00"}}')
|
48
57
|
end
|
49
58
|
|
@@ -10,21 +10,17 @@ describe 'Concurrency' do
|
|
10
10
|
|
11
11
|
it 'supports multiple requests in #respond_to' do
|
12
12
|
freddy1.respond_to 'Concurrency1' do |_payload, msg_handler|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
msg_handler.error(e.response)
|
19
|
-
end
|
13
|
+
freddy1.deliver_with_response 'Concurrency2', msg: 'noop'
|
14
|
+
result2 = freddy1.deliver_with_response 'Concurrency3', msg: 'noop'
|
15
|
+
msg_handler.success(result2)
|
16
|
+
rescue Freddy::InvalidRequestError => e
|
17
|
+
msg_handler.error(e.response)
|
20
18
|
end
|
21
19
|
|
22
20
|
freddy2.respond_to 'Concurrency2' do |_payload, msg_handler|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
msg_handler.error(e.response)
|
27
|
-
end
|
21
|
+
msg_handler.success(from: 'Concurrency2')
|
22
|
+
rescue Freddy::InvalidRequestError => e
|
23
|
+
msg_handler.error(e.response)
|
28
24
|
end
|
29
25
|
|
30
26
|
freddy3.respond_to 'Concurrency3' do |_payload, msg_handler|
|
@@ -10,6 +10,11 @@ describe 'Tapping into with group identifier' do
|
|
10
10
|
|
11
11
|
after { [deliverer, responder1, responder2].each(&:close) }
|
12
12
|
|
13
|
+
it 'raises an exception if option :durable is provided without group' do
|
14
|
+
expect { responder1.tap_into(destination, durable: true) }
|
15
|
+
.to raise_error(RuntimeError)
|
16
|
+
end
|
17
|
+
|
13
18
|
it 'receives a message once' do
|
14
19
|
msg_counter = Hamster::MutableSet[]
|
15
20
|
|
@@ -21,4 +26,33 @@ describe 'Tapping into with group identifier' do
|
|
21
26
|
default_sleep
|
22
27
|
expect(msg_counter.count).to eq(1)
|
23
28
|
end
|
29
|
+
|
30
|
+
it 'can requeue message on exception' do
|
31
|
+
counter = 0
|
32
|
+
|
33
|
+
responder1.tap_into(destination, group: arbitrary_id, on_exception: :requeue) do
|
34
|
+
counter += 1
|
35
|
+
raise 'error' if counter == 1
|
36
|
+
end
|
37
|
+
|
38
|
+
deliverer.deliver(destination, {})
|
39
|
+
|
40
|
+
wait_for { counter == 2 }
|
41
|
+
expect(counter).to eq(2)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'taps into multiple topics' do
|
45
|
+
destination2 = random_destination
|
46
|
+
counter = 0
|
47
|
+
|
48
|
+
responder1.tap_into([destination, destination2], group: arbitrary_id) do
|
49
|
+
counter += 1
|
50
|
+
end
|
51
|
+
|
52
|
+
deliverer.deliver(destination, {})
|
53
|
+
deliverer.deliver(destination2, {})
|
54
|
+
|
55
|
+
wait_for { counter == 2 }
|
56
|
+
expect(counter).to eq(2)
|
57
|
+
end
|
24
58
|
end
|
@@ -1,13 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'opentracing_test_tracer'
|
3
2
|
|
4
3
|
describe 'Tracing' do
|
5
|
-
let(:tracer) { OpenTracingTestTracer.build(logger: logger) }
|
6
4
|
let(:logger) { spy }
|
7
5
|
|
8
|
-
before { OpenTracing.global_tracer = tracer }
|
9
|
-
after { OpenTracing.global_tracer = nil }
|
10
|
-
|
11
6
|
context 'when receiving a traced request' do
|
12
7
|
let(:freddy) { Freddy.build(logger, config) }
|
13
8
|
let(:freddy2) { Freddy.build(logger, config) }
|
@@ -18,21 +13,13 @@ describe 'Tracing' do
|
|
18
13
|
before do
|
19
14
|
freddy.respond_to(destination) do |_payload, msg_handler|
|
20
15
|
msg_handler.success(
|
21
|
-
trace_initiator:
|
22
|
-
trace_id: active_span.context.trace_id,
|
23
|
-
parent_id: active_span.context.parent_id,
|
24
|
-
span_id: active_span.context.span_id
|
25
|
-
},
|
16
|
+
trace_initiator: current_span_attributes,
|
26
17
|
current_receiver: freddy.deliver_with_response(destination2, {})
|
27
18
|
)
|
28
19
|
end
|
29
20
|
|
30
21
|
freddy2.respond_to(destination2) do |_payload, msg_handler|
|
31
|
-
msg_handler.success(
|
32
|
-
trace_id: active_span.context.trace_id,
|
33
|
-
parent_id: active_span.context.parent_id,
|
34
|
-
span_id: active_span.context.span_id
|
35
|
-
)
|
22
|
+
msg_handler.success(current_span_attributes)
|
36
23
|
end
|
37
24
|
end
|
38
25
|
|
@@ -75,31 +62,19 @@ describe 'Tracing' do
|
|
75
62
|
before do
|
76
63
|
freddy.respond_to(destination) do |_payload, msg_handler|
|
77
64
|
msg_handler.success({
|
78
|
-
trace_initiator:
|
79
|
-
trace_id: active_span.context.trace_id,
|
80
|
-
parent_id: active_span.context.parent_id,
|
81
|
-
span_id: active_span.context.span_id
|
82
|
-
}
|
65
|
+
trace_initiator: current_span_attributes
|
83
66
|
}.merge(freddy.deliver_with_response(destination2, {})))
|
84
67
|
end
|
85
68
|
|
86
69
|
freddy2.respond_to(destination2) do |_payload, msg_handler|
|
87
70
|
msg_handler.success(
|
88
|
-
previous_receiver:
|
89
|
-
trace_id: active_span.context.trace_id,
|
90
|
-
parent_id: active_span.context.parent_id,
|
91
|
-
span_id: active_span.context.span_id
|
92
|
-
},
|
71
|
+
previous_receiver: current_span_attributes,
|
93
72
|
current_receiver: freddy2.deliver_with_response(destination3, {})
|
94
73
|
)
|
95
74
|
end
|
96
75
|
|
97
76
|
freddy3.respond_to(destination3) do |_payload, msg_handler|
|
98
|
-
msg_handler.success(
|
99
|
-
trace_id: active_span.context.trace_id,
|
100
|
-
parent_id: active_span.context.parent_id,
|
101
|
-
span_id: active_span.context.span_id
|
102
|
-
)
|
77
|
+
msg_handler.success(current_span_attributes)
|
103
78
|
end
|
104
79
|
end
|
105
80
|
|
@@ -131,7 +106,15 @@ describe 'Tracing' do
|
|
131
106
|
end
|
132
107
|
end
|
133
108
|
|
134
|
-
def
|
135
|
-
|
109
|
+
def current_span_attributes
|
110
|
+
{
|
111
|
+
trace_id: current_span.context.trace_id,
|
112
|
+
parent_id: current_span.parent_span_id,
|
113
|
+
span_id: current_span.context.span_id
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def current_span
|
118
|
+
OpenTelemetry::Trace.current_span
|
136
119
|
end
|
137
120
|
end
|