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
@@ -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