freddy 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|