liebre 0.1.21 → 0.2.1

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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -0
  3. data/Gemfile.lock +9 -7
  4. data/{LICENSE → LICENSE.txt} +1 -1
  5. data/README.md +492 -195
  6. data/Rakefile +2 -0
  7. data/lib/liebre.rb +27 -16
  8. data/lib/liebre/actor.rb +11 -0
  9. data/lib/liebre/actor/consumer.rb +80 -0
  10. data/lib/liebre/actor/consumer/callback.rb +34 -0
  11. data/lib/liebre/actor/consumer/core.rb +80 -0
  12. data/lib/liebre/actor/consumer/reporter.rb +84 -0
  13. data/lib/liebre/actor/consumer/resources.rb +47 -0
  14. data/lib/liebre/actor/consumer/resources/config.rb +65 -0
  15. data/lib/liebre/actor/context.rb +40 -0
  16. data/lib/liebre/actor/context/declare.rb +44 -0
  17. data/lib/liebre/actor/context/handler.rb +44 -0
  18. data/lib/liebre/actor/publisher.rb +58 -0
  19. data/lib/liebre/actor/publisher/core.rb +42 -0
  20. data/lib/liebre/actor/publisher/reporter.rb +55 -0
  21. data/lib/liebre/actor/publisher/resources.rb +33 -0
  22. data/lib/liebre/actor/rpc/client.rb +88 -0
  23. data/lib/liebre/actor/rpc/client/core.rb +75 -0
  24. data/lib/liebre/actor/rpc/client/pending.rb +65 -0
  25. data/lib/liebre/actor/rpc/client/reporter.rb +71 -0
  26. data/lib/liebre/actor/rpc/client/resources.rb +62 -0
  27. data/lib/liebre/actor/rpc/client/task.rb +33 -0
  28. data/lib/liebre/actor/rpc/server.rb +74 -0
  29. data/lib/liebre/actor/rpc/server/callback.rb +28 -0
  30. data/lib/liebre/actor/rpc/server/core.rb +75 -0
  31. data/lib/liebre/actor/rpc/server/reporter.rb +72 -0
  32. data/lib/liebre/actor/rpc/server/resources.rb +53 -0
  33. data/lib/liebre/adapter.rb +8 -0
  34. data/lib/liebre/adapter/bunny.rb +23 -0
  35. data/lib/liebre/adapter/bunny/chan.rb +38 -0
  36. data/lib/liebre/adapter/bunny/conn.rb +32 -0
  37. data/lib/liebre/adapter/bunny/exchange.rb +20 -0
  38. data/lib/liebre/adapter/bunny/queue.rb +59 -0
  39. data/lib/liebre/adapter/interface.rb +26 -0
  40. data/lib/liebre/adapter/interface/chan.rb +29 -0
  41. data/lib/liebre/adapter/interface/conn.rb +21 -0
  42. data/lib/liebre/adapter/interface/exchange.rb +13 -0
  43. data/lib/liebre/adapter/interface/queue.rb +37 -0
  44. data/lib/liebre/bridge.rb +72 -0
  45. data/lib/liebre/bridge/channel_builder.rb +36 -0
  46. data/lib/liebre/config.rb +8 -38
  47. data/lib/liebre/engine.rb +61 -0
  48. data/lib/liebre/engine/builder.rb +48 -0
  49. data/lib/liebre/engine/repository.rb +56 -0
  50. data/lib/liebre/engine/state.rb +49 -0
  51. data/lib/liebre/runner.rb +15 -47
  52. data/lib/liebre/version.rb +1 -1
  53. data/liebre.gemspec +9 -7
  54. data/spec/integration/publish_and_consume_spec.rb +71 -0
  55. data/spec/integration/rpc_communication_spec.rb +81 -0
  56. data/spec/integration/start_twice_spec.rb +63 -0
  57. data/spec/liebre/actor/consumer_spec.rb +169 -0
  58. data/spec/liebre/actor/context/declare_spec.rb +69 -0
  59. data/spec/liebre/actor/context/handler_spec.rb +65 -0
  60. data/spec/liebre/actor/publisher_spec.rb +58 -0
  61. data/spec/liebre/actor/rpc/client_spec.rb +126 -0
  62. data/spec/liebre/actor/rpc/server_spec.rb +141 -0
  63. data/spec/liebre/adapter/bunny_spec.rb +66 -0
  64. data/spec/liebre/bridge_spec.rb +54 -0
  65. data/spec/liebre/engine/builder_spec.rb +42 -0
  66. data/spec/liebre/engine_spec.rb +90 -0
  67. data/spec/liebre/version_spec.rb +10 -0
  68. data/spec/spec_helper.rb +2 -9
  69. metadata +97 -58
  70. data/lib/liebre/common.rb +0 -7
  71. data/lib/liebre/common/utils.rb +0 -37
  72. data/lib/liebre/connection_manager.rb +0 -85
  73. data/lib/liebre/publisher.rb +0 -113
  74. data/lib/liebre/runner/consumers.rb +0 -46
  75. data/lib/liebre/runner/starter.rb +0 -44
  76. data/lib/liebre/runner/starter/consumer.rb +0 -129
  77. data/lib/liebre/runner/starter/consumer/handler.rb +0 -35
  78. data/lib/liebre/runner/starter/resources.rb +0 -45
  79. data/lib/liebre/runner/starter/resources/queue_builder.rb +0 -63
  80. data/lib/liebre/runner/starter/rpc.rb +0 -59
  81. data/lib/liebre/tasks.rb +0 -12
  82. data/spec/config/liebre.yml +0 -48
  83. data/spec/config/rabbitmq.yml +0 -35
  84. data/spec/integration_spec.rb +0 -76
  85. data/spec/liebre/config_spec.rb +0 -63
  86. data/spec/liebre/connection_manager_spec.rb +0 -44
  87. data/spec/liebre/publisher_spec.rb +0 -92
  88. data/spec/liebre/runner/consumers_spec.rb +0 -59
  89. data/spec/liebre/runner/starter/consumer_spec.rb +0 -145
  90. data/spec/liebre/runner/starter/resources/queue_builder_spec.rb +0 -69
  91. data/spec/liebre/runner/starter/resources_spec.rb +0 -38
  92. data/spec/liebre/runner/starter/rpc_spec.rb +0 -100
  93. data/spec/liebre/runner/starter_spec.rb +0 -70
  94. data/spec/liebre/runner_spec.rb +0 -54
@@ -1,113 +0,0 @@
1
- module Liebre
2
- class Publisher
3
-
4
- def initialize publisher_name
5
- @publisher_name = publisher_name
6
- end
7
-
8
- def enqueue message, options = {}
9
- with_connection do
10
- exchange = exchange_for default_channel
11
- logger.debug "Liebre# Publishing '#{message}' with '#{options}' to exchange: #{exchange.name}"
12
- exchange.publish message, options
13
- end
14
- end
15
-
16
- def enqueue_and_wait message, options = {}
17
- result = nil
18
- with_rpc_channel do |channel|
19
- correlation_id = options[:correlation_id] ||= generate_uuid
20
- reply_queue = reply_queue channel, correlation_id
21
- options[:reply_to] = reply_queue.name
22
- reply_queue.subscribe(:block => false) do |delivery_info, meta, payload|
23
- if meta[:correlation_id] == correlation_id
24
- result = payload
25
- logger.debug "Liebre# Received response '#{result}'"
26
- channel.consumers[delivery_info.consumer_tag].cancel
27
- end
28
- end
29
- exchange = exchange_for channel
30
- logger.debug "Liebre# Publishing '#{message}' with '#{options}' to exchange: #{exchange.name}"
31
- exchange.publish message, options
32
- begin
33
- Timeout.timeout(Liebre.config.rpc_request_timeout) do
34
- sleep 0.01 while result.nil?
35
- end
36
- rescue Timeout::Error
37
- #do nothing
38
- end
39
- end
40
- result
41
- end
42
-
43
- alias_method :rpc, :enqueue_and_wait
44
-
45
- private
46
-
47
- def with_connection
48
- connection_manager.ensure_started
49
- begin
50
- yield
51
- rescue Bunny::Exception => e
52
- logger.warn("#{self.class.name}: #{e.class} found restarting connection - #{e.message}")
53
- connection_manager.restart
54
- retry
55
- end
56
- end
57
-
58
- def with_rpc_channel
59
- with_connection do
60
- Common::Utils.mutex_sync do
61
- channel = connection_manager.get(connection_name).create_channel
62
- channel.prefetch 1
63
- yield(channel)
64
- channel.close
65
- end
66
- end
67
- end
68
-
69
- def default_channel
70
- @default_channel ||= connection_manager.channel_for(connection_name)
71
- end
72
-
73
- def reply_queue channel, correlation_id
74
- queue_name = "#{publisher_name}_callback_#{correlation_id}"
75
- channel.queue queue_name, :exclusive => true, :auto_delete => true
76
- end
77
-
78
- def exchange_for channel
79
- Liebre::Common::Utils.create_exchange channel, exchange_config
80
- end
81
-
82
- def publishers
83
- Liebre.config.publishers
84
- end
85
-
86
- def exchange_config
87
- config.fetch("exchange")
88
- end
89
-
90
- def config
91
- publishers.fetch publisher_name
92
- end
93
-
94
- def connection_name
95
- config.fetch('connection_name', 'default').to_sym
96
- end
97
-
98
- def connection_manager
99
- @connection_manager ||= ConnectionManager.instance
100
- end
101
-
102
- def generate_uuid
103
- SecureRandom.uuid
104
- end
105
-
106
- def logger
107
- Liebre::Config.logger
108
- end
109
-
110
- attr_reader :publisher_name
111
-
112
- end
113
- end
@@ -1,46 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Consumers
4
-
5
- def initialize connection_manager
6
- @connection_manager = connection_manager
7
- @threads = []
8
- end
9
-
10
- def consumer_names
11
- consumers.keys
12
- end
13
-
14
- def start_all
15
- consumer_names.each do |name|
16
- start(name)
17
- end
18
- end
19
-
20
- def stop
21
- threads.each do |starter|
22
- starter.stop
23
- end
24
- end
25
-
26
- def start name
27
- params = consumers.fetch(name)
28
- num_threads = params.fetch("num_threads", 1)
29
- num_threads.times do
30
- starter = Starter.new(connection_manager, params)
31
- starter.start
32
- threads << starter
33
- end
34
- end
35
-
36
- private
37
-
38
- def consumers
39
- Liebre.config.consumers
40
- end
41
-
42
- attr_reader :connection_manager, :threads
43
-
44
- end
45
- end
46
- end
@@ -1,44 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Starter
4
-
5
- autoload :Consumer, 'liebre/runner/starter/consumer'
6
- autoload :Resources, 'liebre/runner/starter/resources'
7
- autoload :RPC, 'liebre/runner/starter/rpc'
8
-
9
- def initialize connection_manager, config
10
- @connection_manager = connection_manager
11
- @config = config
12
- end
13
-
14
- def start
15
- @consumer = consumer_class.new(connection, config).start
16
- end
17
-
18
- def stop
19
- @consumer.cancel
20
- end
21
-
22
- private
23
-
24
- def consumer_class
25
- is_rpc? ? RPC : Consumer
26
- end
27
-
28
- def is_rpc?
29
- config.fetch("rpc", false)
30
- end
31
-
32
- def connection
33
- connection_manager.get connection_name
34
- end
35
-
36
- def connection_name
37
- config.fetch('connection_name', 'default').to_sym
38
- end
39
-
40
- attr_reader :connection_manager, :config
41
-
42
- end
43
- end
44
- end
@@ -1,129 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Starter
4
- class Consumer
5
-
6
- autoload :Handler, "liebre/runner/starter/consumer/handler"
7
-
8
- def initialize connection, config
9
- @connection = connection
10
- @config = config
11
- end
12
-
13
- def start
14
- initialize_error_queue
15
- initialize_queue
16
- end
17
-
18
- def stop
19
- if @consumer
20
- @consumer.cancel
21
- channel.close
22
- end
23
- end
24
-
25
- protected
26
-
27
- def call_consumer payload, meta
28
- consumer = klass.new(payload, meta)
29
- consumer.call
30
- end
31
-
32
- private
33
-
34
- def initialize_queue
35
- @consumer = queue.subscribe(:manual_ack => true) do |info, meta, payload|
36
- response = :reject
37
- debug_string = ""
38
- elapsed_time = nil
39
- begin
40
- debug_string = "Liebre# Received message for #{klass.name}(#{queue.name}): #{payload} - #{meta}"
41
- start_at = Time.now
42
- response = call_consumer(payload, meta)
43
- elapsed_time = (Time.now - start_at).to_f * 1000
44
- rescue StandardError => e
45
- response = :error
46
- logger.error error_string(e, payload, meta)
47
- rescue Exception => e
48
- response = :error
49
- logger.error error_string(e, payload, meta)
50
- handler.respond response, info
51
- raise e
52
- ensure
53
- debug_string += "\nLiebre# Responding with #{response}"
54
- log_result debug_string, elapsed_time
55
- handler.respond response, info
56
- end
57
- end
58
- end
59
-
60
- def log_result debug_string, elapsed_time
61
- time_string = "\nLiebre# Elapsed time #{elapsed_time} ms"
62
- if logger.debug?
63
- logger.debug debug_string + time_string
64
- else
65
- logger.info "Liebre# Received message for #{klass.name}(#{queue.name})" + time_string
66
- end
67
- end
68
-
69
- def error_string error, payload, meta
70
- "Liebre# Error while processing #{klass.name}(#{queue.name}): #{payload} - #{meta}" +
71
- "\n" + error.inspect + "\n" + error.backtrace.join("\n")
72
- end
73
-
74
- def initialize_error_queue
75
- Resources.new(connection, error_config).queue
76
- end
77
-
78
- def klass
79
- @klass ||= Kernel.const_get config.fetch("class_name")
80
- end
81
-
82
- def handler
83
- @handler ||= Handler.new(channel)
84
- end
85
-
86
- def channel
87
- resources.channel
88
- end
89
-
90
- def exchange
91
- resources.exchange
92
- end
93
-
94
- def queue
95
- resources.queue
96
- end
97
-
98
- def resources
99
- @resources ||= Resources.new(connection, parse_config)
100
- end
101
-
102
- def parse_config
103
- result = clone_hash config
104
- result['queue']['opts']['arguments'] ||= {}
105
- result['queue']['opts']['arguments']['x-dead-letter-exchange'] = result['exchange']['name'] + "-error"
106
- result
107
- end
108
-
109
- def error_config
110
- result = clone_hash config
111
- result['exchange']['name'] += "-error"
112
- result['queue']['name'] += "-error"
113
- result
114
- end
115
-
116
- def logger
117
- Liebre::Config.logger
118
- end
119
-
120
- def clone_hash hash
121
- Marshal.load(Marshal.dump(hash))
122
- end
123
-
124
- attr_reader :connection, :config
125
-
126
- end
127
- end
128
- end
129
- end
@@ -1,35 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Starter
4
- class Consumer
5
- class Handler
6
-
7
- def initialize channel
8
- @channel = channel
9
- end
10
-
11
- def respond action, meta
12
- send(action, meta.delivery_tag)
13
- end
14
-
15
- private
16
-
17
- def ack delivery_tag
18
- channel.acknowledge delivery_tag
19
- end
20
-
21
- def reject delivery_tag
22
- channel.reject delivery_tag, true
23
- end
24
-
25
- def error delivery_tag
26
- channel.reject delivery_tag, false
27
- end
28
-
29
- attr_reader :channel
30
-
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,45 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Starter
4
- class Resources
5
- autoload :QueueBuilder, "liebre/runner/starter/resources/queue_builder"
6
-
7
- def initialize connection, config
8
- @connection = connection
9
- @config = config
10
- end
11
-
12
- def exchange
13
- @exchange ||= queue_builder.exchange
14
- end
15
-
16
- def queue
17
- @queue ||= queue_builder.queue
18
- end
19
-
20
- def channel
21
- @channel ||= connection.create_channel(nil, pool_size).tap do |channel|
22
- channel.prefetch(prefetch_count)
23
- end
24
- end
25
-
26
- private
27
-
28
- def queue_builder
29
- @queue_bilder ||= QueueBuilder.new(channel, config)
30
- end
31
-
32
- def prefetch_count
33
- config.fetch("prefetch_count", 10)
34
- end
35
-
36
- def pool_size
37
- config.fetch("pool_size", 1)
38
- end
39
-
40
- attr_reader :connection, :config
41
-
42
- end
43
- end
44
- end
45
- end
@@ -1,63 +0,0 @@
1
- module Liebre
2
- class Runner
3
- class Starter
4
- class Resources
5
- class QueueBuilder
6
-
7
- def initialize channel, config
8
- @channel = channel
9
- @config = config
10
- end
11
-
12
- def queue
13
- q = channel.queue(queue_name, queue_opts)
14
- if routing_keys.any?
15
- routing_keys.each do |key|
16
- q.bind(exchange, bind_opts.merge(:routing_key => key))
17
- end
18
- else
19
- q.bind(exchange, bind_opts)
20
- end
21
- q
22
- end
23
-
24
- def exchange
25
- Liebre::Common::Utils.create_exchange channel, exchange_config
26
- end
27
-
28
- private
29
-
30
- def queue_name
31
- queue_config.fetch("name")
32
- end
33
-
34
- def queue_opts
35
- Liebre::Common::Utils.symbolize_keys queue_config.fetch("opts", {})
36
- end
37
-
38
- def exchange_config
39
- config.fetch("exchange")
40
- end
41
-
42
- def queue_config
43
- config.fetch("queue")
44
- end
45
-
46
- def routing_keys
47
- @routing_keys ||= begin
48
- bind_opts[:routing_key] = [*bind_opts[:routing_key]]
49
- bind_opts.delete :routing_key
50
- end
51
- end
52
-
53
- def bind_opts
54
- @bind_opts ||= Liebre::Common::Utils.symbolize_keys config.fetch("bind", {})
55
- end
56
-
57
- attr_reader :channel, :config
58
-
59
- end
60
- end
61
- end
62
- end
63
- end