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,40 @@
|
|
1
|
+
require "liebre/actor/context/declare"
|
2
|
+
require "liebre/actor/context/handler"
|
3
|
+
|
4
|
+
module Liebre
|
5
|
+
module Actor
|
6
|
+
class Context
|
7
|
+
|
8
|
+
attr_reader :chan, :name, :opts
|
9
|
+
|
10
|
+
def initialize chan, name, opts, config
|
11
|
+
@chan = chan
|
12
|
+
@name = name
|
13
|
+
@opts = opts
|
14
|
+
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def spec
|
19
|
+
opts.fetch(:resources, {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def declare
|
23
|
+
@declare ||= Declare.new(chan)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handler
|
27
|
+
@handler ||= Handler.new(opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
def logger
|
31
|
+
config.logger
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :config
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Liebre
|
2
|
+
module Actor
|
3
|
+
class Context
|
4
|
+
class Declare
|
5
|
+
|
6
|
+
def initialize chan
|
7
|
+
@chan = chan
|
8
|
+
end
|
9
|
+
|
10
|
+
def default_exchange
|
11
|
+
chan.default_exchange
|
12
|
+
end
|
13
|
+
|
14
|
+
def exchange config
|
15
|
+
name = config.fetch(:name)
|
16
|
+
type = config.fetch(:type)
|
17
|
+
opts = config.fetch(:opts, {})
|
18
|
+
|
19
|
+
chan.exchange(name, type, opts)
|
20
|
+
end
|
21
|
+
|
22
|
+
def queue config
|
23
|
+
name = config.fetch(:name)
|
24
|
+
opts = config.fetch(:opts, {})
|
25
|
+
|
26
|
+
chan.queue(name, opts)
|
27
|
+
end
|
28
|
+
|
29
|
+
def bind queue, exchange, config = {}
|
30
|
+
all_opts = [config].flatten
|
31
|
+
|
32
|
+
all_opts.each do |opts|
|
33
|
+
queue.bind(exchange, opts)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr_reader :chan
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
module Liebre
|
4
|
+
module Actor
|
5
|
+
class Context
|
6
|
+
class Handler
|
7
|
+
|
8
|
+
DEFAULT_POOL_SIZE = 5
|
9
|
+
|
10
|
+
def initialize opts
|
11
|
+
@opts = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def call *args, &block
|
15
|
+
pool.post { handle(args, block) }
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def handle args, block
|
21
|
+
handler = handler_class.new(*args)
|
22
|
+
handler.call
|
23
|
+
rescue => error
|
24
|
+
block.call(error)
|
25
|
+
end
|
26
|
+
|
27
|
+
def pool
|
28
|
+
@pool ||= begin
|
29
|
+
size = opts.fetch(:pool_size, DEFAULT_POOL_SIZE)
|
30
|
+
|
31
|
+
Concurrent::FixedThreadPool.new(size)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def handler_class
|
36
|
+
@handler_class ||= opts.fetch(:handler)
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :opts
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
require 'liebre/actor/publisher/resources'
|
4
|
+
require 'liebre/actor/publisher/core'
|
5
|
+
require 'liebre/actor/publisher/reporter'
|
6
|
+
|
7
|
+
module Liebre
|
8
|
+
module Actor
|
9
|
+
class Publisher
|
10
|
+
include Concurrent::Async
|
11
|
+
|
12
|
+
def initialize context
|
13
|
+
super()
|
14
|
+
|
15
|
+
@context = context
|
16
|
+
end
|
17
|
+
|
18
|
+
def start() async.__start__(); end
|
19
|
+
def stop() async.__stop__(); end
|
20
|
+
|
21
|
+
def publish(payload, opts = {}) async.__publish__(payload, opts); end
|
22
|
+
|
23
|
+
def clean() async.__clean__(); end
|
24
|
+
|
25
|
+
def __start__
|
26
|
+
reporter.on_start { core.start }
|
27
|
+
end
|
28
|
+
def __stop__
|
29
|
+
reporter.on_stop { core.stop }
|
30
|
+
end
|
31
|
+
|
32
|
+
def __publish__ payload, opts
|
33
|
+
reporter.on_publish { core.publish(payload, opts) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def __clean__
|
37
|
+
reporter.on_clean { core.clean() }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def core
|
43
|
+
@core ||= Core.new(resources, context)
|
44
|
+
end
|
45
|
+
|
46
|
+
def resources
|
47
|
+
Resources.new(context)
|
48
|
+
end
|
49
|
+
|
50
|
+
def reporter
|
51
|
+
@reporter ||= Reporter.new(context)
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :context
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Liebre
|
2
|
+
module Actor
|
3
|
+
class Publisher
|
4
|
+
class Core
|
5
|
+
|
6
|
+
def initialize resources, context
|
7
|
+
@resources = resources
|
8
|
+
@context = context
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
exchange
|
13
|
+
end
|
14
|
+
|
15
|
+
def stop
|
16
|
+
chan.close
|
17
|
+
end
|
18
|
+
|
19
|
+
def publish payload, opts
|
20
|
+
exchange.publish(payload, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def clean
|
24
|
+
exchange.delete
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def exchange
|
30
|
+
resources.exchange
|
31
|
+
end
|
32
|
+
|
33
|
+
def chan
|
34
|
+
context.chan
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :resources, :context
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Liebre
|
2
|
+
module Actor
|
3
|
+
class Publisher
|
4
|
+
class Reporter
|
5
|
+
|
6
|
+
def initialize context
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_start
|
11
|
+
yield
|
12
|
+
logger.info("Publisher started: #{name}")
|
13
|
+
rescue Exception => error
|
14
|
+
logger.error("Error starting publisher: #{name}\n#{error.message}\n#{error.backtrace}")
|
15
|
+
raise error
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_publish
|
19
|
+
yield
|
20
|
+
rescue Exception => error
|
21
|
+
logger.error("Error publising: #{name}\n#{error.message}\n#{error.backtrace}")
|
22
|
+
raise error
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_stop
|
26
|
+
yield
|
27
|
+
logger.info("Publisher stopped: #{name}")
|
28
|
+
rescue Exception => error
|
29
|
+
logger.error("Error stopping publisher: #{name}\n#{error.message}\n#{error.backtrace}")
|
30
|
+
raise error
|
31
|
+
end
|
32
|
+
|
33
|
+
def on_clean
|
34
|
+
yield
|
35
|
+
rescue Exception => error
|
36
|
+
logger.error("Error cleaning publisher: #{name}\n#{error.message}\n#{error.backtrace}")
|
37
|
+
raise error
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def name
|
43
|
+
@name ||= context.name.inspect
|
44
|
+
end
|
45
|
+
|
46
|
+
def logger
|
47
|
+
@logger ||= context.logger
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_reader :context
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Liebre
|
2
|
+
module Actor
|
3
|
+
class Publisher
|
4
|
+
class Resources
|
5
|
+
|
6
|
+
def initialize context
|
7
|
+
@context = context
|
8
|
+
end
|
9
|
+
|
10
|
+
def exchange
|
11
|
+
@exchange ||= declare.exchange(exchange_config)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def exchange_config
|
17
|
+
spec.fetch(:exchange)
|
18
|
+
end
|
19
|
+
|
20
|
+
def spec
|
21
|
+
context.spec
|
22
|
+
end
|
23
|
+
|
24
|
+
def declare
|
25
|
+
context.declare
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :context
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'concurrent'
|
2
|
+
|
3
|
+
require 'liebre/actor/rpc/client/resources'
|
4
|
+
require 'liebre/actor/rpc/client/pending'
|
5
|
+
require 'liebre/actor/rpc/client/task'
|
6
|
+
require 'liebre/actor/rpc/client/core'
|
7
|
+
require 'liebre/actor/rpc/client/reporter'
|
8
|
+
|
9
|
+
module Liebre
|
10
|
+
module Actor
|
11
|
+
module RPC
|
12
|
+
class Client
|
13
|
+
include Concurrent::Async
|
14
|
+
|
15
|
+
TIMEOUT = 5
|
16
|
+
|
17
|
+
def initialize context
|
18
|
+
super()
|
19
|
+
|
20
|
+
@context = context
|
21
|
+
end
|
22
|
+
|
23
|
+
def start() async.__start__(); end
|
24
|
+
def stop() async.__stop__(); end
|
25
|
+
|
26
|
+
def request payload, opts = {}, timeout = TIMEOUT
|
27
|
+
call_ivar = await.__request__(payload, opts, timeout)
|
28
|
+
response_ivar = call_ivar.value
|
29
|
+
|
30
|
+
response_ivar.value(timeout)
|
31
|
+
end
|
32
|
+
def reply(meta, response) async.__reply__(meta, response); end
|
33
|
+
|
34
|
+
def expire() async.__expire__(); end
|
35
|
+
|
36
|
+
def clean() async.__clean__(); end
|
37
|
+
|
38
|
+
def __start__()
|
39
|
+
reporter.on_start { core.start }
|
40
|
+
end
|
41
|
+
def __stop__()
|
42
|
+
reporter.on_stop { core.stop }
|
43
|
+
end
|
44
|
+
|
45
|
+
def __request__(payload, opts, timeout)
|
46
|
+
reporter.on_request { core.request(payload, opts, timeout) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def __reply__(meta, response)
|
50
|
+
reporter.on_reply { core.reply(meta, response) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def __expire__()
|
54
|
+
reporter.on_expire { core.expire() }
|
55
|
+
end
|
56
|
+
|
57
|
+
def __clean__()
|
58
|
+
reporter.on_clean { core.clean() }
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def core
|
64
|
+
@core ||= Core.new(self, resources, context, pending, task)
|
65
|
+
end
|
66
|
+
|
67
|
+
def resources
|
68
|
+
Resources.new(context)
|
69
|
+
end
|
70
|
+
|
71
|
+
def pending
|
72
|
+
Pending.new
|
73
|
+
end
|
74
|
+
|
75
|
+
def task
|
76
|
+
Task.new
|
77
|
+
end
|
78
|
+
|
79
|
+
def reporter
|
80
|
+
@reporter ||= Reporter.new(context)
|
81
|
+
end
|
82
|
+
|
83
|
+
attr_reader :context
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Liebre
|
2
|
+
module Actor
|
3
|
+
module RPC
|
4
|
+
class Client
|
5
|
+
class Core
|
6
|
+
|
7
|
+
OPTS = {:block => false, :manual_ack => false}
|
8
|
+
EXPIRE_INTERVAL = 60
|
9
|
+
|
10
|
+
def initialize client, resources, context, pending, task
|
11
|
+
@client = client
|
12
|
+
@resources = resources
|
13
|
+
@context = context
|
14
|
+
@pending = pending
|
15
|
+
@task = task
|
16
|
+
end
|
17
|
+
|
18
|
+
def start
|
19
|
+
response_queue.subscribe(OPTS) do |_info, meta, payload|
|
20
|
+
client.reply(meta, payload)
|
21
|
+
end
|
22
|
+
request_exchange
|
23
|
+
|
24
|
+
task.every(EXPIRE_INTERVAL) { client.expire }
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop
|
28
|
+
task.cancel_all
|
29
|
+
chan.close
|
30
|
+
end
|
31
|
+
|
32
|
+
def request payload, opts, timeout
|
33
|
+
r = pending.add(timeout) do |correlation_id|
|
34
|
+
opts = opts.merge :reply_to => response_queue.name,
|
35
|
+
:correlation_id => correlation_id
|
36
|
+
|
37
|
+
request_exchange.publish(payload, opts)
|
38
|
+
context.logger.info("request pending - correlation_id: #{correlation_id}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def reply meta, response
|
43
|
+
pending.finish(meta.correlation_id, response)
|
44
|
+
end
|
45
|
+
|
46
|
+
def expire
|
47
|
+
pending.expire()
|
48
|
+
end
|
49
|
+
|
50
|
+
def clean
|
51
|
+
request_exchange.delete
|
52
|
+
response_queue.delete
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def response_queue
|
58
|
+
resources.response_queue
|
59
|
+
end
|
60
|
+
|
61
|
+
def request_exchange
|
62
|
+
resources.request_exchange
|
63
|
+
end
|
64
|
+
|
65
|
+
def chan
|
66
|
+
context.chan
|
67
|
+
end
|
68
|
+
|
69
|
+
attr_reader :client, :resources, :context, :pending, :task
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|