circuitry 2.1.1 → 3.0.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/CHANGELOG.md +7 -0
- data/README.md +107 -59
- data/circuitry.gemspec +2 -2
- data/lib/circuitry.rb +32 -15
- data/lib/circuitry/cli.rb +32 -32
- data/lib/circuitry/config/file_loader.rb +24 -0
- data/lib/circuitry/config/publisher_settings.rb +16 -0
- data/lib/circuitry/config/shared_settings.rb +39 -0
- data/lib/circuitry/config/subscriber_settings.rb +32 -0
- data/lib/circuitry/locks/base.rb +3 -3
- data/lib/circuitry/locks/memory.rb +4 -4
- data/lib/circuitry/locks/noop.rb +1 -1
- data/lib/circuitry/locks/redis.rb +1 -1
- data/lib/circuitry/middleware/chain.rb +1 -1
- data/lib/circuitry/processor.rb +12 -10
- data/lib/circuitry/processors/forker.rb +1 -1
- data/lib/circuitry/processors/threader.rb +1 -1
- data/lib/circuitry/provisioning.rb +9 -0
- data/lib/circuitry/provisioning/provisioner.rb +71 -0
- data/lib/circuitry/provisioning/queue_creator.rb +64 -0
- data/lib/circuitry/provisioning/subscription_creator.rb +65 -0
- data/lib/circuitry/provisioning/topic_creator.rb +31 -0
- data/lib/circuitry/publisher.rb +5 -6
- data/lib/circuitry/queue.rb +25 -3
- data/lib/circuitry/railtie.rb +9 -0
- data/lib/circuitry/services/sns.rb +1 -1
- data/lib/circuitry/services/sqs.rb +1 -1
- data/lib/circuitry/subscriber.rb +8 -8
- data/lib/circuitry/tasks.rb +3 -3
- data/lib/circuitry/topic.rb +24 -2
- data/lib/circuitry/version.rb +1 -1
- metadata +11 -7
- data/lib/circuitry/configuration.rb +0 -64
- data/lib/circuitry/provisioner.rb +0 -60
- data/lib/circuitry/queue_creator.rb +0 -50
- data/lib/circuitry/subscription_creator.rb +0 -60
- data/lib/circuitry/topic_creator.rb +0 -25
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'circuitry/services/sns'
|
2
|
+
require 'circuitry/topic'
|
3
|
+
|
4
|
+
module Circuitry
|
5
|
+
module Provisioning
|
6
|
+
class TopicCreator
|
7
|
+
include Services::SNS
|
8
|
+
|
9
|
+
attr_reader :topic_name
|
10
|
+
|
11
|
+
def self.find_or_create(topic_name)
|
12
|
+
new(topic_name).topic
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(topic_name)
|
16
|
+
self.topic_name = topic_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def topic
|
20
|
+
return @_topic if defined?(@_topic)
|
21
|
+
|
22
|
+
response = sns.create_topic(name: topic_name)
|
23
|
+
@_topic = Topic.new(response.topic_arn)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_writer :topic_name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/circuitry/publisher.rb
CHANGED
@@ -2,7 +2,6 @@ require 'json'
|
|
2
2
|
require 'timeout'
|
3
3
|
require 'circuitry/concerns/async'
|
4
4
|
require 'circuitry/services/sns'
|
5
|
-
require 'circuitry/topic_creator'
|
6
5
|
|
7
6
|
module Circuitry
|
8
7
|
class PublishError < StandardError; end
|
@@ -40,7 +39,7 @@ module Circuitry
|
|
40
39
|
end
|
41
40
|
|
42
41
|
def self.default_async_strategy
|
43
|
-
Circuitry.
|
42
|
+
Circuitry.publisher_config.async_strategy
|
44
43
|
end
|
45
44
|
|
46
45
|
protected
|
@@ -52,7 +51,7 @@ module Circuitry
|
|
52
51
|
Timeout.timeout(timeout) do
|
53
52
|
logger.info("Publishing message to #{topic_name}")
|
54
53
|
|
55
|
-
topic =
|
54
|
+
topic = Topic.find(topic_name)
|
56
55
|
sns.publish(topic_arn: topic.arn, message: message)
|
57
56
|
end
|
58
57
|
end
|
@@ -63,17 +62,17 @@ module Circuitry
|
|
63
62
|
private
|
64
63
|
|
65
64
|
def logger
|
66
|
-
Circuitry.
|
65
|
+
Circuitry.publisher_config.logger
|
67
66
|
end
|
68
67
|
|
69
68
|
def can_publish?
|
70
|
-
Circuitry.
|
69
|
+
Circuitry.publisher_config.aws_options.values.all? do |value|
|
71
70
|
!value.nil? && !value.empty?
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
74
|
def middleware
|
76
|
-
Circuitry.
|
75
|
+
Circuitry.publisher_config.middleware
|
77
76
|
end
|
78
77
|
end
|
79
78
|
end
|
data/lib/circuitry/queue.rb
CHANGED
@@ -4,10 +4,30 @@ module Circuitry
|
|
4
4
|
class Queue
|
5
5
|
include Services::SQS
|
6
6
|
|
7
|
+
class Finder
|
8
|
+
include Services::SQS
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
self.name = name
|
12
|
+
end
|
13
|
+
|
14
|
+
def find
|
15
|
+
sqs.get_queue_url(queue_name: name)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_accessor :name
|
21
|
+
end
|
22
|
+
|
7
23
|
attr_reader :url
|
8
24
|
|
9
25
|
def initialize(url)
|
10
|
-
|
26
|
+
self.url = url
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.find(name)
|
30
|
+
new(Finder.new(name).find.queue_url)
|
11
31
|
end
|
12
32
|
|
13
33
|
def name
|
@@ -18,10 +38,12 @@ module Circuitry
|
|
18
38
|
@arn ||= attribute('QueueArn')
|
19
39
|
end
|
20
40
|
|
21
|
-
private
|
22
|
-
|
23
41
|
def attribute(name)
|
24
42
|
sqs.get_queue_attributes(queue_url: url, attribute_names: [name]).attributes[name]
|
25
43
|
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_writer :url
|
26
48
|
end
|
27
49
|
end
|
data/lib/circuitry/railtie.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
require 'rails'
|
2
|
+
require 'circuitry/config/file_loader'
|
2
3
|
|
3
4
|
module Circuitry
|
4
5
|
class Railtie < Rails::Railtie
|
5
6
|
rake_tasks do
|
6
7
|
load 'circuitry/tasks.rb'
|
7
8
|
end
|
9
|
+
|
10
|
+
initializer 'circuitry' do
|
11
|
+
env = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
12
|
+
|
13
|
+
%w[config/circuitry.yml.erb config/circuitry.yml].detect do |filename|
|
14
|
+
Circuitry::Config::FileLoader.load(filename, env)
|
15
|
+
end
|
16
|
+
end
|
8
17
|
end
|
9
18
|
end
|
data/lib/circuitry/subscriber.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'retries'
|
2
2
|
require 'timeout'
|
3
|
-
require 'circuitry/queue_creator'
|
4
3
|
require 'circuitry/concerns/async'
|
5
4
|
require 'circuitry/services/sqs'
|
6
5
|
require 'circuitry/message'
|
6
|
+
require 'circuitry/queue'
|
7
7
|
|
8
8
|
module Circuitry
|
9
9
|
class SubscribeError < StandardError; end
|
@@ -30,8 +30,8 @@ module Circuitry
|
|
30
30
|
options = DEFAULT_OPTIONS.merge(options)
|
31
31
|
|
32
32
|
self.subscribed = false
|
33
|
+
self.queue = Queue.find(Circuitry.subscriber_config.queue_name).url
|
33
34
|
|
34
|
-
self.queue = QueueCreator.find_or_create(Circuitry.config.subscriber_queue_name).url
|
35
35
|
%i[lock async timeout wait_time batch_size].each do |sym|
|
36
36
|
send(:"#{sym}=", options[sym])
|
37
37
|
end
|
@@ -64,7 +64,7 @@ module Circuitry
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def self.default_async_strategy
|
67
|
-
Circuitry.
|
67
|
+
Circuitry.subscriber_config.async_strategy
|
68
68
|
end
|
69
69
|
|
70
70
|
protected
|
@@ -74,7 +74,7 @@ module Circuitry
|
|
74
74
|
|
75
75
|
def lock=(value)
|
76
76
|
value = case value
|
77
|
-
when true then Circuitry.
|
77
|
+
when true then Circuitry.subscriber_config.lock_strategy
|
78
78
|
when false then Circuitry::Locks::NOOP.new
|
79
79
|
when Circuitry::Locks::Base then value
|
80
80
|
else raise ArgumentError, lock_value_error(value)
|
@@ -181,21 +181,21 @@ module Circuitry
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def logger
|
184
|
-
Circuitry.
|
184
|
+
Circuitry.subscriber_config.logger
|
185
185
|
end
|
186
186
|
|
187
187
|
def error_handler
|
188
|
-
Circuitry.
|
188
|
+
Circuitry.subscriber_config.error_handler
|
189
189
|
end
|
190
190
|
|
191
191
|
def can_subscribe?
|
192
|
-
Circuitry.
|
192
|
+
Circuitry.subscriber_config.aws_options.values.all? do |value|
|
193
193
|
!value.nil? && !value.empty?
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
197
|
def middleware
|
198
|
-
Circuitry.
|
198
|
+
Circuitry.subscriber_config.middleware
|
199
199
|
end
|
200
200
|
end
|
201
201
|
end
|
data/lib/circuitry/tasks.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
namespace :circuitry do
|
2
2
|
desc 'Create subscriber queues and subscribe queue to topics'
|
3
3
|
task setup: :environment do
|
4
|
-
require 'circuitry/
|
5
|
-
|
4
|
+
require 'circuitry/provisioning'
|
5
|
+
|
6
6
|
logger = Logger.new(STDOUT)
|
7
7
|
logger.level = Logger::INFO
|
8
8
|
|
9
|
-
Circuitry::
|
9
|
+
Circuitry::Provisioning.provision(logger: logger)
|
10
10
|
end
|
11
11
|
end
|
data/lib/circuitry/topic.rb
CHANGED
@@ -1,17 +1,39 @@
|
|
1
|
+
require 'circuitry/services/sns'
|
2
|
+
|
1
3
|
module Circuitry
|
2
4
|
class Topic
|
5
|
+
class Finder
|
6
|
+
include Services::SNS
|
7
|
+
|
8
|
+
def initialize(name)
|
9
|
+
self.name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def find
|
13
|
+
sns.create_topic(name: name)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_accessor :name
|
19
|
+
end
|
20
|
+
|
3
21
|
attr_reader :arn
|
4
22
|
|
5
23
|
def initialize(arn)
|
6
24
|
@arn = arn
|
7
25
|
end
|
8
26
|
|
27
|
+
def self.find(name)
|
28
|
+
new(Finder.new(name).find.topic_arn)
|
29
|
+
end
|
30
|
+
|
9
31
|
def name
|
10
32
|
@name ||= arn.split(':').last
|
11
33
|
end
|
12
34
|
|
13
|
-
def ==(
|
14
|
-
|
35
|
+
def ==(other)
|
36
|
+
other.hash == hash
|
15
37
|
end
|
16
38
|
|
17
39
|
def hash
|
data/lib/circuitry/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: circuitry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Huggins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-02-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -247,7 +247,10 @@ files:
|
|
247
247
|
- lib/circuitry.rb
|
248
248
|
- lib/circuitry/cli.rb
|
249
249
|
- lib/circuitry/concerns/async.rb
|
250
|
-
- lib/circuitry/
|
250
|
+
- lib/circuitry/config/file_loader.rb
|
251
|
+
- lib/circuitry/config/publisher_settings.rb
|
252
|
+
- lib/circuitry/config/shared_settings.rb
|
253
|
+
- lib/circuitry/config/subscriber_settings.rb
|
251
254
|
- lib/circuitry/locks/base.rb
|
252
255
|
- lib/circuitry/locks/memcache.rb
|
253
256
|
- lib/circuitry/locks/memory.rb
|
@@ -260,18 +263,19 @@ files:
|
|
260
263
|
- lib/circuitry/processors/batcher.rb
|
261
264
|
- lib/circuitry/processors/forker.rb
|
262
265
|
- lib/circuitry/processors/threader.rb
|
263
|
-
- lib/circuitry/
|
266
|
+
- lib/circuitry/provisioning.rb
|
267
|
+
- lib/circuitry/provisioning/provisioner.rb
|
268
|
+
- lib/circuitry/provisioning/queue_creator.rb
|
269
|
+
- lib/circuitry/provisioning/subscription_creator.rb
|
270
|
+
- lib/circuitry/provisioning/topic_creator.rb
|
264
271
|
- lib/circuitry/publisher.rb
|
265
272
|
- lib/circuitry/queue.rb
|
266
|
-
- lib/circuitry/queue_creator.rb
|
267
273
|
- lib/circuitry/railtie.rb
|
268
274
|
- lib/circuitry/services/sns.rb
|
269
275
|
- lib/circuitry/services/sqs.rb
|
270
276
|
- lib/circuitry/subscriber.rb
|
271
|
-
- lib/circuitry/subscription_creator.rb
|
272
277
|
- lib/circuitry/tasks.rb
|
273
278
|
- lib/circuitry/topic.rb
|
274
|
-
- lib/circuitry/topic_creator.rb
|
275
279
|
- lib/circuitry/version.rb
|
276
280
|
homepage: https://github.com/kapost/circuitry
|
277
281
|
licenses:
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
require 'virtus'
|
3
|
-
|
4
|
-
module Circuitry
|
5
|
-
class Configuration
|
6
|
-
include Virtus::Model
|
7
|
-
|
8
|
-
attribute :subscriber_queue_name, String
|
9
|
-
attribute :subscriber_dead_letter_queue_name, String
|
10
|
-
attribute :publisher_topic_names, Array[String]
|
11
|
-
|
12
|
-
attribute :access_key, String
|
13
|
-
attribute :secret_key, String
|
14
|
-
attribute :region, String, default: 'us-east-1'
|
15
|
-
attribute :logger, Logger, default: Logger.new(STDERR)
|
16
|
-
attribute :error_handler
|
17
|
-
attribute :lock_strategy, Object, default: ->(_page, _attribute) { Circuitry::Locks::Memory.new }
|
18
|
-
attribute :publish_async_strategy, Symbol, default: ->(_page, _attribute) { :fork }
|
19
|
-
attribute :subscribe_async_strategy, Symbol, default: ->(_page, _attribute) { :fork }
|
20
|
-
attribute :on_thread_exit
|
21
|
-
attribute :on_fork_exit
|
22
|
-
|
23
|
-
def publish_async_strategy=(value)
|
24
|
-
validate(value, Publisher.async_strategies)
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
28
|
-
def subscribe_async_strategy=(value)
|
29
|
-
validate(value, Subscriber.async_strategies)
|
30
|
-
super
|
31
|
-
end
|
32
|
-
|
33
|
-
def subscriber_dead_letter_queue_name
|
34
|
-
super || "#{subscriber_queue_name}-failures"
|
35
|
-
end
|
36
|
-
|
37
|
-
def subscriber_middleware
|
38
|
-
@subscriber_middleware ||= Circuitry::Middleware::Chain.new
|
39
|
-
yield @subscriber_middleware if block_given?
|
40
|
-
@subscriber_middleware
|
41
|
-
end
|
42
|
-
|
43
|
-
def publisher_middleware
|
44
|
-
@publisher_middleware ||= Circuitry::Middleware::Chain.new
|
45
|
-
yield @publisher_middleware if block_given?
|
46
|
-
@publisher_middleware
|
47
|
-
end
|
48
|
-
|
49
|
-
def aws_options
|
50
|
-
{
|
51
|
-
access_key_id: access_key,
|
52
|
-
secret_access_key: secret_key,
|
53
|
-
region: region
|
54
|
-
}
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def validate(value, permitted_values)
|
60
|
-
return if permitted_values.include?(value)
|
61
|
-
raise ArgumentError, "invalid value `#{value}`, must be one of #{permitted_values.inspect}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'circuitry/queue_creator'
|
2
|
-
require 'circuitry/topic_creator'
|
3
|
-
require 'circuitry/subscription_creator'
|
4
|
-
|
5
|
-
module Circuitry
|
6
|
-
class Provisioner
|
7
|
-
attr_reader :config, :logger
|
8
|
-
|
9
|
-
def initialize(config, logger: Logger.new(STDOUT))
|
10
|
-
self.config = config
|
11
|
-
self.logger = logger
|
12
|
-
end
|
13
|
-
|
14
|
-
def run
|
15
|
-
queue = create_queue
|
16
|
-
topics = create_topics if queue
|
17
|
-
subscribe_topics(queue, topics) if queue && topics
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
attr_writer :config, :logger
|
23
|
-
|
24
|
-
def create_queue
|
25
|
-
safe_aws('Create Queue') do
|
26
|
-
queue = Circuitry::QueueCreator.find_or_create(
|
27
|
-
config.subscriber_queue_name,
|
28
|
-
dead_letter_queue_name: config.subscriber_dead_letter_queue_name
|
29
|
-
)
|
30
|
-
logger.info "Created queue #{queue.url}"
|
31
|
-
queue
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def create_topics
|
36
|
-
safe_aws('Create Topics') do
|
37
|
-
config.publisher_topic_names.map do |topic_name|
|
38
|
-
topic = Circuitry::TopicCreator.find_or_create(topic_name)
|
39
|
-
logger.info "Created topic #{topic.name}"
|
40
|
-
topic
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def subscribe_topics(queue, topics)
|
46
|
-
safe_aws('Subscribe Topics') do
|
47
|
-
Circuitry::SubscriptionCreator.subscribe_all(queue, topics)
|
48
|
-
logger.info "Subscribed all topics to #{queue.name}"
|
49
|
-
true
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def safe_aws(desc)
|
54
|
-
yield
|
55
|
-
rescue Aws::SQS::Errors::AccessDenied
|
56
|
-
logger.fatal("#{desc}: Access denied. Check your configured credentials.")
|
57
|
-
nil
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|