liebre 0.1.21 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|