bi-frost 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -9
- data/lib/bifrost.rb +6 -1
- data/lib/bifrost/bus.rb +1 -1
- data/lib/bifrost/exceptions/message_delivery_error.rb +6 -0
- data/lib/bifrost/message.rb +20 -5
- data/lib/bifrost/topic.rb +13 -2
- data/lib/bifrost/version.rb +2 -2
- data/spec/bifrost/bus_spec.rb +1 -1
- data/spec/bifrost/message_spec.rb +34 -12
- data/spec/bifrost/topic_spec.rb +36 -18
- data/spec/bifrost/worker_spec.rb +1 -2
- data/spec/spec_helper.rb +12 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c7ef1811b993361b82e924590621cd7acbcd263
|
4
|
+
data.tar.gz: b365ca8848c557b296fbef2ad330746e70472aa5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 933abde1218ef15a966004dcded976de5076fb5eb7b4e97fa316dc957e55e8009e1058758a1f6c4cb78649a5e5c522238bd8a6e9387e340714dff541a4d49fd7
|
7
|
+
data.tar.gz: c0b8558f903e565ce019cdc833e9b99a604ceb1d144653b82a7a4152a6b350b21fa1eb287c992dce98836e60eae8e179b155dee61d11d977d2c7b7cfcc5f4b67
|
data/README.md
CHANGED
@@ -56,31 +56,29 @@ subscriber = Bifrost::Subscriber.new('new_subscriber')
|
|
56
56
|
topic.add_subscriber(subscriber)
|
57
57
|
```
|
58
58
|
|
59
|
-
Each topic can only have a unique list of subscribers, a subscriber cannot be added to a topic more than once. When a subscriber is added to
|
60
|
-
a topic this function will return a true or false indicating success of the add.
|
59
|
+
Each topic can only have a unique list of subscribers, a subscriber cannot be added to a topic more than once. When a subscriber is added to a topic this function will return a true or false indicating success of the add.
|
61
60
|
|
62
61
|
To post a message to a topic;
|
63
62
|
|
64
63
|
```ruby
|
65
64
|
topic = Bifrost::Topic.new('topic_name')
|
66
65
|
message = Bifrost::Message.new(content: 'some data')
|
67
|
-
message.
|
66
|
+
message.publish(topic)
|
68
67
|
```
|
69
68
|
|
70
|
-
This function returns a `true` or `false` indicating the success of the message delivery. This method is synchronous. Each message has an
|
71
|
-
identifier which gets sets upon successful delivery only.
|
69
|
+
This function returns a `true` or `false` indicating the success of the message delivery. This method is synchronous. Each message has an identifier which gets sets upon successful delivery only.
|
72
70
|
|
73
71
|
A message can also be optionally published with a subject;
|
74
72
|
|
75
73
|
```ruby
|
76
74
|
topic = Bifrost::Topic.new('topic_name')
|
77
75
|
message = Bifrost::Message.new(content: 'some data', 'message subject')
|
78
|
-
message.
|
76
|
+
message.publish(topic)
|
79
77
|
```
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
hoping to add at some point. In the Bifrost each actor is referred to as a `worker`. A worker is designed to receive
|
79
|
+
An alternative method named `publish!` also exists. This method raises an error is a message cannot be delivered. The error raised is `Bifrost::Exceptions::MessageDeliveryError`. If the message is successfully delivered with the method `publish!`, the messages `UUID` is returned in the call.
|
80
|
+
|
81
|
+
Subscribers in the Bifrost are [actors](http://http://doc.akka.io/docs/akka/2.4/general/actors.html), these actors run in their own threads. At present the Bifrost does not support thread pools, this is something we are investigating and are hoping to add at some point. In the Bifrost each actor is referred to as a `worker`. A worker is designed to receive
|
84
82
|
messages published to a particular topic with a specific subscriber in mind (refer to the fan-out comment earlier).
|
85
83
|
|
86
84
|
Workers are added to the Bifrost via the manager. The manager is what activates the workers in the Bifrost environment.
|
data/lib/bifrost.rb
CHANGED
@@ -5,11 +5,16 @@ require 'bifrost/topic'
|
|
5
5
|
require 'bifrost/subscriber'
|
6
6
|
require 'bifrost/manager'
|
7
7
|
require 'bifrost/worker'
|
8
|
+
|
9
|
+
require 'bifrost/exceptions/duplicate_subscriber_error'
|
10
|
+
require 'bifrost/exceptions/invalid_worker_definition_error'
|
11
|
+
require 'bifrost/exceptions/message_delivery_error'
|
12
|
+
require 'bifrost/exceptions/unsupported_lambda_error'
|
13
|
+
|
8
14
|
require 'celluloid'
|
9
15
|
|
10
16
|
# Bifrost is a pub/sub gem built on top of the Azure MessageBus system
|
11
17
|
module Bifrost
|
12
|
-
|
13
18
|
# Workers and the infrastructure can log using the standard level of granularity affored to any
|
14
19
|
# standard logger (i.e. info, debug, error levels etc)
|
15
20
|
def self.logger=(log_provider)
|
data/lib/bifrost/bus.rb
CHANGED
data/lib/bifrost/message.rb
CHANGED
@@ -17,23 +17,38 @@ module Bifrost
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# A message can be posted to a particular topic
|
20
|
-
def
|
20
|
+
def publish(topic)
|
21
21
|
if topic.exists?
|
22
|
-
|
23
|
-
@bus.interface.send_topic_message(topic.name, message)
|
24
|
-
update_message_state_to_delivered(message)
|
22
|
+
send_message(topic, create_brokered_message)
|
25
23
|
true
|
26
24
|
else
|
27
25
|
false
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
29
|
+
# A message can be posted to a particular topic, if the message is succssfully delivered
|
30
|
+
# we return a unique identifier for the message
|
31
|
+
def publish!(topic)
|
32
|
+
if topic.exists?
|
33
|
+
send_message(topic, create_brokered_message)
|
34
|
+
message_id
|
35
|
+
else
|
36
|
+
raise Bifrost::Exceptions::MessageDeliveryError, "Could not post message to #{topic}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
31
40
|
private
|
32
41
|
|
42
|
+
# Create the message and attempt to deliver It
|
43
|
+
def send_message(topic, message)
|
44
|
+
@bus.interface.send_topic_message(topic.name, message)
|
45
|
+
update_message_state_to_delivered(message)
|
46
|
+
end
|
47
|
+
|
33
48
|
# Create the brokered message
|
34
49
|
def create_brokered_message
|
35
50
|
message = Azure::ServiceBus::BrokeredMessage.new(subject, message: body)
|
36
|
-
message.correlation_id = SecureRandom.
|
51
|
+
message.correlation_id = SecureRandom.uuid
|
37
52
|
message
|
38
53
|
end
|
39
54
|
|
data/lib/bifrost/topic.rb
CHANGED
@@ -33,6 +33,13 @@ module Bifrost
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
# This method returns a list of subscribers currently defined on the topic
|
37
|
+
def subscribers
|
38
|
+
@bus.interface.list_subscriptions(name).map do |s|
|
39
|
+
Subscriber.new(s.name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
36
43
|
# A new subscriber can be added to a topic
|
37
44
|
def add_subscriber(subscriber)
|
38
45
|
if exists?
|
@@ -63,8 +70,8 @@ module Bifrost
|
|
63
70
|
end
|
64
71
|
end
|
65
72
|
|
66
|
-
def ==(
|
67
|
-
|
73
|
+
def ==(other)
|
74
|
+
name == other.name && self.class == other.class
|
68
75
|
end
|
69
76
|
|
70
77
|
# Topics are self aware, and know if they exist or not, but only with the help
|
@@ -72,5 +79,9 @@ module Bifrost
|
|
72
79
|
def exists?
|
73
80
|
@bus.topic_exists?(self)
|
74
81
|
end
|
82
|
+
|
83
|
+
def to_s
|
84
|
+
name
|
85
|
+
end
|
75
86
|
end
|
76
87
|
end
|
data/lib/bifrost/version.rb
CHANGED
@@ -5,11 +5,11 @@ module Bifrost
|
|
5
5
|
MAJOR_VERSION = 0
|
6
6
|
|
7
7
|
# The minor version of Bifrost, updated for new feature releases.
|
8
|
-
MINOR_VERSION =
|
8
|
+
MINOR_VERSION = 2
|
9
9
|
|
10
10
|
# The patch version of Bifrost, updated only for bug fixes from the last
|
11
11
|
# feature release.
|
12
|
-
PATCH_VERSION =
|
12
|
+
PATCH_VERSION = 0
|
13
13
|
|
14
14
|
# The full version as a string.
|
15
15
|
VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{PATCH_VERSION}".freeze
|
data/spec/bifrost/bus_spec.rb
CHANGED
@@ -8,7 +8,8 @@ describe Bifrost::Message do
|
|
8
8
|
it { is_expected.to respond_to(:status) }
|
9
9
|
it { is_expected.to respond_to(:message_id) }
|
10
10
|
it { is_expected.to respond_to(:body) }
|
11
|
-
it { is_expected.to respond_to(:
|
11
|
+
it { is_expected.to respond_to(:publish) }
|
12
|
+
it { is_expected.to respond_to(:publish!) }
|
12
13
|
|
13
14
|
context 'which is initialized' do
|
14
15
|
it 'should be in an undelivered status' do
|
@@ -21,18 +22,39 @@ describe Bifrost::Message do
|
|
21
22
|
expect(new_message).to_not be_nil
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
describe 'publish' do
|
26
|
+
it 'should publish to a valid topic' do
|
27
|
+
topic = Bifrost::Topic.new('valid-topic')
|
28
|
+
topic.save
|
29
|
+
topic.add_subscriber(Bifrost::Subscriber.new('new_subscriber'))
|
30
|
+
expect(message.publish(topic)).to be_truthy
|
31
|
+
expect(message.status).to eq(:delivered)
|
32
|
+
expect(message.message_id).not_to be_nil
|
33
|
+
topic.delete
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should not be postable to an invalid topic' do
|
37
|
+
topic = Bifrost::Topic.new('invalid-topic') # A topic that is neither saved, nor with no subscribers is semantically invalid
|
38
|
+
expect(message.publish(topic)).to be_falsey
|
39
|
+
end
|
32
40
|
end
|
33
41
|
|
34
|
-
|
35
|
-
|
36
|
-
|
42
|
+
describe 'publish!' do
|
43
|
+
it 'should publish to a valid topic and return the message id' do
|
44
|
+
topic = Bifrost::Topic.new('valid-topic')
|
45
|
+
topic.save
|
46
|
+
topic.add_subscriber(Bifrost::Subscriber.new('new_subscriber'))
|
47
|
+
response = message.publish!(topic)
|
48
|
+
expect(response).not_to be_nil
|
49
|
+
expect(message.status).to eq(:delivered)
|
50
|
+
expect(message.message_id).not_to be_nil
|
51
|
+
expect(response).to eq(message.message_id)
|
52
|
+
topic.delete
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should raise an exception upon publish to an invalid topic' do
|
56
|
+
topic = Bifrost::Topic.new('invalid-topic')
|
57
|
+
expect { message.publish!(topic) }.to raise_error(Bifrost::Exceptions::MessageDeliveryError)
|
58
|
+
end
|
37
59
|
end
|
38
60
|
end
|
data/spec/bifrost/topic_spec.rb
CHANGED
@@ -15,6 +15,15 @@ describe Bifrost::Topic do
|
|
15
15
|
expect { invalid_topic.save }.to raise_error(TypeError)
|
16
16
|
end
|
17
17
|
|
18
|
+
it 'should have a friendly name' do
|
19
|
+
expect(topic.to_s).to eq('topic_name')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should not accept names with spaces in them' do
|
23
|
+
invalid_topic = Bifrost::Topic.new('topic name')
|
24
|
+
expect { invalid_topic.save }.to raise_error(URI::InvalidURIError)
|
25
|
+
end
|
26
|
+
|
18
27
|
describe 'equality' do
|
19
28
|
it 'should return true for the same object' do
|
20
29
|
expect(topic).to eq(topic)
|
@@ -32,10 +41,13 @@ describe Bifrost::Topic do
|
|
32
41
|
end
|
33
42
|
|
34
43
|
context 'for an undefined topic' do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
|
45
|
+
describe 'save' do
|
46
|
+
it 'should persist the topic and return a binary value' do
|
47
|
+
new_topic = Bifrost::Topic.new('new_topic_name')
|
48
|
+
expect(new_topic.save).to be_truthy
|
49
|
+
expect(new_topic.delete).to be_truthy
|
50
|
+
end
|
39
51
|
end
|
40
52
|
|
41
53
|
it 'should return false for delete' do
|
@@ -56,16 +68,8 @@ describe Bifrost::Topic do
|
|
56
68
|
context 'for a defined topic' do
|
57
69
|
let(:new_topic) { Bifrost::Topic.new('test_donotdelete') }
|
58
70
|
|
59
|
-
before(:
|
60
|
-
|
61
|
-
tp = Bifrost::Topic.new('test_donotdelete')
|
62
|
-
tp.save unless bus.topic_exists?(tp)
|
63
|
-
end
|
64
|
-
|
65
|
-
after(:all) do
|
66
|
-
bus = Bifrost::Bus.new
|
67
|
-
tp = Bifrost::Topic.new('test_donotdelete')
|
68
|
-
tp.delete if bus.topic_exists?(tp)
|
71
|
+
before(:each) do
|
72
|
+
new_topic.save
|
69
73
|
end
|
70
74
|
|
71
75
|
it 'should return false for save' do
|
@@ -88,10 +92,24 @@ describe Bifrost::Topic do
|
|
88
92
|
expect(new_topic.add_subscriber(subscriber)).to be_truthy
|
89
93
|
expect(new_topic.add_subscriber(subscriber)).to be_falsey
|
90
94
|
end
|
91
|
-
end
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
+
context 'with no subscribers' do
|
97
|
+
it 'should return no subscribers' do
|
98
|
+
expect(new_topic.subscribers).to be_empty
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with subscribers' do
|
103
|
+
before(:each) do
|
104
|
+
subscriber_a = Bifrost::Subscriber.new('new_subscriber_a')
|
105
|
+
subscriber_b = Bifrost::Subscriber.new('new_subscriber_b')
|
106
|
+
new_topic.add_subscriber(subscriber_a)
|
107
|
+
new_topic.add_subscriber(subscriber_b)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should return a list of it\'s subscribers' do
|
111
|
+
expect(new_topic.subscribers.size).to eq(2)
|
112
|
+
end
|
113
|
+
end
|
96
114
|
end
|
97
115
|
end
|
data/spec/bifrost/worker_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'bifrost/exceptions/unsupported_lambda_error'
|
3
2
|
require 'bifrost'
|
4
3
|
|
5
4
|
describe Bifrost::Worker do
|
@@ -33,7 +32,7 @@ describe Bifrost::Worker do
|
|
33
32
|
subscriber = Bifrost::Subscriber.new('subscriber')
|
34
33
|
topic.add_subscriber(subscriber)
|
35
34
|
msg = Bifrost::Message.new([item1: { data: 2 }, item2: { more_data: 3 }])
|
36
|
-
msg.
|
35
|
+
msg.publish(topic)
|
37
36
|
expect(msg.status).to eq(:delivered)
|
38
37
|
expect(msg.message_id).not_to be_nil
|
39
38
|
worker.async.run
|
data/spec/spec_helper.rb
CHANGED
@@ -44,4 +44,16 @@ RSpec.configure do |config|
|
|
44
44
|
# inherited by the metadata hash of host groups and examples, rather than
|
45
45
|
# triggering implicit auto-inclusion in groups with matching metadata.
|
46
46
|
config.shared_context_metadata_behavior = :apply_to_host_groups
|
47
|
+
|
48
|
+
# Clear the bifrost before running each spec
|
49
|
+
config.before(:example) do
|
50
|
+
bus = Bifrost::Bus.new
|
51
|
+
bus.topics.each(&:delete)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Clear the bifrost after running specs
|
55
|
+
config.after(:suite) do
|
56
|
+
bus = Bifrost::Bus.new
|
57
|
+
bus.topics.each(&:delete)
|
58
|
+
end
|
47
59
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bi-frost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shirren Premaratne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: azure
|
@@ -164,6 +164,7 @@ files:
|
|
164
164
|
- lib/bifrost/entity.rb
|
165
165
|
- lib/bifrost/exceptions/duplicate_subscriber_error.rb
|
166
166
|
- lib/bifrost/exceptions/invalid_worker_definition_error.rb
|
167
|
+
- lib/bifrost/exceptions/message_delivery_error.rb
|
167
168
|
- lib/bifrost/exceptions/unsupported_lambda_error.rb
|
168
169
|
- lib/bifrost/manager.rb
|
169
170
|
- lib/bifrost/message.rb
|