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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +107 -59
  4. data/circuitry.gemspec +2 -2
  5. data/lib/circuitry.rb +32 -15
  6. data/lib/circuitry/cli.rb +32 -32
  7. data/lib/circuitry/config/file_loader.rb +24 -0
  8. data/lib/circuitry/config/publisher_settings.rb +16 -0
  9. data/lib/circuitry/config/shared_settings.rb +39 -0
  10. data/lib/circuitry/config/subscriber_settings.rb +32 -0
  11. data/lib/circuitry/locks/base.rb +3 -3
  12. data/lib/circuitry/locks/memory.rb +4 -4
  13. data/lib/circuitry/locks/noop.rb +1 -1
  14. data/lib/circuitry/locks/redis.rb +1 -1
  15. data/lib/circuitry/middleware/chain.rb +1 -1
  16. data/lib/circuitry/processor.rb +12 -10
  17. data/lib/circuitry/processors/forker.rb +1 -1
  18. data/lib/circuitry/processors/threader.rb +1 -1
  19. data/lib/circuitry/provisioning.rb +9 -0
  20. data/lib/circuitry/provisioning/provisioner.rb +71 -0
  21. data/lib/circuitry/provisioning/queue_creator.rb +64 -0
  22. data/lib/circuitry/provisioning/subscription_creator.rb +65 -0
  23. data/lib/circuitry/provisioning/topic_creator.rb +31 -0
  24. data/lib/circuitry/publisher.rb +5 -6
  25. data/lib/circuitry/queue.rb +25 -3
  26. data/lib/circuitry/railtie.rb +9 -0
  27. data/lib/circuitry/services/sns.rb +1 -1
  28. data/lib/circuitry/services/sqs.rb +1 -1
  29. data/lib/circuitry/subscriber.rb +8 -8
  30. data/lib/circuitry/tasks.rb +3 -3
  31. data/lib/circuitry/topic.rb +24 -2
  32. data/lib/circuitry/version.rb +1 -1
  33. metadata +11 -7
  34. data/lib/circuitry/configuration.rb +0 -64
  35. data/lib/circuitry/provisioner.rb +0 -60
  36. data/lib/circuitry/queue_creator.rb +0 -50
  37. data/lib/circuitry/subscription_creator.rb +0 -60
  38. 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
@@ -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.config.publish_async_strategy
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 = TopicCreator.find_or_create(topic_name)
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.config.logger
65
+ Circuitry.publisher_config.logger
67
66
  end
68
67
 
69
68
  def can_publish?
70
- Circuitry.config.aws_options.values.all? do |value|
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.config.publisher_middleware
75
+ Circuitry.publisher_config.middleware
77
76
  end
78
77
  end
79
78
  end
@@ -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
- @url = url
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
@@ -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
@@ -4,7 +4,7 @@ module Circuitry
4
4
  module Services
5
5
  module SNS
6
6
  def sns
7
- @sns ||= Aws::SNS::Client.new(Circuitry.config.aws_options)
7
+ @sns ||= Aws::SNS::Client.new(Circuitry.publisher_config.aws_options)
8
8
  end
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Circuitry
4
4
  module Services
5
5
  module SQS
6
6
  def sqs
7
- @sqs ||= Aws::SQS::Client.new(Circuitry.config.aws_options)
7
+ @sqs ||= Aws::SQS::Client.new(Circuitry.subscriber_config.aws_options)
8
8
  end
9
9
  end
10
10
  end
@@ -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.config.subscribe_async_strategy
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.config.lock_strategy
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.config.logger
184
+ Circuitry.subscriber_config.logger
185
185
  end
186
186
 
187
187
  def error_handler
188
- Circuitry.config.error_handler
188
+ Circuitry.subscriber_config.error_handler
189
189
  end
190
190
 
191
191
  def can_subscribe?
192
- Circuitry.config.aws_options.values.all? do |value|
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.config.subscriber_middleware
198
+ Circuitry.subscriber_config.middleware
199
199
  end
200
200
  end
201
201
  end
@@ -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/provisioner'
5
-
4
+ require 'circuitry/provisioning'
5
+
6
6
  logger = Logger.new(STDOUT)
7
7
  logger.level = Logger::INFO
8
8
 
9
- Circuitry::Provisioner.new(Circuitry.config, logger: logger).run
9
+ Circuitry::Provisioning.provision(logger: logger)
10
10
  end
11
11
  end
@@ -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 ==(obj)
14
- obj.hash == self.hash
35
+ def ==(other)
36
+ other.hash == hash
15
37
  end
16
38
 
17
39
  def hash
@@ -1,3 +1,3 @@
1
1
  module Circuitry
2
- VERSION = '2.1.1'
2
+ VERSION = '3.0.0'
3
3
  end
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: 2.1.1
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-01-30 00:00:00.000000000 Z
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/configuration.rb
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/provisioner.rb
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