multiple_man 0.3.2 → 0.4.0
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/lib/multiple_man.rb +2 -1
- data/lib/multiple_man/listener.rb +12 -5
- data/lib/multiple_man/mixins/publisher.rb +15 -3
- data/lib/multiple_man/model_publisher.rb +21 -10
- data/lib/multiple_man/routing_key.rb +7 -3
- data/lib/multiple_man/seeder_listener.rb +12 -0
- data/lib/multiple_man/subscribers/base.rb +7 -3
- data/lib/multiple_man/subscribers/model_subscriber.rb +3 -2
- data/lib/multiple_man/tasks/worker.rake +11 -2
- data/lib/multiple_man/version.rb +1 -1
- data/spec/connection_spec.rb +2 -2
- data/spec/model_publisher_spec.rb +6 -6
- data/spec/publisher_spec.rb +4 -4
- data/spec/routing_key_spec.rb +7 -2
- data/spec/seeder_listener_spec.rb +21 -0
- data/spec/subscribers/base_spec.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b69cb35c812dfa3b4814a81a6cdca0aaa495afc
|
4
|
+
data.tar.gz: ea18e5f3984487b6f7278febc96269612b7038b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c1b1b58da01c48d575aea0ce54eac633e9996fed67a3f8860396596c721f122cdb92175823b2bb528d403fb7fb05e7748c55c14f1ead348fd32e2f6ce79a19c
|
7
|
+
data.tar.gz: 93b9be1ffd2e8a8427c35791ad87c76ef4e3a3b4f401cf8150b4a048797af2e0a8c4758826c8aa24b1d3fe120c0c34cc12d3e2b5e04b4ed019fdae1f23e3b3f3
|
data/lib/multiple_man.rb
CHANGED
@@ -14,6 +14,7 @@ module MultipleMan
|
|
14
14
|
require 'multiple_man/connection'
|
15
15
|
require 'multiple_man/routing_key'
|
16
16
|
require 'multiple_man/listener'
|
17
|
+
require 'multiple_man/seeder_listener'
|
17
18
|
require 'multiple_man/model_populator'
|
18
19
|
require 'multiple_man/identity'
|
19
20
|
|
@@ -36,4 +37,4 @@ module MultipleMan
|
|
36
37
|
raise ex
|
37
38
|
end
|
38
39
|
end
|
39
|
-
end
|
40
|
+
end
|
@@ -25,8 +25,8 @@ module MultipleMan
|
|
25
25
|
attr_accessor :subscription
|
26
26
|
|
27
27
|
def listen
|
28
|
-
MultipleMan.logger.info "Listening for #{subscription.klass} with routing key #{
|
29
|
-
queue.bind(connection.topic, routing_key:
|
28
|
+
MultipleMan.logger.info "Listening for #{subscription.klass} with routing key #{routing_key}."
|
29
|
+
queue.bind(connection.topic, routing_key: routing_key).subscribe do |delivery_info, meta_data, payload|
|
30
30
|
process_message(delivery_info, payload)
|
31
31
|
end
|
32
32
|
end
|
@@ -34,8 +34,7 @@ module MultipleMan
|
|
34
34
|
def process_message(delivery_info, payload)
|
35
35
|
MultipleMan.logger.info "Processing message for #{delivery_info.routing_key}."
|
36
36
|
begin
|
37
|
-
operation
|
38
|
-
subscription.send(operation, JSON.parse(payload).with_indifferent_access)
|
37
|
+
subscription.send(operation(delivery_info), JSON.parse(payload).with_indifferent_access)
|
39
38
|
rescue Exception => ex
|
40
39
|
MultipleMan.logger.error " Error - #{ex.message}\n\n#{ex.backtrace}"
|
41
40
|
MultipleMan.error(ex)
|
@@ -44,10 +43,18 @@ module MultipleMan
|
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
46
|
+
def operation(delivery_info)
|
47
|
+
delivery_info.routing_key.split(".").last
|
48
|
+
end
|
49
|
+
|
47
50
|
def queue
|
48
51
|
connection.queue(subscription.queue_name, durable: true, auto_delete: false)
|
49
52
|
end
|
50
53
|
|
54
|
+
def routing_key
|
55
|
+
subscription.routing_key
|
56
|
+
end
|
57
|
+
|
51
58
|
private
|
52
59
|
|
53
60
|
def connection
|
@@ -55,4 +62,4 @@ module MultipleMan
|
|
55
62
|
end
|
56
63
|
|
57
64
|
end
|
58
|
-
end
|
65
|
+
end
|
@@ -2,13 +2,25 @@ module MultipleMan
|
|
2
2
|
module Publisher
|
3
3
|
def Publisher.included(base)
|
4
4
|
base.extend(ClassMethods)
|
5
|
+
base.after_commit(on: :create) { |r| r.multiple_man_publish(:create) }
|
6
|
+
base.after_commit(on: :update) { |r| r.multiple_man_publish(:update) }
|
7
|
+
base.after_commit(on: :destroy) { |r| r.multiple_man_publish(:destroy) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def multiple_man_publish(operation=:create)
|
11
|
+
self.class.multiple_man_publisher.publish(self, operation)
|
5
12
|
end
|
6
13
|
|
7
14
|
module ClassMethods
|
15
|
+
|
16
|
+
def multiple_man_publish(operation=:create)
|
17
|
+
multiple_man_publisher.publish(self, operation)
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_accessor :multiple_man_publisher
|
21
|
+
|
8
22
|
def publish(options = {})
|
9
|
-
|
10
|
-
after_commit ModelPublisher.new(:update, options), on: :update
|
11
|
-
after_commit ModelPublisher.new(:destroy, options), on: :destroy
|
23
|
+
self.multiple_man_publisher = ModelPublisher.new(options)
|
12
24
|
end
|
13
25
|
end
|
14
26
|
end
|
@@ -1,25 +1,25 @@
|
|
1
1
|
module MultipleMan
|
2
2
|
class ModelPublisher
|
3
3
|
|
4
|
-
def initialize(
|
5
|
-
self.operation = operation
|
4
|
+
def initialize(options = {})
|
6
5
|
self.options = options
|
7
6
|
end
|
8
7
|
|
9
|
-
def
|
8
|
+
def publish(records, operation=:create)
|
10
9
|
return unless MultipleMan.configuration.enabled
|
11
10
|
|
12
|
-
MultipleMan.logger.info("Publishing #{record}")
|
13
11
|
Connection.connect do |connection|
|
14
|
-
|
12
|
+
all_records(records) do |record|
|
13
|
+
push_record(connection, record, operation)
|
14
|
+
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
attr_accessor :
|
20
|
+
attr_accessor :options
|
21
21
|
|
22
|
-
def push_record(connection, record)
|
22
|
+
def push_record(connection, record, operation)
|
23
23
|
data = record_data(record)
|
24
24
|
routing_key = RoutingKey.new(record_type(record), operation).to_s
|
25
25
|
MultipleMan.logger.debug(" Record Data: #{data} | Routing Key: #{routing_key}")
|
@@ -28,12 +28,23 @@ module MultipleMan
|
|
28
28
|
MultipleMan.error(ex)
|
29
29
|
end
|
30
30
|
|
31
|
+
def all_records(records, &block)
|
32
|
+
if records.respond_to?(:find_each)
|
33
|
+
records.find_each(&block)
|
34
|
+
elsif records.respond_to?(:each)
|
35
|
+
records.each(&block)
|
36
|
+
else
|
37
|
+
yield records
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
31
42
|
def record_type(record)
|
32
43
|
options[:as] || record.class.name
|
33
44
|
end
|
34
45
|
|
35
46
|
def record_data(record)
|
36
|
-
{
|
47
|
+
{
|
37
48
|
id: Identity.new(record, identifier).value,
|
38
49
|
data: serializer(record).as_json
|
39
50
|
}.to_json
|
@@ -56,6 +67,6 @@ module MultipleMan
|
|
56
67
|
def identifier
|
57
68
|
options[:identifier]
|
58
69
|
end
|
59
|
-
|
70
|
+
|
60
71
|
end
|
61
|
-
end
|
72
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module MultipleMan
|
2
2
|
class RoutingKey
|
3
|
-
ALLOWED_OPERATIONS = [:create, :update, :destroy, :"#"]
|
3
|
+
ALLOWED_OPERATIONS = [:create, :update, :destroy, :seed, :"#"]
|
4
4
|
|
5
5
|
def initialize(klass, operation = :"#")
|
6
6
|
self.klass = klass
|
@@ -8,7 +8,11 @@ module MultipleMan
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def to_s
|
11
|
-
|
11
|
+
if operation == :seed
|
12
|
+
"#{topic_name}.#{operation}.#{klass}"
|
13
|
+
else
|
14
|
+
"#{topic_name}.#{klass}.#{operation}"
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
attr_reader :operation
|
@@ -25,4 +29,4 @@ module MultipleMan
|
|
25
29
|
end
|
26
30
|
|
27
31
|
end
|
28
|
-
end
|
32
|
+
end
|
@@ -19,8 +19,12 @@ module MultipleMan::Subscribers
|
|
19
19
|
# noop
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
|
22
|
+
def seed
|
23
|
+
# noop
|
24
|
+
end
|
25
|
+
|
26
|
+
def routing_key(operation = :'#')
|
27
|
+
MultipleMan::RoutingKey.new(klass, operation).to_s
|
24
28
|
end
|
25
29
|
|
26
30
|
def queue_name
|
@@ -31,4 +35,4 @@ module MultipleMan::Subscribers
|
|
31
35
|
|
32
36
|
attr_writer :klass
|
33
37
|
end
|
34
|
-
end
|
38
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module MultipleMan::Subscribers
|
1
|
+
module MultipleMan::Subscribers
|
2
2
|
class ModelSubscriber < Base
|
3
3
|
|
4
4
|
def initialize(klass, options)
|
@@ -15,6 +15,7 @@ module MultipleMan::Subscribers
|
|
15
15
|
end
|
16
16
|
|
17
17
|
alias_method :update, :create
|
18
|
+
alias_method :seed, :create
|
18
19
|
|
19
20
|
def destroy(payload)
|
20
21
|
model = find_model(payload[:id])
|
@@ -30,4 +31,4 @@ module MultipleMan::Subscribers
|
|
30
31
|
attr_writer :klass
|
31
32
|
|
32
33
|
end
|
33
|
-
end
|
34
|
+
end
|
@@ -1,14 +1,23 @@
|
|
1
1
|
namespace :multiple_man do
|
2
2
|
desc "Run multiple man listeners"
|
3
3
|
task :worker => :environment do
|
4
|
+
run_listener(MultipleMan::Listener)
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Run a seeding listener'
|
8
|
+
task seed: :environment do
|
9
|
+
run_listener(MultipleMan::SeederListener)
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_listener(listener)
|
4
13
|
Rails.application.eager_load!
|
5
14
|
|
6
15
|
MultipleMan::Connection.connect do |connection|
|
7
|
-
|
16
|
+
listener.start(connection)
|
8
17
|
|
9
18
|
while(true)
|
10
19
|
sleep 10
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
14
|
-
end
|
23
|
+
end
|
data/lib/multiple_man/version.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe MultipleMan::Connection do
|
|
9
9
|
it "should open a connection and a channel" do
|
10
10
|
mock_bunny.should_receive(:start)
|
11
11
|
Bunny.should_receive(:new).and_return(mock_bunny)
|
12
|
-
mock_bunny.should_receive(:create_channel)
|
12
|
+
mock_bunny.should_receive(:create_channel)
|
13
13
|
|
14
14
|
described_class.connect
|
15
15
|
end
|
@@ -19,4 +19,4 @@ describe MultipleMan::Connection do
|
|
19
19
|
|
20
20
|
its(:topic_name) { should == MultipleMan.configuration.topic_name }
|
21
21
|
|
22
|
-
end
|
22
|
+
end
|
@@ -25,20 +25,20 @@ describe MultipleMan::ModelPublisher do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
subject { described_class.new(
|
28
|
+
subject { described_class.new(fields: [:foo]) }
|
29
29
|
|
30
|
-
describe "
|
30
|
+
describe "publish" do
|
31
31
|
it "should send the jsonified version of the model to the correct routing key" do
|
32
32
|
MultipleMan::AttributeExtractor.any_instance.should_receive(:as_json).and_return({foo: "bar"})
|
33
33
|
topic_stub.should_receive(:publish).with('{"id":"10","data":{"foo":"bar"}}', routing_key: "app.MockObject.create")
|
34
|
-
described_class.new(
|
34
|
+
described_class.new(fields: [:foo]).publish(MockObject.new)
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should call the error handler on error" do
|
38
38
|
ex = Exception.new("Bad stuff happened")
|
39
39
|
topic_stub.stub(:publish) { raise ex }
|
40
40
|
MultipleMan.should_receive(:error).with(ex)
|
41
|
-
described_class.new(
|
41
|
+
described_class.new(fields: [:foo]).publish(MockObject.new)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -51,12 +51,12 @@ describe MultipleMan::ModelPublisher do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
subject { described_class.new(
|
54
|
+
subject { described_class.new(with: MySerializer) }
|
55
55
|
|
56
56
|
it "should get its data from the serializer" do
|
57
57
|
obj = MockObject.new
|
58
58
|
topic_stub.should_receive(:publish).with('{"id":"10","data":{"a":"yes"}}', routing_key: "app.MockObject.create")
|
59
|
-
subject.
|
59
|
+
subject.publish(obj)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
data/spec/publisher_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe MultipleMan::Publisher do
|
|
5
5
|
class << self
|
6
6
|
attr_accessor :subscriber
|
7
7
|
|
8
|
-
def after_commit(subscriber
|
8
|
+
def after_commit(subscriber)
|
9
9
|
self.subscriber = subscriber
|
10
10
|
end
|
11
11
|
end
|
@@ -13,15 +13,15 @@ describe MultipleMan::Publisher do
|
|
13
13
|
include MultipleMan::Publisher
|
14
14
|
|
15
15
|
def save
|
16
|
-
self.
|
16
|
+
self.multiple_man_publish
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "including" do
|
21
21
|
it "should add an after commit hook" do
|
22
22
|
# once for each operation
|
23
|
-
MockClass.should_receive(:after_commit).exactly(3).times
|
24
23
|
MockClass.publish
|
24
|
+
MockClass.multiple_man_publisher.should be_kind_of MultipleMan::ModelPublisher
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -30,7 +30,7 @@ describe MultipleMan::Publisher do
|
|
30
30
|
it "should tell ModelPublisher to publish" do
|
31
31
|
my_mock = MockClass.new
|
32
32
|
mock_publisher = double(MultipleMan::ModelPublisher)
|
33
|
-
MultipleMan::ModelPublisher.any_instance.should_receive(:
|
33
|
+
MultipleMan::ModelPublisher.any_instance.should_receive(:publish).with(my_mock, :create)
|
34
34
|
my_mock.save
|
35
35
|
end
|
36
36
|
end
|
data/spec/routing_key_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe MultipleMan::RoutingKey do
|
3
|
+
describe MultipleMan::RoutingKey do
|
4
4
|
class MockObject
|
5
5
|
end
|
6
6
|
|
@@ -28,6 +28,11 @@ describe MultipleMan::RoutingKey do
|
|
28
28
|
it { should == "app.MockObject.destroy" }
|
29
29
|
end
|
30
30
|
|
31
|
+
context "seeding" do
|
32
|
+
let(:operation) { :seed }
|
33
|
+
it { should == "app.seed.MockObject" }
|
34
|
+
end
|
35
|
+
|
31
36
|
context "not specified" do
|
32
37
|
subject { described_class.new("MockObject").to_s }
|
33
38
|
it { should == "app.MockObject.#" }
|
@@ -51,4 +56,4 @@ describe MultipleMan::RoutingKey do
|
|
51
56
|
end
|
52
57
|
|
53
58
|
end
|
54
|
-
end
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MultipleMan::SeederListener do
|
4
|
+
class MockClass1; end
|
5
|
+
|
6
|
+
let(:connection_stub) { double(MultipleMan::Connection, queue: queue_stub, topic: 'app') }
|
7
|
+
let(:queue_stub) { double(Bunny::Queue, bind: bind_stub) }
|
8
|
+
let(:bind_stub) { double(:bind, subscribe: nil)}
|
9
|
+
|
10
|
+
before { MultipleMan::Listener.stub(:connection).and_return(connection_stub) }
|
11
|
+
|
12
|
+
it 'listens to seed events' do
|
13
|
+
listener = described_class.new(double(MultipleMan::Subscribers::ModelSubscriber,
|
14
|
+
klass: MockClass1,
|
15
|
+
routing_key: "seed.MockClass1",
|
16
|
+
queue_name: "MockClass1"))
|
17
|
+
|
18
|
+
queue_stub.should_receive(:bind).with('app', routing_key: "seed.MockClass1")
|
19
|
+
listener.listen
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multiple_man
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Brunner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- lib/multiple_man/model_publisher.rb
|
120
120
|
- lib/multiple_man/railtie.rb
|
121
121
|
- lib/multiple_man/routing_key.rb
|
122
|
+
- lib/multiple_man/seeder_listener.rb
|
122
123
|
- lib/multiple_man/subscribers/base.rb
|
123
124
|
- lib/multiple_man/subscribers/model_subscriber.rb
|
124
125
|
- lib/multiple_man/subscribers/registry.rb
|
@@ -134,6 +135,7 @@ files:
|
|
134
135
|
- spec/model_publisher_spec.rb
|
135
136
|
- spec/publisher_spec.rb
|
136
137
|
- spec/routing_key_spec.rb
|
138
|
+
- spec/seeder_listener_spec.rb
|
137
139
|
- spec/spec_helper.rb
|
138
140
|
- spec/subscriber_spec.rb
|
139
141
|
- spec/subscribers/base_spec.rb
|
@@ -173,6 +175,7 @@ test_files:
|
|
173
175
|
- spec/model_publisher_spec.rb
|
174
176
|
- spec/publisher_spec.rb
|
175
177
|
- spec/routing_key_spec.rb
|
178
|
+
- spec/seeder_listener_spec.rb
|
176
179
|
- spec/spec_helper.rb
|
177
180
|
- spec/subscriber_spec.rb
|
178
181
|
- spec/subscribers/base_spec.rb
|