liebre 0.1.21 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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