bi-frost 0.1.0 → 0.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 +4 -4
- data/lib/bifrost.rb +9 -4
- data/lib/bifrost/manager.rb +40 -15
- data/lib/bifrost/version.rb +4 -4
- data/lib/bifrost/worker.rb +15 -9
- data/spec/bifrost/manager_spec.rb +1 -1
- data/spec/bifrost/topic_spec.rb +2 -2
- data/spec/bifrost/worker_spec.rb +8 -3
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 363ad309cb14525b8eff19191a79063afbd1dafa
|
4
|
+
data.tar.gz: ca5ff194604f4bfd3748082c40cfb4b5252f20be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e01794fc41e75b97540793609859481ea476d3f0029e30b2451dac5438e7afc73cf4d868678c9e718a109ad83d9b3010cb0d2363cb420fe9f33c20b09ecb230
|
7
|
+
data.tar.gz: bafa72e44054663f88246a33e072b379747e17969c78112cdeb854c193eb4637ebe37d1c53ecfb433f0fec0368ac1bbd132a148f96c5b1b4a004b95c601616bb
|
data/lib/bifrost.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'bifrost/entity'
|
1
2
|
require 'bifrost/message'
|
2
3
|
require 'bifrost/topic'
|
3
4
|
require 'bifrost/subscriber'
|
@@ -8,11 +9,15 @@ require 'bifrost/worker'
|
|
8
9
|
module Bifrost
|
9
10
|
# Simple utlity that creates a topic and a single subscriber for the given
|
10
11
|
# topic. The topic is returned
|
11
|
-
def self.create_topic_with_subscriber(
|
12
|
-
topic = Bifrost::Topic.new(
|
12
|
+
def self.create_topic_with_subscriber(topic, subscriber)
|
13
|
+
topic = Bifrost::Topic.new(topic)
|
13
14
|
topic.save
|
14
|
-
|
15
|
-
topic.add_subscriber(subscriber)
|
15
|
+
topic.add_subscriber(Bifrost::Subscriber.new(subscriber))
|
16
16
|
topic
|
17
17
|
end
|
18
|
+
|
19
|
+
# Creates a manager instance
|
20
|
+
def self.manager
|
21
|
+
Bifrost::Manager.new
|
22
|
+
end
|
18
23
|
end
|
data/lib/bifrost/manager.rb
CHANGED
@@ -6,44 +6,69 @@ module Bifrost
|
|
6
6
|
# This class is used to handle the setup and execution of multiple listeners
|
7
7
|
class Manager
|
8
8
|
include Celluloid
|
9
|
+
include Celluloid::Internals::Logger
|
10
|
+
include Celluloid::Notifications
|
9
11
|
|
10
12
|
# The supervisor needs to be notified when a worker dies, it also needs to
|
11
13
|
# protect itself from harm
|
12
14
|
trap_exit :worker_died
|
13
15
|
|
16
|
+
# Initialisation of the Manager sets up a subscriber, which informs the manager
|
17
|
+
# when the worker is ready to begin work
|
18
|
+
def initialize
|
19
|
+
subscribe('worker_ready', :worker_ready)
|
20
|
+
end
|
21
|
+
|
14
22
|
# A supervised worker can be added to the current collection of supervised workers
|
15
23
|
# this also starts the actor
|
16
|
-
def add(
|
17
|
-
if
|
24
|
+
def add(topic, subscriber, proc)
|
25
|
+
if topic.nil? || subscriber.nil? || proc.nil?
|
18
26
|
raise InvalidWorkerDefinitionError, 'Invalid worker'
|
19
27
|
else
|
20
|
-
@supervisor = Worker.supervise(
|
21
|
-
as: Worker.supervisor_handle(topic_name, subscriber_name),
|
22
|
-
args: [topic_name, subscriber_name, proc]
|
23
|
-
)
|
24
|
-
# Link the worker to the supervisor so if the worker misbehaves the supervisor is alerted
|
25
|
-
# to this poor behaviour, the supervisor decides how to handle recovery
|
26
|
-
link(@supervisor.actors.last)
|
28
|
+
@supervisor = Worker.supervise(as: Worker.handle(topic, subscriber), args: [topic, subscriber, proc])
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
# When we run all the workers as actors in their own threads. This run also blocks to make sure
|
31
33
|
# the spawned threads remain operational indefinitely
|
32
34
|
def run
|
33
|
-
|
34
|
-
# Put the supervisor thread to sleep indefinitely # Better way?
|
35
|
+
# Put the supervisor thread to sleep indefinitely
|
35
36
|
loop do
|
36
|
-
# TODO:
|
37
|
-
sleep(
|
37
|
+
# TODO: Perhaps there is a better way?
|
38
|
+
sleep(60)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# This callback is fired when the worker signals it is ready to commence work after initialisation or
|
43
|
+
# recommence after recovering from a failure.
|
44
|
+
# When a worker completes initialisation it can take a while for the worker to be registered as an Actor
|
45
|
+
# in Celluloid, for this reason we need need to put a minor delay in the initialisation procedure
|
46
|
+
def worker_ready(*args)
|
47
|
+
info("Worker bootstrapping with #{args}...")
|
48
|
+
sleep(ENV['ACTOR_BOOTSTRAP_DELAY'] || 2) # TODO: Perhaps there is a better way?
|
49
|
+
worker = get_worker(args[1], args[2])
|
50
|
+
if worker
|
51
|
+
# Link the worker to the supervisor so if the worker misbehaves the supervisor is alerted
|
52
|
+
# to this poor behaviour, the supervisor decides how to handle recovery
|
53
|
+
link(worker)
|
54
|
+
worker.async.run
|
55
|
+
else
|
56
|
+
error("Worker bootstrap failure with #{args}")
|
38
57
|
end
|
39
58
|
end
|
40
59
|
|
41
60
|
private
|
42
61
|
|
62
|
+
# Retrieve a worker through the supervisory structure, this can take a while as the worker might
|
63
|
+
# be going through a restart procedure by the actor framework
|
64
|
+
def get_worker(topic, subscriber)
|
65
|
+
handle = Worker.handle(topic, subscriber)
|
66
|
+
Celluloid::Actor[handle.to_sym]
|
67
|
+
end
|
68
|
+
|
43
69
|
# This callback function fires when an worker dies
|
44
70
|
def worker_died(worker, reason)
|
45
|
-
#
|
46
|
-
puts "#{worker.inspect} has died: #{reason.class}"
|
71
|
+
error("Worker #{worker.inspect} has died: #{reason.class}")
|
47
72
|
end
|
48
73
|
end
|
49
74
|
end
|
data/lib/bifrost/version.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Major.Minor.Patch version numbering
|
2
2
|
module Bifrost
|
3
|
-
# The major version of
|
3
|
+
# The major version of Bifrost, updated only for major changes that are
|
4
4
|
# likely to require modification to Filmpond apps.
|
5
5
|
MAJOR_VERSION = 0
|
6
6
|
|
7
|
-
# The minor version of
|
7
|
+
# The minor version of Bifrost, updated for new feature releases.
|
8
8
|
MINOR_VERSION = 1
|
9
9
|
|
10
|
-
# The patch version of
|
10
|
+
# The patch version of Bifrost, updated only for bug fixes from the last
|
11
11
|
# feature release.
|
12
|
-
PATCH_VERSION =
|
12
|
+
PATCH_VERSION = 1
|
13
13
|
|
14
14
|
# The full version as a string.
|
15
15
|
VERSION = "#{MAJOR_VERSION}.#{MINOR_VERSION}.#{PATCH_VERSION}".freeze
|
data/lib/bifrost/worker.rb
CHANGED
@@ -9,20 +9,26 @@ module Bifrost
|
|
9
9
|
# combination one at a time
|
10
10
|
class Worker < Bifrost::Entity
|
11
11
|
include Celluloid
|
12
|
+
include Celluloid::Internals::Logger
|
13
|
+
include Celluloid::Notifications
|
12
14
|
|
13
|
-
attr_reader :
|
15
|
+
attr_reader :topic, :subscriber, :callback
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@
|
17
|
+
# Initialise the worker/actor. This actually starts the worker by implicitly calling the run method
|
18
|
+
def initialize(topic, subscriber, callback)
|
19
|
+
raise Bifrost::Exceptions::UnsupportedLambdaError, 'callback is not a proc' unless callback.respond_to?(:call)
|
20
|
+
@topic ||= topic
|
21
|
+
@subscriber ||= subscriber
|
19
22
|
@callback ||= callback
|
20
23
|
super()
|
24
|
+
info("Worker #{to_sym} starting up...")
|
25
|
+
publish('worker_ready', topic, subscriber)
|
21
26
|
end
|
22
27
|
|
23
28
|
# This method starts the actor, which runs in an infinite loop. This means the worker should
|
24
29
|
# not terminate, but if it does, the supervisor will make sure it restarts
|
25
30
|
def run
|
31
|
+
info("Worker #{to_sym} running...")
|
26
32
|
loop do
|
27
33
|
read_message
|
28
34
|
sleep(ENV['QUEUE_DELAY'] || 10)
|
@@ -32,7 +38,7 @@ module Bifrost
|
|
32
38
|
# Workers have a friendly name which is a combination of the topic and subscriber name
|
33
39
|
# which in the operational environment should be unique
|
34
40
|
def to_s
|
35
|
-
Worker.
|
41
|
+
Worker.handle(topic, subscriber)
|
36
42
|
end
|
37
43
|
|
38
44
|
# Utlity method to get the name of the worker as a symbol
|
@@ -41,15 +47,15 @@ module Bifrost
|
|
41
47
|
end
|
42
48
|
|
43
49
|
# A worker can tell you what it's friendly name will be, this is in order for supervision
|
44
|
-
def self.
|
45
|
-
"#{
|
50
|
+
def self.handle(topic, subscriber)
|
51
|
+
"#{topic.downcase}#{subscriber.downcase}"
|
46
52
|
end
|
47
53
|
|
48
54
|
private
|
49
55
|
|
50
56
|
# Actual processing of the message
|
51
57
|
def read_message
|
52
|
-
message = bus.receive_subscription_message(
|
58
|
+
message = bus.receive_subscription_message(topic, subscriber, timeout: ENV['TIMEOUT'] || 10)
|
53
59
|
if message
|
54
60
|
callback.call(message.properties['message'])
|
55
61
|
bus.delete_subscription_message(message)
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'bifrost'
|
3
3
|
|
4
4
|
describe Bifrost::Manager do
|
5
|
-
let(:cb
|
5
|
+
let(:cb) { proc { |m| puts "Principle Received: message #{m}" } }
|
6
6
|
let(:worker) { Bifrost::Worker.new('topic', 'subscriber', proc) }
|
7
7
|
let(:manager) { Bifrost::Manager.new }
|
8
8
|
|
data/spec/bifrost/topic_spec.rb
CHANGED
@@ -83,7 +83,7 @@ describe Bifrost::Topic do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'should not accept names with spaces in them' do
|
86
|
-
|
87
|
-
expect {
|
86
|
+
invalid_topic = Bifrost::Topic.new('topic name')
|
87
|
+
expect { invalid_topic.save }.to raise_error(URI::InvalidURIError)
|
88
88
|
end
|
89
89
|
end
|
data/spec/bifrost/worker_spec.rb
CHANGED
@@ -9,8 +9,8 @@ describe Bifrost::Worker do
|
|
9
9
|
let(:cb) { proc { |m| puts "Received: message #{m}" } }
|
10
10
|
subject(:worker) { Bifrost::Worker.new('topic', 'subscriber', cb) }
|
11
11
|
|
12
|
-
it { is_expected.to respond_to(:
|
13
|
-
it { is_expected.to respond_to(:
|
12
|
+
it { is_expected.to respond_to(:topic) }
|
13
|
+
it { is_expected.to respond_to(:subscriber) }
|
14
14
|
|
15
15
|
it 'should not except non procs in last argument' do
|
16
16
|
expect { Bifrost::Worker.new('topic', 'subscriber', 'x') }
|
@@ -18,7 +18,12 @@ describe Bifrost::Worker do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should have a friendly string name' do
|
21
|
-
expect(worker.to_s).to eq("#{worker.
|
21
|
+
expect(worker.to_s).to eq("#{worker.topic}#{worker.subscriber}")
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should downcase the friendly name' do
|
25
|
+
another_worker = Bifrost::Worker.new('toPic', 'subScriber', cb)
|
26
|
+
expect(another_worker.to_s).to eq("#{another_worker.topic.downcase}#{another_worker.subscriber.downcase}")
|
22
27
|
end
|
23
28
|
|
24
29
|
it 'should have a friendly symbol name' do
|
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.1.
|
4
|
+
version: 0.1.1
|
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
|
+
date: 2016-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: azure
|
@@ -42,14 +42,14 @@ dependencies:
|
|
42
42
|
name: rubocop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -150,8 +150,8 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0.7'
|
153
|
-
description:
|
154
|
-
|
153
|
+
description: Bifrost is a pub/sub wrapper library which uses Azure message bus and
|
154
|
+
actors.
|
155
155
|
email:
|
156
156
|
- shirren@filmpond.com
|
157
157
|
executables: []
|
@@ -178,7 +178,8 @@ files:
|
|
178
178
|
- spec/bifrost/worker_spec.rb
|
179
179
|
- spec/spec_helper.rb
|
180
180
|
homepage: https://github.com/filmpond/bifrost
|
181
|
-
licenses:
|
181
|
+
licenses:
|
182
|
+
- MIT
|
182
183
|
metadata: {}
|
183
184
|
post_install_message:
|
184
185
|
rdoc_options: []
|
@@ -188,7 +189,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
189
|
requirements:
|
189
190
|
- - ">="
|
190
191
|
- !ruby/object:Gem::Version
|
191
|
-
version: '0'
|
192
|
+
version: '2.0'
|
192
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
194
|
requirements:
|
194
195
|
- - ">="
|
@@ -199,7 +200,8 @@ rubyforge_project:
|
|
199
200
|
rubygems_version: 2.5.1
|
200
201
|
signing_key:
|
201
202
|
specification_version: 4
|
202
|
-
summary: Bifrost is a
|
203
|
+
summary: Bifrost is a pub/sub wrapper library which uses the Azure message bus and
|
204
|
+
actors.
|
203
205
|
test_files:
|
204
206
|
- spec/bifrost/manager_spec.rb
|
205
207
|
- spec/bifrost/message_spec.rb
|