freddy 1.4.1 → 1.4.2
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 +4 -4
- data/.rubocop.yml +49 -0
- data/.travis.yml +1 -1
- data/Gemfile +4 -2
- data/Rakefile +6 -4
- data/freddy.gemspec +21 -21
- data/lib/freddy.rb +7 -8
- data/lib/freddy/adapters.rb +2 -0
- data/lib/freddy/adapters/bunny_adapter.rb +7 -7
- data/lib/freddy/adapters/march_hare_adapter.rb +6 -4
- data/lib/freddy/consumers.rb +2 -0
- data/lib/freddy/consumers/respond_to_consumer.rb +14 -17
- data/lib/freddy/consumers/response_consumer.rb +4 -2
- data/lib/freddy/consumers/tap_into_consumer.rb +11 -14
- data/lib/freddy/delivery.rb +2 -0
- data/lib/freddy/error_response.rb +2 -0
- data/lib/freddy/invalid_request_error.rb +2 -0
- data/lib/freddy/message_handler.rb +3 -1
- data/lib/freddy/message_handler_adapaters.rb +2 -0
- data/lib/freddy/payload.rb +5 -3
- data/lib/freddy/producers.rb +2 -0
- data/lib/freddy/producers/reply_producer.rb +6 -6
- data/lib/freddy/producers/send_and_forget_producer.rb +8 -8
- data/lib/freddy/producers/send_and_wait_response_producer.rb +39 -31
- data/lib/freddy/request_manager.rb +7 -4
- data/lib/freddy/responder_handler.rb +2 -0
- data/lib/freddy/sync_response_container.rb +4 -4
- data/lib/freddy/timeout_error.rb +2 -0
- data/lib/freddy/trace_carrier.rb +4 -2
- data/spec/freddy/consumers/respond_to_consumer_spec.rb +1 -1
- data/spec/freddy/error_response_spec.rb +9 -9
- data/spec/freddy/freddy_spec.rb +38 -38
- data/spec/freddy/message_handler_spec.rb +2 -2
- data/spec/freddy/payload_spec.rb +5 -5
- data/spec/freddy/responder_handler_spec.rb +1 -1
- data/spec/freddy/sync_response_container_spec.rb +8 -8
- data/spec/freddy/trace_carrier_spec.rb +5 -5
- data/spec/integration/concurrency_spec.rb +9 -9
- data/spec/integration/reply_spec.rb +4 -4
- data/spec/integration/tap_into_with_group_spec.rb +2 -2
- data/spec/integration/tracing_spec.rb +19 -19
- data/spec/spec_helper.rb +6 -6
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afcbdc550b2c021be177ce71767e874d88f62266
|
4
|
+
data.tar.gz: b385e9fc1aa1f12d01e42db629c8e669f56c08f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b850d5ce01a28ee9f1ed0762ac61ca293a36270d754f2065d5cfcfc4f8ee2f666584a0e82d60ebafc1c734692835bd39e38319b63fdbd2509862a4707db5f13d
|
7
|
+
data.tar.gz: 47cf5182652976f7966226142845fd3c64077046d5fbeb5b5627c20a4e2a69936b33f26731344f74273a32b778f01420299b5a80ca9147e802a897e72cb8081a
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
3
|
+
Metrics/AbcSize:
|
4
|
+
Enabled: no
|
5
|
+
|
6
|
+
Metrics/BlockLength:
|
7
|
+
Enabled: no
|
8
|
+
|
9
|
+
Metrics/LineLength:
|
10
|
+
Max: 120
|
11
|
+
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Enabled: no
|
14
|
+
|
15
|
+
Style/Documentation:
|
16
|
+
Enabled: no
|
17
|
+
|
18
|
+
RSpec/ExampleLength:
|
19
|
+
Enabled: no
|
20
|
+
|
21
|
+
RSpec/MultipleExpectations:
|
22
|
+
Enabled: no
|
23
|
+
|
24
|
+
RSpec/MessageSpies:
|
25
|
+
Enabled: no
|
26
|
+
|
27
|
+
RSpec/VerifiedDoubles:
|
28
|
+
Enabled: no
|
29
|
+
|
30
|
+
RSpec/InstanceVariable:
|
31
|
+
Enabled: no
|
32
|
+
|
33
|
+
RSpec/NestedGroups:
|
34
|
+
Enabled: no
|
35
|
+
|
36
|
+
RSpec/DescribeClass:
|
37
|
+
Enabled: no
|
38
|
+
|
39
|
+
Style/FrozenStringLiteralComment:
|
40
|
+
Enabled: yes
|
41
|
+
EnforcedStyle: always
|
42
|
+
Include:
|
43
|
+
- 'lib/**/*'
|
44
|
+
|
45
|
+
Performance/TimesMap:
|
46
|
+
Enabled: no
|
47
|
+
|
48
|
+
Naming/FileName:
|
49
|
+
Enabled: no
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'rspec'
|
4
|
-
gem 'pry'
|
5
3
|
gem 'codeclimate-test-reporter'
|
6
4
|
gem 'hamster', '~> 3.0'
|
7
5
|
gem 'opentracing_test_tracer', '~> 0.1'
|
6
|
+
gem 'pry'
|
7
|
+
gem 'rspec'
|
8
|
+
gem 'rubocop', '~> 0.54.0'
|
9
|
+
gem 'rubocop-rspec', '~> 1.24.0'
|
8
10
|
|
9
11
|
gemspec
|
data/Rakefile
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
2
4
|
|
3
|
-
require "rspec/core/rake_task"
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
RuboCop::RakeTask.new(:rubocop)
|
8
|
+
|
9
|
+
task default: %i[rubocop spec]
|
data/freddy.gemspec
CHANGED
@@ -1,36 +1,36 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('
|
1
|
+
|
2
|
+
lib = File.expand_path('lib', __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
if RUBY_PLATFORM == 'java'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
spec.version = '1.4.
|
12
|
-
spec.authors = [
|
13
|
-
spec.email = [
|
14
|
-
spec.description =
|
15
|
-
spec.summary =
|
16
|
-
spec.license =
|
6
|
+
spec.name = if RUBY_PLATFORM == 'java'
|
7
|
+
'freddy-jruby'
|
8
|
+
else
|
9
|
+
'freddy'
|
10
|
+
end
|
11
|
+
spec.version = '1.4.2'
|
12
|
+
spec.authors = ['Salemove TechMovers']
|
13
|
+
spec.email = ['techmovers@salemove.com']
|
14
|
+
spec.description = 'Messaging API'
|
15
|
+
spec.summary = 'API for inter-application messaging supporting acknowledgements and request-response'
|
16
|
+
spec.license = 'Private'
|
17
17
|
|
18
|
-
spec.files = `git ls-files`.split(
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
19
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
-
spec.require_paths = [
|
21
|
+
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
25
|
|
26
26
|
if RUBY_PLATFORM == 'java'
|
27
27
|
spec.add_dependency 'march_hare', '~> 2.12.0'
|
28
28
|
spec.add_dependency 'symbolizer'
|
29
29
|
else
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_dependency
|
30
|
+
spec.add_dependency 'bunny', '~> 2.11'
|
31
|
+
spec.add_dependency 'oj', '~> 2.13'
|
32
32
|
end
|
33
33
|
|
34
|
-
spec.add_dependency
|
35
|
-
spec.add_dependency
|
34
|
+
spec.add_dependency 'opentracing', '~> 0.4'
|
35
|
+
spec.add_dependency 'thread', '~> 0.1'
|
36
36
|
end
|
data/lib/freddy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'thread/pool'
|
3
5
|
require 'securerandom'
|
@@ -6,7 +8,7 @@ require 'opentracing'
|
|
6
8
|
Dir[File.dirname(__FILE__) + '/freddy/*.rb'].each(&method(:require))
|
7
9
|
|
8
10
|
class Freddy
|
9
|
-
FREDDY_TOPIC_EXCHANGE_NAME = 'freddy-topic'
|
11
|
+
FREDDY_TOPIC_EXCHANGE_NAME = 'freddy-topic'
|
10
12
|
DEFAULT_MAX_CONCURRENCY = 4
|
11
13
|
|
12
14
|
# Creates a new freddy instance
|
@@ -39,9 +41,7 @@ class Freddy
|
|
39
41
|
|
40
42
|
# @deprecated Use OpenTracing ScopeManager instead
|
41
43
|
def self.trace=(trace)
|
42
|
-
if OpenTracing.active_span != trace
|
43
|
-
OpenTracing.scope_manager.activate(trace)
|
44
|
-
end
|
44
|
+
OpenTracing.scope_manager.activate(trace) if OpenTracing.active_span != trace
|
45
45
|
end
|
46
46
|
|
47
47
|
def initialize(connection, logger, max_concurrency)
|
@@ -156,7 +156,7 @@ class Freddy
|
|
156
156
|
def deliver(destination, payload, options = {})
|
157
157
|
timeout = options.fetch(:timeout, 0)
|
158
158
|
opts = {}
|
159
|
-
opts[:expiration] = (timeout * 1000).to_i if timeout
|
159
|
+
opts[:expiration] = (timeout * 1000).to_i if timeout.positive?
|
160
160
|
|
161
161
|
@send_and_forget_producer.produce(destination, payload, opts)
|
162
162
|
end
|
@@ -194,9 +194,8 @@ class Freddy
|
|
194
194
|
timeout = options.fetch(:timeout, 3)
|
195
195
|
delete_on_timeout = options.fetch(:delete_on_timeout, true)
|
196
196
|
|
197
|
-
@send_and_wait_response_producer.produce destination, payload,
|
198
|
-
|
199
|
-
}
|
197
|
+
@send_and_wait_response_producer.produce destination, payload,
|
198
|
+
timeout_in_seconds: timeout, delete_on_timeout: delete_on_timeout
|
200
199
|
end
|
201
200
|
|
202
201
|
# Closes the connection with message queue
|
data/lib/freddy/adapters.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bunny'
|
2
4
|
|
3
5
|
class Freddy
|
@@ -38,23 +40,21 @@ class Freddy
|
|
38
40
|
Queue.new(@channel.queue(*args))
|
39
41
|
end
|
40
42
|
|
41
|
-
def on_no_route
|
42
|
-
default_exchange.on_return do |return_info, properties,
|
43
|
-
if return_info[:reply_code] == NO_ROUTE
|
44
|
-
block.call(properties[:correlation_id])
|
45
|
-
end
|
43
|
+
def on_no_route
|
44
|
+
default_exchange.on_return do |return_info, properties, _content|
|
45
|
+
yield(properties[:correlation_id]) if return_info[:reply_code] == NO_ROUTE
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
class Queue < Shared::Queue
|
51
|
-
def subscribe(manual_ack: false
|
51
|
+
def subscribe(manual_ack: false)
|
52
52
|
@queue.subscribe(manual_ack: manual_ack) do |info, properties, payload|
|
53
53
|
parsed_payload = Payload.parse(payload)
|
54
54
|
delivery = Delivery.new(
|
55
55
|
parsed_payload, properties, info.routing_key, info.delivery_tag
|
56
56
|
)
|
57
|
-
|
57
|
+
yield(delivery)
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'march_hare'
|
2
4
|
|
3
5
|
class Freddy
|
@@ -37,23 +39,23 @@ class Freddy
|
|
37
39
|
Queue.new(@channel.queue(*args))
|
38
40
|
end
|
39
41
|
|
40
|
-
def on_no_route
|
42
|
+
def on_no_route
|
41
43
|
@channel.on_return do |reply_code, _, exchange_name, _, properties|
|
42
44
|
if exchange_name != Freddy::FREDDY_TOPIC_EXCHANGE_NAME && reply_code == NO_ROUTE
|
43
|
-
|
45
|
+
yield(properties.correlation_id)
|
44
46
|
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
49
51
|
class Queue < Shared::Queue
|
50
|
-
def subscribe(manual_ack: false
|
52
|
+
def subscribe(manual_ack: false)
|
51
53
|
@queue.subscribe(manual_ack: manual_ack) do |meta, payload|
|
52
54
|
parsed_payload = Payload.parse(payload)
|
53
55
|
delivery = Delivery.new(
|
54
56
|
parsed_payload, meta, meta.routing_key, meta.delivery_tag
|
55
57
|
)
|
56
|
-
|
58
|
+
yield(delivery)
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
data/lib/freddy/consumers.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Freddy
|
2
4
|
module Consumers
|
3
5
|
class RespondToConsumer
|
@@ -12,12 +14,12 @@ class Freddy
|
|
12
14
|
@handler_adapter_factory = handler_adapter_factory
|
13
15
|
end
|
14
16
|
|
15
|
-
def consume
|
17
|
+
def consume
|
16
18
|
consumer = consume_from_destination do |delivery|
|
17
19
|
adapter = @handler_adapter_factory.for(delivery)
|
18
20
|
|
19
21
|
msg_handler = MessageHandler.new(adapter, delivery)
|
20
|
-
|
22
|
+
yield(delivery.payload, msg_handler)
|
21
23
|
end
|
22
24
|
|
23
25
|
ResponderHandler.new(consumer, @consume_thread_pool)
|
@@ -31,24 +33,19 @@ class Freddy
|
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
|
-
def process_message(delivery
|
36
|
+
def process_message(delivery)
|
35
37
|
@consume_thread_pool.process do
|
36
38
|
begin
|
37
39
|
scope = delivery.build_trace("freddy:respond:#{@destination}",
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
payload: delivery.payload,
|
48
|
-
correlation_id: delivery.correlation_id
|
49
|
-
)
|
50
|
-
|
51
|
-
block.call(delivery)
|
40
|
+
tags: {
|
41
|
+
'peer.address' => "#{@destination}:#{delivery.payload[:type]}",
|
42
|
+
'component' => 'freddy',
|
43
|
+
'span.kind' => 'server', # RPC
|
44
|
+
'message_bus.destination' => @destination,
|
45
|
+
'message_bus.correlation_id' => delivery.correlation_id
|
46
|
+
})
|
47
|
+
|
48
|
+
yield(delivery)
|
52
49
|
ensure
|
53
50
|
@channel.acknowledge(delivery.tag, false)
|
54
51
|
scope.close
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Freddy
|
2
4
|
module Consumers
|
3
5
|
class ResponseConsumer
|
@@ -5,10 +7,10 @@ class Freddy
|
|
5
7
|
@logger = logger
|
6
8
|
end
|
7
9
|
|
8
|
-
def consume(
|
10
|
+
def consume(_channel, queue)
|
9
11
|
@logger.debug "Consuming messages on #{queue.name}"
|
10
12
|
queue.subscribe do |delivery|
|
11
|
-
|
13
|
+
yield(delivery)
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Freddy
|
2
4
|
module Consumers
|
3
5
|
class TapIntoConsumer
|
@@ -39,24 +41,19 @@ class Freddy
|
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
42
|
-
def process_message(
|
44
|
+
def process_message(_queue, delivery)
|
43
45
|
@consume_thread_pool.process do
|
44
46
|
begin
|
45
47
|
scope = delivery.build_trace("freddy:observe:#{@pattern}",
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
scope.span.log_kv(
|
54
|
-
event: 'Received message through tap_into',
|
55
|
-
payload: delivery.payload,
|
56
|
-
correlation_id: delivery.correlation_id
|
57
|
-
)
|
48
|
+
tags: {
|
49
|
+
'message_bus.destination' => @pattern,
|
50
|
+
'message_bus.correlation_id' => delivery.correlation_id,
|
51
|
+
'component' => 'freddy',
|
52
|
+
'span.kind' => 'consumer' # Message Bus
|
53
|
+
},
|
54
|
+
force_follows_from: true)
|
58
55
|
|
59
|
-
|
56
|
+
yield delivery.payload, delivery.routing_key
|
60
57
|
ensure
|
61
58
|
@channel.acknowledge(delivery.tag, false)
|
62
59
|
scope.close
|
data/lib/freddy/delivery.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Freddy
|
2
4
|
class MessageHandler
|
3
5
|
def initialize(adapter, delivery)
|
@@ -9,7 +11,7 @@ class Freddy
|
|
9
11
|
@adapter.success(@delivery, response)
|
10
12
|
end
|
11
13
|
|
12
|
-
def error(response = {error: "Couldn't process message"})
|
14
|
+
def error(response = { error: "Couldn't process message" })
|
13
15
|
@adapter.error(@delivery, response)
|
14
16
|
end
|
15
17
|
end
|
data/lib/freddy/payload.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require 'oj'
|
3
5
|
rescue LoadError
|
@@ -18,12 +20,12 @@ class Freddy
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def self.json_handler
|
21
|
-
@
|
23
|
+
@json_handler ||= defined?(Oj) ? OjAdapter : JsonAdapter
|
22
24
|
end
|
23
25
|
|
24
26
|
class OjAdapter
|
25
|
-
PARSE_OPTIONS = { symbol_keys: true }
|
26
|
-
DUMP_OPTIONS = { mode: :compat, time_format: :xmlschema, second_precision: 6 }
|
27
|
+
PARSE_OPTIONS = { symbol_keys: true }.freeze
|
28
|
+
DUMP_OPTIONS = { mode: :compat, time_format: :xmlschema, second_precision: 6 }.freeze
|
27
29
|
|
28
30
|
def self.parse(payload)
|
29
31
|
Oj.strict_load(payload, PARSE_OPTIONS)
|