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.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/Gemfile.lock +9 -7
- data/{LICENSE → LICENSE.txt} +1 -1
- data/README.md +492 -195
- data/Rakefile +2 -0
- data/lib/liebre.rb +27 -16
- data/lib/liebre/actor.rb +11 -0
- data/lib/liebre/actor/consumer.rb +80 -0
- data/lib/liebre/actor/consumer/callback.rb +34 -0
- data/lib/liebre/actor/consumer/core.rb +80 -0
- data/lib/liebre/actor/consumer/reporter.rb +84 -0
- data/lib/liebre/actor/consumer/resources.rb +47 -0
- data/lib/liebre/actor/consumer/resources/config.rb +65 -0
- data/lib/liebre/actor/context.rb +40 -0
- data/lib/liebre/actor/context/declare.rb +44 -0
- data/lib/liebre/actor/context/handler.rb +44 -0
- data/lib/liebre/actor/publisher.rb +58 -0
- data/lib/liebre/actor/publisher/core.rb +42 -0
- data/lib/liebre/actor/publisher/reporter.rb +55 -0
- data/lib/liebre/actor/publisher/resources.rb +33 -0
- data/lib/liebre/actor/rpc/client.rb +88 -0
- data/lib/liebre/actor/rpc/client/core.rb +75 -0
- data/lib/liebre/actor/rpc/client/pending.rb +65 -0
- data/lib/liebre/actor/rpc/client/reporter.rb +71 -0
- data/lib/liebre/actor/rpc/client/resources.rb +62 -0
- data/lib/liebre/actor/rpc/client/task.rb +33 -0
- data/lib/liebre/actor/rpc/server.rb +74 -0
- data/lib/liebre/actor/rpc/server/callback.rb +28 -0
- data/lib/liebre/actor/rpc/server/core.rb +75 -0
- data/lib/liebre/actor/rpc/server/reporter.rb +72 -0
- data/lib/liebre/actor/rpc/server/resources.rb +53 -0
- data/lib/liebre/adapter.rb +8 -0
- data/lib/liebre/adapter/bunny.rb +23 -0
- data/lib/liebre/adapter/bunny/chan.rb +38 -0
- data/lib/liebre/adapter/bunny/conn.rb +32 -0
- data/lib/liebre/adapter/bunny/exchange.rb +20 -0
- data/lib/liebre/adapter/bunny/queue.rb +59 -0
- data/lib/liebre/adapter/interface.rb +26 -0
- data/lib/liebre/adapter/interface/chan.rb +29 -0
- data/lib/liebre/adapter/interface/conn.rb +21 -0
- data/lib/liebre/adapter/interface/exchange.rb +13 -0
- data/lib/liebre/adapter/interface/queue.rb +37 -0
- data/lib/liebre/bridge.rb +72 -0
- data/lib/liebre/bridge/channel_builder.rb +36 -0
- data/lib/liebre/config.rb +8 -38
- data/lib/liebre/engine.rb +61 -0
- data/lib/liebre/engine/builder.rb +48 -0
- data/lib/liebre/engine/repository.rb +56 -0
- data/lib/liebre/engine/state.rb +49 -0
- data/lib/liebre/runner.rb +15 -47
- data/lib/liebre/version.rb +1 -1
- data/liebre.gemspec +9 -7
- data/spec/integration/publish_and_consume_spec.rb +71 -0
- data/spec/integration/rpc_communication_spec.rb +81 -0
- data/spec/integration/start_twice_spec.rb +63 -0
- data/spec/liebre/actor/consumer_spec.rb +169 -0
- data/spec/liebre/actor/context/declare_spec.rb +69 -0
- data/spec/liebre/actor/context/handler_spec.rb +65 -0
- data/spec/liebre/actor/publisher_spec.rb +58 -0
- data/spec/liebre/actor/rpc/client_spec.rb +126 -0
- data/spec/liebre/actor/rpc/server_spec.rb +141 -0
- data/spec/liebre/adapter/bunny_spec.rb +66 -0
- data/spec/liebre/bridge_spec.rb +54 -0
- data/spec/liebre/engine/builder_spec.rb +42 -0
- data/spec/liebre/engine_spec.rb +90 -0
- data/spec/liebre/version_spec.rb +10 -0
- data/spec/spec_helper.rb +2 -9
- metadata +97 -58
- data/lib/liebre/common.rb +0 -7
- data/lib/liebre/common/utils.rb +0 -37
- data/lib/liebre/connection_manager.rb +0 -85
- data/lib/liebre/publisher.rb +0 -113
- data/lib/liebre/runner/consumers.rb +0 -46
- data/lib/liebre/runner/starter.rb +0 -44
- data/lib/liebre/runner/starter/consumer.rb +0 -129
- data/lib/liebre/runner/starter/consumer/handler.rb +0 -35
- data/lib/liebre/runner/starter/resources.rb +0 -45
- data/lib/liebre/runner/starter/resources/queue_builder.rb +0 -63
- data/lib/liebre/runner/starter/rpc.rb +0 -59
- data/lib/liebre/tasks.rb +0 -12
- data/spec/config/liebre.yml +0 -48
- data/spec/config/rabbitmq.yml +0 -35
- data/spec/integration_spec.rb +0 -76
- data/spec/liebre/config_spec.rb +0 -63
- data/spec/liebre/connection_manager_spec.rb +0 -44
- data/spec/liebre/publisher_spec.rb +0 -92
- data/spec/liebre/runner/consumers_spec.rb +0 -59
- data/spec/liebre/runner/starter/consumer_spec.rb +0 -145
- data/spec/liebre/runner/starter/resources/queue_builder_spec.rb +0 -69
- data/spec/liebre/runner/starter/resources_spec.rb +0 -38
- data/spec/liebre/runner/starter/rpc_spec.rb +0 -100
- data/spec/liebre/runner/starter_spec.rb +0 -70
- 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
|