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,36 @@
|
|
1
|
+
module Liebre
|
2
|
+
class Bridge
|
3
|
+
class ChannelBuilder
|
4
|
+
|
5
|
+
DEFAULT_PREFETCH = 10
|
6
|
+
|
7
|
+
def initialize connections, opts
|
8
|
+
@connections = connections
|
9
|
+
@opts = opts
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
connection.open_channel.tap do |channel|
|
14
|
+
channel.set_prefetch(prefetch_count)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def connection
|
21
|
+
connections.fetch(conn_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def conn_name
|
25
|
+
opts.fetch(:connection)
|
26
|
+
end
|
27
|
+
|
28
|
+
def prefetch_count
|
29
|
+
opts.fetch(:prefetch_count, DEFAULT_PREFETCH)
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_reader :connections, :opts
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/liebre/config.rb
CHANGED
@@ -1,47 +1,17 @@
|
|
1
|
-
require "yaml"
|
2
|
-
|
3
1
|
module Liebre
|
4
2
|
class Config
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
class << self
|
12
|
-
attr_accessor :env
|
13
|
-
attr_writer :config_path, :connection_path, :logger
|
14
|
-
|
15
|
-
def config_path
|
16
|
-
@config_path || CONFIG_PATH
|
17
|
-
end
|
18
|
-
|
19
|
-
def connection_path
|
20
|
-
@connection_path || CONNECTION_PATH
|
21
|
-
end
|
22
|
-
|
23
|
-
def logger
|
24
|
-
@logger || DEFAULT_LOGGER
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def consumers
|
30
|
-
config.fetch 'consumers', {}
|
31
|
-
end
|
32
|
-
|
33
|
-
def publishers
|
34
|
-
config.fetch 'publishers', {}
|
35
|
-
end
|
36
|
-
|
37
|
-
def rpc_request_timeout
|
38
|
-
config.fetch 'rpc_request_timeout', DEFAULT_RPC_TIMEOUT
|
4
|
+
attr_accessor :adapter, :connections, :actors
|
5
|
+
attr_writer :logger
|
6
|
+
|
7
|
+
def logger
|
8
|
+
@logger || null_logger
|
39
9
|
end
|
40
10
|
|
41
|
-
|
11
|
+
private
|
42
12
|
|
43
|
-
def
|
44
|
-
@
|
13
|
+
def null_logger
|
14
|
+
@null_logger ||= Logger.new(nil)
|
45
15
|
end
|
46
16
|
|
47
17
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "liebre/engine/state"
|
2
|
+
require "liebre/engine/builder"
|
3
|
+
|
4
|
+
require "liebre/engine/repository"
|
5
|
+
|
6
|
+
module Liebre
|
7
|
+
class Engine
|
8
|
+
|
9
|
+
def initialize config
|
10
|
+
@config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def start only: nil
|
14
|
+
bridge.start
|
15
|
+
|
16
|
+
state.to_start(only: only) do |type, name, opts|
|
17
|
+
actor = build(type, name, opts)
|
18
|
+
actor.start
|
19
|
+
|
20
|
+
repo.insert(type, name, actor)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean only: nil
|
25
|
+
bridge.start
|
26
|
+
|
27
|
+
state.to_clean(only: only) do |type, name, opts|
|
28
|
+
actor = build(type, name, opts)
|
29
|
+
actor.clean
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def stop
|
34
|
+
repo.each(&:stop)
|
35
|
+
repo.clear
|
36
|
+
bridge.stop
|
37
|
+
end
|
38
|
+
|
39
|
+
def repo
|
40
|
+
@repo ||= Repository.new
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def build type, name, opts
|
46
|
+
builder = Builder.new(bridge, type, name, opts, config)
|
47
|
+
builder.call
|
48
|
+
end
|
49
|
+
|
50
|
+
def state
|
51
|
+
@state ||= State.new(config.actors)
|
52
|
+
end
|
53
|
+
|
54
|
+
def bridge
|
55
|
+
@bridge ||= Bridge.new(config)
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_reader :config
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Liebre
|
2
|
+
class Engine
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
CONTEXT = Actor::Context
|
6
|
+
|
7
|
+
ACTORS = {
|
8
|
+
:publishers => Actor::Publisher,
|
9
|
+
:consumers => Actor::Consumer,
|
10
|
+
:rpc_clients => Actor::RPC::Client,
|
11
|
+
:rpc_servers => Actor::RPC::Server
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize bridge, type, name, opts, config, context: CONTEXT, actors: ACTORS
|
15
|
+
@bridge = bridge
|
16
|
+
@type = type
|
17
|
+
@name = name
|
18
|
+
@opts = opts
|
19
|
+
@config = config
|
20
|
+
|
21
|
+
@context_class = context
|
22
|
+
@actor_classes = actors
|
23
|
+
end
|
24
|
+
|
25
|
+
def call
|
26
|
+
actor_class.new(context)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def actor_class
|
32
|
+
actor_classes.fetch(type)
|
33
|
+
end
|
34
|
+
|
35
|
+
def context
|
36
|
+
context_class.new(chan, name, opts, config)
|
37
|
+
end
|
38
|
+
|
39
|
+
def chan
|
40
|
+
bridge.open_channel(opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :bridge, :type, :name, :opts, :config,
|
44
|
+
:context_class, :actor_classes
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Liebre
|
2
|
+
class Engine
|
3
|
+
class Repository
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@publishers = {}
|
7
|
+
@consumers = {}
|
8
|
+
@rpc_clients = {}
|
9
|
+
@rpc_servers = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def insert type, name, resource
|
13
|
+
case type
|
14
|
+
when :publishers then publishers[name] = resource
|
15
|
+
when :consumers then consumers[name] = resource
|
16
|
+
when :rpc_clients then rpc_clients[name] = resource
|
17
|
+
when :rpc_servers then rpc_servers[name] = resource
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def all
|
22
|
+
publishers.values + consumers.values + rpc_clients.values + rpc_servers.values
|
23
|
+
end
|
24
|
+
|
25
|
+
def each &block
|
26
|
+
all.each(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
publishers.clear
|
31
|
+
consumers.clear
|
32
|
+
rpc_clients.clear
|
33
|
+
rpc_servers.clear
|
34
|
+
end
|
35
|
+
|
36
|
+
def publisher name
|
37
|
+
publishers.fetch(name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def consumer name
|
41
|
+
consumers.fetch(name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def rpc_client name
|
45
|
+
rpc_clients.fetch(name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def rpc_server name
|
49
|
+
rpc_servers.fetch(name)
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_reader :publishers, :consumers, :rpc_clients, :rpc_servers
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Liebre
|
2
|
+
class Engine
|
3
|
+
class State
|
4
|
+
|
5
|
+
def initialize config
|
6
|
+
@config = config
|
7
|
+
@started = Hash.new { |hash, key| hash[key] = {} }
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_start only: nil
|
11
|
+
all do |type, name, opts|
|
12
|
+
if has_to_start?(type, name, only)
|
13
|
+
yield(type, name, opts)
|
14
|
+
set_started(type, name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_clean only: nil
|
20
|
+
all do |type, name, opts|
|
21
|
+
yield(type, name, opts) if match?(type, only)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def has_to_start? type, name, only
|
28
|
+
started[type][name].nil? and match?(type, only)
|
29
|
+
end
|
30
|
+
|
31
|
+
def match? type, only
|
32
|
+
only.nil? or only.include?(type)
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_started type, name
|
36
|
+
started[type][name] = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def all
|
40
|
+
config.each do |type, specs|
|
41
|
+
specs.each { |name, opts| yield(type, name, opts) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
attr_reader :config, :started
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/liebre/runner.rb
CHANGED
@@ -1,65 +1,33 @@
|
|
1
1
|
module Liebre
|
2
2
|
class Runner
|
3
|
-
|
4
|
-
autoload :Consumers, 'liebre/runner/consumers'
|
5
|
-
autoload :Starter, 'liebre/runner/starter'
|
6
|
-
|
3
|
+
|
7
4
|
RETRY_INTERVAL = 5
|
8
5
|
|
9
|
-
def initialize
|
10
|
-
@
|
6
|
+
def initialize engine: Liebre.engine
|
7
|
+
@engine = engine
|
11
8
|
end
|
12
9
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
start_consumers
|
10
|
+
def run only: nil
|
11
|
+
setup_signals
|
12
|
+
engine.start(only: only)
|
17
13
|
sleep
|
18
|
-
rescue
|
19
|
-
|
14
|
+
rescue => e
|
15
|
+
sleep(RETRY_INTERVAL)
|
20
16
|
retry
|
21
17
|
end
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
def setup_shutdown
|
26
|
-
Signal.trap("TERM") { do_shutdown; exit }
|
27
|
-
Signal.trap("USR1") { do_shutdown; exit }
|
28
|
-
end
|
29
|
-
|
30
|
-
def do_shutdown
|
31
|
-
Thread.start do
|
32
|
-
logger.info("Liebre# Closing AMQP connection...")
|
33
|
-
consumers.stop
|
34
|
-
connection_manager.stop
|
35
|
-
logger.info("Liebre# AMQP connection closed")
|
36
|
-
end.join
|
37
|
-
end
|
38
|
-
|
39
|
-
def start_consumers
|
40
|
-
logger.info("Liebre# Starting consumers...")
|
41
|
-
consumers.start_all
|
42
|
-
end
|
19
|
+
private
|
43
20
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
logger.warn("Liebre# Retrying connection")
|
48
|
-
end
|
49
|
-
|
50
|
-
def logger
|
51
|
-
Liebre.logger
|
52
|
-
end
|
53
|
-
|
54
|
-
def consumers
|
55
|
-
@consumers ||= Consumers.new(connection_manager)
|
21
|
+
def setup_signals
|
22
|
+
Signal.trap("TERM") { do_stop; exit }
|
23
|
+
Signal.trap("USR1") { do_stop; exit }
|
56
24
|
end
|
57
25
|
|
58
|
-
def
|
59
|
-
|
26
|
+
def do_stop
|
27
|
+
Thread.new { engine.stop }.join
|
60
28
|
end
|
61
29
|
|
62
|
-
attr_reader :
|
30
|
+
attr_reader :engine
|
63
31
|
|
64
32
|
end
|
65
33
|
end
|
data/lib/liebre/version.rb
CHANGED
data/liebre.gemspec
CHANGED
@@ -6,10 +6,10 @@ require 'liebre/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "liebre"
|
8
8
|
spec.version = Liebre::VERSION
|
9
|
-
spec.authors = ["jcabotc"
|
10
|
-
spec.email = ["jcabot@gmail.com"
|
11
|
-
spec.summary = %q{
|
12
|
-
spec.homepage = "
|
9
|
+
spec.authors = ["jcabotc"]
|
10
|
+
spec.email = ["jcabot@gmail.com"]
|
11
|
+
spec.summary = %q{Some abstractions to interact with a AMQP broker}
|
12
|
+
spec.homepage = ""
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -17,10 +17,12 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.
|
20
|
+
spec.add_dependency "concurrent-ruby"
|
21
21
|
|
22
|
-
spec.add_development_dependency "
|
22
|
+
spec.add_development_dependency "bunny"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
23
26
|
spec.add_development_dependency "rspec"
|
24
27
|
spec.add_development_dependency "pry"
|
25
|
-
spec.add_development_dependency "rake"
|
26
28
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
RSpec.describe "Publish and consume" do
|
2
|
+
|
3
|
+
let(:connections) { {"test_conn" => {}} }
|
4
|
+
|
5
|
+
let :exchange do
|
6
|
+
{:name => "__test__.liebre.publish_and_consume_exchange",
|
7
|
+
:type => "fanout",
|
8
|
+
:opts => {:auto_delete => true, :durable => false}}
|
9
|
+
end
|
10
|
+
|
11
|
+
let :queue do
|
12
|
+
{:name => "__test__.liebre.publish_and_consume_queue",
|
13
|
+
:opts => {:auto_delete => true, :durable => false}}
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:handler_class) { double 'handler_class' }
|
17
|
+
let(:handler) { double 'handler' }
|
18
|
+
|
19
|
+
let :actors do
|
20
|
+
{
|
21
|
+
:publishers => {
|
22
|
+
:my_publisher => {
|
23
|
+
:connection => "test_conn",
|
24
|
+
:resources => {:exchange => exchange}
|
25
|
+
}
|
26
|
+
},
|
27
|
+
:consumers => {
|
28
|
+
:my_consumer => {
|
29
|
+
:connection => "test_conn",
|
30
|
+
:prefetch_count => 5,
|
31
|
+
:pool_size => 1,
|
32
|
+
:handler => handler_class,
|
33
|
+
:resources => {:exchange => exchange, :queue => queue}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
let :config do
|
40
|
+
Liebre::Config.new.tap do |config|
|
41
|
+
config.adapter = Liebre::Adapter::Bunny
|
42
|
+
config.connections = connections
|
43
|
+
config.actors = actors
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:payload) { "some_data" }
|
48
|
+
let(:headers) { {"foo" => "bar"} }
|
49
|
+
|
50
|
+
it "sends and receives data" do
|
51
|
+
engine = Liebre::Engine.new(config)
|
52
|
+
engine.start
|
53
|
+
|
54
|
+
repo = engine.repo
|
55
|
+
publisher = repo.publisher(:my_publisher)
|
56
|
+
|
57
|
+
expect(handler_class).to receive :new do |payload, meta, callback|
|
58
|
+
expect(payload ).to eq payload
|
59
|
+
expect(meta.headers).to eq headers
|
60
|
+
|
61
|
+
handler
|
62
|
+
end
|
63
|
+
expect(handler).to receive(:call)
|
64
|
+
|
65
|
+
sleep(0.1) # wait for the consumer to bind its queue to the exchange
|
66
|
+
publisher.publish(payload, :headers => headers)
|
67
|
+
|
68
|
+
sleep(0.2) # wait for the message to be published and consumed
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|