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
@@ -0,0 +1,65 @@
1
+ require 'concurrent'
2
+ require 'securerandom'
3
+
4
+ module Liebre
5
+ module Actor
6
+ module RPC
7
+ class Client
8
+ class Pending
9
+
10
+ Request = Struct.new(:ivar, :expiration_time)
11
+
12
+ def initialize
13
+ @pending = {}
14
+ end
15
+
16
+ def add timeout
17
+ new_ivar.tap do |ivar|
18
+ correlation_id = new_correlation_id()
19
+ yield(correlation_id)
20
+
21
+ store(correlation_id, ivar, timeout)
22
+ end
23
+ end
24
+
25
+ def finish correlation_id, response
26
+ pending.delete(correlation_id).tap do |request|
27
+ request.ivar.set(response) if request
28
+ end
29
+ end
30
+
31
+ def expire
32
+ now = current_time
33
+
34
+ pending.delete_if do |_correlation_id, request|
35
+ now > request.expiration_time
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def store correlation_id, ivar, timeout
42
+ expiration_time = current_time + timeout
43
+
44
+ pending[correlation_id] = Request.new(ivar, expiration_time)
45
+ end
46
+
47
+ def new_correlation_id
48
+ SecureRandom.urlsafe_base64
49
+ end
50
+
51
+ def new_ivar
52
+ Concurrent::IVar.new
53
+ end
54
+
55
+ def current_time
56
+ Time.now
57
+ end
58
+
59
+ attr_reader :pending
60
+
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,71 @@
1
+ module Liebre
2
+ module Actor
3
+ module RPC
4
+ class Client
5
+ class Reporter
6
+
7
+ def initialize context
8
+ @context = context
9
+ end
10
+
11
+ def on_start
12
+ yield
13
+ logger.info("RPC client started: #{name}")
14
+ rescue Exception => error
15
+ logger.error("Error starting RPC client: #{name}\n#{error.message}\n#{error.backtrace}")
16
+ raise error
17
+ end
18
+
19
+ def on_stop
20
+ yield
21
+ logger.info("RPC client stopped: #{name}")
22
+ rescue Exception => error
23
+ logger.error("Error stopping RPC client: #{name}\n#{error.message}\n#{error.backtrace}")
24
+ raise error
25
+ end
26
+
27
+ def on_request
28
+ yield
29
+ rescue Exception => error
30
+ logger.error("Error performing request: #{name}\n#{error.message}\n#{error.backtrace}")
31
+ raise error
32
+ end
33
+
34
+ def on_reply
35
+ yield
36
+ rescue Exception => error
37
+ logger.error("Error receiving request reply: #{name}\n#{error.message}\n#{error.backtrace}")
38
+ raise error
39
+ end
40
+
41
+ def on_expire
42
+ yield
43
+ rescue Exception => error
44
+ logger.error("Error expiring RPC client pending requests: #{name}\n#{error.message}\n#{error.backtrace}")
45
+ raise error
46
+ end
47
+
48
+ def on_clean
49
+ yield
50
+ rescue Exception => error
51
+ logger.error("Error cleaning RPC client: #{name}\n#{error.message}\n#{error.backtrace}")
52
+ raise error
53
+ end
54
+
55
+ private
56
+
57
+ def name
58
+ @name ||= context.name.inspect
59
+ end
60
+
61
+ def logger
62
+ @logger ||= context.logger
63
+ end
64
+
65
+ attr_reader :context
66
+
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,62 @@
1
+ require 'securerandom'
2
+
3
+ module Liebre
4
+ module Actor
5
+ module RPC
6
+ class Client
7
+ class Resources
8
+
9
+ DEFAULT_PREFIX = "rpc_responses"
10
+
11
+ QUEUE_OPTS = {:auto_delete => true,
12
+ :exclusive => true,
13
+ :durable => false}
14
+
15
+ def initialize context
16
+ @context = context
17
+ end
18
+
19
+ def response_queue
20
+ @response_queue ||= declare.queue(:name => queue_name, :opts => QUEUE_OPTS)
21
+ end
22
+
23
+ def request_exchange
24
+ @request_exchange ||= declare.exchange(exchange_config)
25
+ end
26
+
27
+ private
28
+
29
+ def queue_name
30
+ prefix = queue_config.fetch(:prefix, DEFAULT_PREFIX)
31
+ suffix = SecureRandom.urlsafe_base64
32
+
33
+ "#{prefix}_#{suffix}"
34
+ end
35
+
36
+ def exchange_config
37
+ spec.fetch(:exchange)
38
+ end
39
+
40
+ def queue_config
41
+ spec.fetch(:queue, {})
42
+ end
43
+
44
+ def bind_config
45
+ spec.fetch(:bind, {})
46
+ end
47
+
48
+ def spec
49
+ context.spec
50
+ end
51
+
52
+ def declare
53
+ context.declare
54
+ end
55
+
56
+ attr_reader :context
57
+
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,33 @@
1
+ require 'concurrent'
2
+
3
+ module Liebre
4
+ module Actor
5
+ module RPC
6
+ class Client
7
+ class Task
8
+
9
+ def initialize
10
+ @tasks = []
11
+ end
12
+
13
+ def every interval, &block
14
+ task = Concurrent::TimerTask.new(execution_interval: interval, &block)
15
+ tasks << task
16
+
17
+ task.execute
18
+ end
19
+
20
+ def cancel_all
21
+ tasks.each(&:shutdown)
22
+ tasks.clear
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :tasks
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,74 @@
1
+ require 'concurrent'
2
+
3
+ require 'liebre/actor/rpc/server/resources'
4
+ require 'liebre/actor/rpc/server/callback'
5
+ require 'liebre/actor/rpc/server/core'
6
+ require 'liebre/actor/rpc/server/reporter'
7
+
8
+ module Liebre
9
+ module Actor
10
+ module RPC
11
+ class Server
12
+ include Concurrent::Async
13
+
14
+ OPTS = {:block => false, :manual_ack => false}
15
+
16
+ def initialize context
17
+ super()
18
+
19
+ @context = context
20
+ end
21
+
22
+ def start() async.__start__(); end
23
+ def stop() async.__stop__(); end
24
+
25
+ def handle(meta, payload) async.__handle__(meta, payload); end
26
+
27
+ def reply(meta, response, opts = {}) async.__reply__(meta, response, opts); end
28
+ def failed(meta, error) async.__failed__(meta, error); end
29
+
30
+ def clean() async.__clean__(); end
31
+
32
+ def __start__()
33
+ reporter.on_start { core.start }
34
+ end
35
+ def __stop__()
36
+ reporter.on_stop { core.stop }
37
+ end
38
+
39
+ def __handle__(meta, payload)
40
+ reporter.on_handle { core.handle(meta, payload) }
41
+ end
42
+
43
+ def __reply__(meta, response, opts)
44
+ reporter.on_reply { core.reply(meta, response, opts) }
45
+ end
46
+
47
+ def __failed__(meta, error)
48
+ reporter.on_failed(error) { core.failed(meta, error) }
49
+ end
50
+
51
+ def __clean__
52
+ reporter.on_clean { core.clean() }
53
+ end
54
+
55
+ private
56
+
57
+ def core
58
+ @core ||= Core.new(self, resources, context, Callback)
59
+ end
60
+
61
+ def resources
62
+ Resources.new(context)
63
+ end
64
+
65
+ def reporter
66
+ @reporter ||= Reporter.new(context)
67
+ end
68
+
69
+ attr_reader :context
70
+
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,28 @@
1
+ module Liebre
2
+ module Actor
3
+ module RPC
4
+ class Server
5
+ class Callback
6
+
7
+ def initialize server, meta
8
+ @server = server
9
+ @meta = meta
10
+ end
11
+
12
+ def reply response, opts = {}
13
+ server.reply(meta, response, opts)
14
+ end
15
+
16
+ def failed error
17
+ server.failed(meta, error)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :server, :meta
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,75 @@
1
+ module Liebre
2
+ module Actor
3
+ module RPC
4
+ class Server
5
+ class Core
6
+ include Concurrent::Async
7
+
8
+ OPTS = {:block => false, :manual_ack => false}
9
+
10
+ def initialize server, resources, context, callback_class
11
+ @server = server
12
+ @resources = resources
13
+ @context = context
14
+ @callback_class = callback_class
15
+ end
16
+
17
+ def start
18
+ queue.subscribe(OPTS) do |info, meta, payload|
19
+ server.handle(meta, payload)
20
+ end
21
+ exchange
22
+ end
23
+
24
+ def stop
25
+ chan.close
26
+ end
27
+
28
+ def handle meta, payload
29
+ callback = callback_class.new(server, meta)
30
+
31
+ handler.call(payload, meta, callback) do |error|
32
+ callback.failed(error)
33
+ end
34
+ end
35
+
36
+ def reply meta, response, opts = {}
37
+ opts = opts.merge :routing_key => meta.reply_to,
38
+ :correlation_id => meta.correlation_id
39
+
40
+ exchange.publish(response, opts)
41
+ end
42
+
43
+ def failed meta, error
44
+ end
45
+
46
+ def clean
47
+ queue.delete
48
+ exchange.delete
49
+ end
50
+
51
+ private
52
+
53
+ def queue
54
+ resources.request_queue
55
+ end
56
+
57
+ def exchange
58
+ resources.response_exchange
59
+ end
60
+
61
+ def chan
62
+ context.chan
63
+ end
64
+
65
+ def handler
66
+ context.handler
67
+ end
68
+
69
+ attr_reader :server, :resources, :context, :callback_class
70
+
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,72 @@
1
+ module Liebre
2
+ module Actor
3
+ module RPC
4
+ class Server
5
+ class Reporter
6
+
7
+ def initialize context
8
+ @context = context
9
+ end
10
+
11
+ def on_start
12
+ yield
13
+ logger.info("RPC server started: #{name}")
14
+ rescue Exception => error
15
+ logger.error("Error starting RPC server: #{name}\n#{error.message}\n#{error.backtrace}")
16
+ raise error
17
+ end
18
+
19
+ def on_stop
20
+ yield
21
+ logger.info("RPC server stopped: #{name}")
22
+ rescue Exception => error
23
+ logger.error("Error stopping RPC server: #{name}\n#{error.message}\n#{error.backtrace}")
24
+ raise error
25
+ end
26
+
27
+ def on_handle
28
+ yield
29
+ rescue Exception => error
30
+ logger.error("Error handling request: #{name}\n#{error.message}\n#{error.backtrace}")
31
+ raise error
32
+ end
33
+
34
+ def on_reply
35
+ yield
36
+ rescue Exception => error
37
+ logger.error("Error replying request: #{name}\n#{error.message}\n#{error.backtrace}")
38
+ raise error
39
+ end
40
+
41
+ def on_failed(error)
42
+ logger.error("Error on RPC server when handling a message #{name}\n#{error.message}\n#{error.backtrace}")
43
+ yield
44
+ rescue Exception => error
45
+ logger.error("Error handling RPC server handler failure: #{name}\n#{error.message}\n#{error.backtrace}")
46
+ raise error
47
+ end
48
+
49
+ def on_clean
50
+ yield
51
+ rescue Exception => error
52
+ logger.error("Error cleaning rpc server: #{name}\n#{error.message}\n#{error.backtrace}")
53
+ raise error
54
+ end
55
+
56
+ private
57
+
58
+ def name
59
+ @name ||= context.name.inspect
60
+ end
61
+
62
+ def logger
63
+ @logger ||= context.logger
64
+ end
65
+
66
+ attr_reader :context
67
+
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end