basquiat 1.1.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 +7 -0
- data/.gitignore +19 -0
- data/.metrics +5 -0
- data/.rspec +4 -0
- data/.rubocop.yml +12 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/Guardfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +95 -0
- data/Rakefile +13 -0
- data/basquiat.gemspec +39 -0
- data/docker/Dockerfile +11 -0
- data/docker/basquiat_start.sh +9 -0
- data/docker-compose.yml +11 -0
- data/lib/basquiat/adapters/base_adapter.rb +54 -0
- data/lib/basquiat/adapters/rabbitmq_adapter.rb +130 -0
- data/lib/basquiat/adapters/test_adapter.rb +52 -0
- data/lib/basquiat/adapters.rb +2 -0
- data/lib/basquiat/interfaces/base.rb +62 -0
- data/lib/basquiat/rails/railtie.rb +14 -0
- data/lib/basquiat/support/configuration.rb +62 -0
- data/lib/basquiat/support/hash_refinements.rb +24 -0
- data/lib/basquiat/support/json.rb +13 -0
- data/lib/basquiat/support.rb +3 -0
- data/lib/basquiat/version.rb +4 -0
- data/lib/basquiat.rb +27 -0
- data/spec/lib/adapters/base_adapter_spec.rb +11 -0
- data/spec/lib/adapters/rabbitmq_adapter_spec.rb +79 -0
- data/spec/lib/adapters/test_adapter_spec.rb +61 -0
- data/spec/lib/basquiat_spec.rb +27 -0
- data/spec/lib/interfaces/base_spec.rb +100 -0
- data/spec/lib/support/configuration_spec.rb +73 -0
- data/spec/lib/support/hash_refinements_spec.rb +24 -0
- data/spec/lib/support/json_spec.rb +5 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/basquiat.yml +9 -0
- data/spec/support/shared_examples/basquiat_adapter_shared_examples.rb +23 -0
- metadata +305 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4d297e7591c1ea6247edd40cf816fd9886c9f8d7
|
4
|
+
data.tar.gz: 93b240d5a7353ed4ceb65ded88e3de66f64a18d9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2fffd158b4d20998d28e100351892571bd952874affb8a18fb83b7cf64d3815b6fbad980ea2826905eda70c88afa33249b10b23d3025a18697e1a1478ed67368
|
7
|
+
data.tar.gz: 45366c9864d178391f97ba52caad3bc6a2c77375a2c360ee66da325a37a3fb75c5066703582f50074acfb5bc2e1a29ab64a0b82168c0d22ed491c437242e2d8a
|
data/.gitignore
ADDED
data/.metrics
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
basquiat
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.5
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
guard :bundler do
|
2
|
+
watch('Gemfile')
|
3
|
+
watch('basquiat.gemspec')
|
4
|
+
end
|
5
|
+
|
6
|
+
guard :rspec, { all_on_start: true, keep: true, all_after_pass: true, run_all: { cmd: 'rspec -f progress'} } do
|
7
|
+
watch(%r{^spec/.+_spec.rb$})
|
8
|
+
watch(%r{^spec/lib/.+_spec.rb$})
|
9
|
+
watch(%r{^lib/basquiat/(.+)\.rb$}) { |matchdata| "spec/lib/#{matchdata[1]}_spec.rb" }
|
10
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
11
|
+
watch(%r{spec/support/.+\.rb}) { 'spec' }
|
12
|
+
end
|
13
|
+
|
14
|
+
guard :rubocop, { cli: '-fs -c./.rubocop.yml'} do
|
15
|
+
#watch(%r{.+\.rb$})
|
16
|
+
#watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
17
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Marcello Rocha
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Basquiat
|
2
|
+
|
3
|
+
**Basquiat** is intended to hide (almost) all the complexity of working with some kind of message queue from the application internals.
|
4
|
+
|
5
|
+
All the exchanges, connections, queues and sessions declarations are swept under rug. The main aim is to provide a simple yet flexible interface to work with message queues.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'basquiat'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install basquiat
|
20
|
+
|
21
|
+
You will also need the right gem for your MQ system. Bundled in this gem you will find 2 adapters for RabbitMQ and ActiveMQ which depends on the gems _bunny_ and _ruby-stomp_ respectively.
|
22
|
+
|
23
|
+
## Basic Usage
|
24
|
+
|
25
|
+
First of all require the gem, the dependecy for the adapter and the adapter itself
|
26
|
+
|
27
|
+
require 'basquiat'
|
28
|
+
require 'bunny'
|
29
|
+
require 'basquiat/adapters/rabbitmq_adapter'
|
30
|
+
|
31
|
+
Then you can extend the class that you will use for communicating with the MQ
|
32
|
+
|
33
|
+
class TownCrier
|
34
|
+
extend Basquiat::Base
|
35
|
+
end
|
36
|
+
|
37
|
+
From here you can publish events to the queue
|
38
|
+
|
39
|
+
TownCrier.publish('some.nifty.event', {a: 'hash', of: 'values'})
|
40
|
+
|
41
|
+
And you can subscribe to one or more events using a proc that will get called when the message is received:
|
42
|
+
|
43
|
+
class TownCrier
|
44
|
+
extend Basquiat::Base
|
45
|
+
|
46
|
+
subscribe_to 'some.nifty.event', ->(msg) { msg.fetch(:of, '').upcase }
|
47
|
+
end
|
48
|
+
|
49
|
+
## Configuration
|
50
|
+
|
51
|
+
You can setup Basquiat using the configure method. This method will yield a Configuration object:
|
52
|
+
|
53
|
+
Basquiat.configure do |config|
|
54
|
+
config.exchange_name = 'my_exchange'
|
55
|
+
end
|
56
|
+
|
57
|
+
The available options are:
|
58
|
+
|
59
|
+
- config_file= Receive a path to an YAML file (example here)
|
60
|
+
- queue_name= The default queue name
|
61
|
+
- exchange_name= The default exchange name
|
62
|
+
- environment= Forces the environment to something other than the value of BASQUIAT_ENV
|
63
|
+
- logger= The logger to be used. Defaults to a null logger.
|
64
|
+
|
65
|
+
The configuration can be reset using the Basquiat.reset method.
|
66
|
+
|
67
|
+
Yaml File configuration example:
|
68
|
+
|
69
|
+
test: #environment
|
70
|
+
exchange_name: 'my.test_exchange' #required
|
71
|
+
queue_name: 'my.nice_queue' #required
|
72
|
+
default_adapter: Basquiat::Adapters::Test #it will overwrite the adapter on all classes that extend Basquiat::Base
|
73
|
+
adapter_options: #Adapter specific options
|
74
|
+
:servers:
|
75
|
+
-
|
76
|
+
:host: 'localhost'
|
77
|
+
:port: '5672'
|
78
|
+
development: #full example of the RabbitMq options
|
79
|
+
exchange_name: 'my.exchange'
|
80
|
+
queue_name: 'my.queue'
|
81
|
+
default_adapter: Basquiat::Adapters::RabbitMq
|
82
|
+
adapter_options:
|
83
|
+
:servers:
|
84
|
+
-
|
85
|
+
:host: 'localhost'
|
86
|
+
:port: '5672'
|
87
|
+
:failover:
|
88
|
+
:default_timeout: 5
|
89
|
+
:max_retries: 5
|
90
|
+
:publisher:
|
91
|
+
:confirm: true
|
92
|
+
:persistent: true
|
93
|
+
:auth:
|
94
|
+
:user: 'guest'
|
95
|
+
:password: 'guest'
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
RuboCop::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
task default: :spec
|
9
|
+
|
10
|
+
desc 'Loads IRB with the gem already required'
|
11
|
+
task :console do
|
12
|
+
system 'irb -I./lib -rbasquiat'
|
13
|
+
end
|
data/basquiat.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'basquiat/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'basquiat'
|
8
|
+
spec.version = Basquiat::VERSION
|
9
|
+
spec.authors = ['Marcello "mereghost" Rocha']
|
10
|
+
spec.email = %w(marcello.rocha@gmail.com.br)
|
11
|
+
spec.description = <<EOD
|
12
|
+
Basquiat is a library that intends to abstract all the complexity of working with message queues
|
13
|
+
EOD
|
14
|
+
spec.summary = 'A pluggable library that aims to hide message queue complexity'
|
15
|
+
spec.homepage = 'http://www.vagas.com.br/'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($RS)
|
19
|
+
spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
21
|
+
spec.require_paths = %w(lib)
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'guard'
|
27
|
+
spec.add_development_dependency 'guard-bundler'
|
28
|
+
spec.add_development_dependency 'guard-rspec'
|
29
|
+
spec.add_development_dependency 'guard-rubocop'
|
30
|
+
spec.add_development_dependency 'bunny'
|
31
|
+
spec.add_development_dependency 'stomp'
|
32
|
+
spec.add_development_dependency 'yajl-ruby'
|
33
|
+
spec.add_development_dependency 'simplecov'
|
34
|
+
spec.add_development_dependency 'metric_fu'
|
35
|
+
spec.add_development_dependency 'rubocop'
|
36
|
+
|
37
|
+
spec.add_dependency 'multi_json'
|
38
|
+
spec.add_dependency 'naught'
|
39
|
+
end
|
data/docker/Dockerfile
ADDED
data/docker-compose.yml
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Basquiat
|
2
|
+
module Adapters
|
3
|
+
# Base implementation for an adapter
|
4
|
+
module Base
|
5
|
+
using Basquiat::HashRefinements
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@options = base_options
|
9
|
+
@procs = {}
|
10
|
+
@retries = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
# Used to set the options for the adapter. It is merged in
|
14
|
+
# to the default_options hash.
|
15
|
+
# @param [Hash] opts an adapter dependant hash of options
|
16
|
+
def adapter_options(opts)
|
17
|
+
@options.deep_merge(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Default options for the adapter
|
21
|
+
# @return [Hash]
|
22
|
+
def base_options
|
23
|
+
default_options.merge(Basquiat.configuration.adapter_options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def default_options
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_config
|
31
|
+
end
|
32
|
+
|
33
|
+
def publish
|
34
|
+
end
|
35
|
+
|
36
|
+
def subscribe_to
|
37
|
+
end
|
38
|
+
|
39
|
+
def disconnect
|
40
|
+
end
|
41
|
+
|
42
|
+
def disconnected?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :procs, :options
|
48
|
+
|
49
|
+
def logger
|
50
|
+
Basquiat.configuration.logger
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
|
3
|
+
module Basquiat
|
4
|
+
module Adapters
|
5
|
+
# The RabbitMQ adapter for Basquiat
|
6
|
+
class RabbitMq
|
7
|
+
include Basquiat::Adapters::Base
|
8
|
+
|
9
|
+
def default_options
|
10
|
+
{ failover: { default_timeout: 5, max_retries: 5 },
|
11
|
+
servers: [{ host: 'localhost', port: 5672 }],
|
12
|
+
queue: { name: Basquiat.configuration.queue_name, options: { durable: true } },
|
13
|
+
exchange: { name: Basquiat.configuration.exchange_name, options: { durable: true } },
|
14
|
+
publisher: { confirm: true, persistent: false },
|
15
|
+
auth: { user: 'guest', password: 'guest' } }
|
16
|
+
end
|
17
|
+
|
18
|
+
def subscribe_to(event_name, proc)
|
19
|
+
procs[event_name] = proc
|
20
|
+
end
|
21
|
+
|
22
|
+
def publish(event, message, persistent: options[:publisher][:persistent])
|
23
|
+
with_network_failure_handler do
|
24
|
+
channel.confirm_select if options[:publisher][:confirm]
|
25
|
+
exchange.publish(Basquiat::Json.encode(message), routing_key: event)
|
26
|
+
disconnect unless persistent
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def listen(block: true)
|
31
|
+
with_network_failure_handler do
|
32
|
+
procs.keys.each { |key| bind_queue(key) }
|
33
|
+
queue.subscribe(block: block) do |di, _, msg|
|
34
|
+
message = Basquiat::Json.decode(msg)
|
35
|
+
procs[di.routing_key].call(message)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def connect
|
41
|
+
with_network_failure_handler do
|
42
|
+
connection.start
|
43
|
+
current_server[:retries] = 0
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def connection_uri
|
48
|
+
current_server_uri
|
49
|
+
end
|
50
|
+
|
51
|
+
def disconnect
|
52
|
+
connection.close_all_channels
|
53
|
+
connection.close
|
54
|
+
reset_connection
|
55
|
+
end
|
56
|
+
|
57
|
+
def connected?
|
58
|
+
@connection
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def with_network_failure_handler
|
63
|
+
yield if block_given?
|
64
|
+
rescue Bunny::ConnectionForced, Bunny::TCPConnectionFailed, Bunny::NetworkFailure => error
|
65
|
+
if current_server.fetch(:retries, 0) <= failover_opts[:max_retries]
|
66
|
+
handle_network_failures
|
67
|
+
retry
|
68
|
+
else
|
69
|
+
raise(error)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def failover_opts
|
74
|
+
options[:failover]
|
75
|
+
end
|
76
|
+
|
77
|
+
def bind_queue(event_name)
|
78
|
+
queue.bind(exchange, routing_key: event_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def reset_connection
|
82
|
+
@connection, @channel, @exchange, @queue = nil, nil, nil, nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def rotate_servers
|
86
|
+
return unless options[:servers].any? { |server| server.fetch(:retries, 0) < failover_opts[:max_retries] }
|
87
|
+
options[:servers].rotate!
|
88
|
+
end
|
89
|
+
|
90
|
+
def handle_network_failures
|
91
|
+
logger.warn "[WARN] Handling connection to #{current_server_uri}"
|
92
|
+
retries = current_server.fetch(:retries, 0)
|
93
|
+
current_server[:retries] = retries + 1
|
94
|
+
if retries < failover_opts[:max_retries]
|
95
|
+
logger.warn("[WARN] Connection failed retrying in #{failover_opts[:default_timeout]} seconds")
|
96
|
+
sleep(failover_opts[:default_timeout])
|
97
|
+
else
|
98
|
+
rotate_servers
|
99
|
+
end
|
100
|
+
reset_connection
|
101
|
+
end
|
102
|
+
|
103
|
+
def connection
|
104
|
+
@connection ||= Bunny.new(current_server_uri)
|
105
|
+
end
|
106
|
+
|
107
|
+
def channel
|
108
|
+
connect
|
109
|
+
@channel ||= connection.create_channel
|
110
|
+
end
|
111
|
+
|
112
|
+
def queue
|
113
|
+
@queue ||= channel.queue(options[:queue][:name], options[:queue][:options])
|
114
|
+
end
|
115
|
+
|
116
|
+
def exchange
|
117
|
+
@exchange ||= channel.topic(options[:exchange][:name], options[:exchange][:options])
|
118
|
+
end
|
119
|
+
|
120
|
+
def current_server
|
121
|
+
options[:servers].first
|
122
|
+
end
|
123
|
+
|
124
|
+
def current_server_uri
|
125
|
+
auth = current_server[:auth] || options[:auth]
|
126
|
+
"amqp://#{auth[:user]}:#{auth[:password]}@#{current_server[:host]}:#{current_server[:port]}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Basquiat
|
2
|
+
module Adapters
|
3
|
+
# An adapter to be used in testing
|
4
|
+
class Test
|
5
|
+
include Basquiat::Adapters::Base
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def events
|
9
|
+
@events ||= Hash.new { |hash, key| hash[key] = [] }
|
10
|
+
end
|
11
|
+
|
12
|
+
def clean
|
13
|
+
@events.clear if @events
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :options
|
18
|
+
|
19
|
+
def default_options
|
20
|
+
@event_names = []
|
21
|
+
{ host: '127.0.0.1', port: 123_456, durable: true }
|
22
|
+
end
|
23
|
+
|
24
|
+
def publish(event, message, _single_message = true)
|
25
|
+
self.class.events[event] << Basquiat::Json.encode(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
def events(key)
|
29
|
+
self.class.events[key]
|
30
|
+
end
|
31
|
+
|
32
|
+
def subscribe_to(event_name, proc)
|
33
|
+
@event_names << event_name
|
34
|
+
procs[event_name] = proc
|
35
|
+
end
|
36
|
+
|
37
|
+
def listen(*)
|
38
|
+
event = subscribed_event
|
39
|
+
msg = self.class.events[event].shift
|
40
|
+
msg ? procs[event].call(Basquiat::Json.decode(msg)) : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def subscribed_event
|
46
|
+
event = @event_names.first
|
47
|
+
@event_names.rotate!
|
48
|
+
event
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Basquiat
|
4
|
+
# base module extend the classes that will use the event infrastructure
|
5
|
+
module Base
|
6
|
+
class << self
|
7
|
+
def extended(klass)
|
8
|
+
descendants.push klass
|
9
|
+
end
|
10
|
+
|
11
|
+
def descendants
|
12
|
+
@descendants ||= []
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def reload_adapter_from_configuration
|
17
|
+
@adapter = Kernel.const_get(Basquiat.configuration.default_adapter).new
|
18
|
+
@adapter.adapter_options Basquiat.configuration.adapter_options
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def event_adapter=(adapter)
|
23
|
+
@adapter = adapter.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def adapter
|
27
|
+
@adapter ||= Kernel.const_get(Basquiat.configuration.default_adapter).new
|
28
|
+
end
|
29
|
+
|
30
|
+
def adapter_options(opts = Basquiat.configuration.adapter_options)
|
31
|
+
adapter.adapter_options(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
def publish(event, message)
|
35
|
+
adapter.publish(event, message)
|
36
|
+
end
|
37
|
+
|
38
|
+
def subscribe_to(event_name, proc)
|
39
|
+
proc = make_callable(proc)
|
40
|
+
adapter.subscribe_to(event_name, proc)
|
41
|
+
end
|
42
|
+
|
43
|
+
def disconnect
|
44
|
+
adapter.disconnect
|
45
|
+
end
|
46
|
+
|
47
|
+
def connected?
|
48
|
+
adapter.connected?
|
49
|
+
end
|
50
|
+
|
51
|
+
def listen(block: true)
|
52
|
+
adapter.listen(block: block)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def make_callable(proc)
|
58
|
+
return proc if proc.respond_to? :call
|
59
|
+
method(proc)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Basquiat
|
2
|
+
class Railtie < ::Rails::Railtie
|
3
|
+
initializer 'load_basquiat_configuration' do
|
4
|
+
ENV['BASQUIAT_ENV'] = Rails.env
|
5
|
+
Basquiat.configure do |config|
|
6
|
+
config.config_file = Rails.root + 'config/basquiat.yml'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
config.after_initialize do
|
11
|
+
Basquiat.configuration.reload_classes
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'basquiat/support/hash_refinements'
|
2
|
+
require 'naught'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Basquiat
|
6
|
+
DefaultLogger = Naught.build { |config| config.mimic Logger }
|
7
|
+
|
8
|
+
class Configuration
|
9
|
+
using HashRefinements
|
10
|
+
|
11
|
+
attr_writer :queue_name, :exchange_name, :logger, :environment
|
12
|
+
|
13
|
+
def queue_name
|
14
|
+
@queue_name || 'basquiat.queue'
|
15
|
+
end
|
16
|
+
|
17
|
+
def exchange_name
|
18
|
+
@exchange_name || 'basquiat.exchange'
|
19
|
+
end
|
20
|
+
|
21
|
+
def logger
|
22
|
+
@logger || DefaultLogger.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def environment
|
26
|
+
(@environment || ENV['BASQUIAT_ENV'] || 'development').to_sym
|
27
|
+
end
|
28
|
+
|
29
|
+
def config_file=(path)
|
30
|
+
load_yaml(path)
|
31
|
+
setup_basic_options
|
32
|
+
end
|
33
|
+
|
34
|
+
def adapter_options
|
35
|
+
config.fetch(:adapter_options) { Hash.new }
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_adapter
|
39
|
+
config.fetch(:default_adapter) { Basquiat::Adapter::Test }
|
40
|
+
end
|
41
|
+
|
42
|
+
def reload_classes
|
43
|
+
Basquiat::Base.descendants.each do |klass|
|
44
|
+
klass.reload_adapter_from_configuration
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def config
|
50
|
+
@yaml.fetch(environment)
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_yaml(path)
|
54
|
+
@yaml = YAML.load(ERB.new(IO.readlines(path).join).result).symbolize_keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def setup_basic_options
|
58
|
+
@queue_name ||= config.fetch(:queue_name) { 'basquiat.exchange' }
|
59
|
+
@exchange_name ||= config.fetch(:exchange_name) { 'basquiat.queue' }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|