announce 0.2.3 → 0.3.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/.travis.yml +3 -2
- data/announce.gemspec +2 -1
- data/lib/announce/adapters/base_adapter.rb +20 -13
- data/lib/announce/adapters/inline_adapter.rb +2 -4
- data/lib/announce/adapters/shoryuken_adapter.rb +87 -48
- data/lib/announce/adapters/test_adapter.rb +11 -4
- data/lib/announce/configuration.rb +13 -9
- data/lib/announce/core_ext.rb +7 -7
- data/lib/announce/message.rb +9 -8
- data/lib/announce/publisher.rb +2 -3
- data/lib/announce/railtie.rb +2 -5
- data/lib/announce/subscriber.rb +7 -9
- data/lib/announce/testing.rb +0 -2
- data/lib/announce/version.rb +1 -1
- data/lib/announce.rb +14 -18
- data/lib/tasks/announce.rake +6 -1
- metadata +25 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c4197e2523a8f2fde2b5c27b19d7ffff59864c21
|
|
4
|
+
data.tar.gz: 447f8331968cedbaa1c11d7e412f1a9d49eaf9f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f96f65e1562900251b14ba50068ec9a2926202250deb371c42be86de5f33fc2e792d071a4c7ae0080286c9a44501646f2c096ae164104d3f14c87a2562908ee5
|
|
7
|
+
data.tar.gz: 3408e11b3d4aa7009532040d42bce7a2f9330771b63412559eea0b04cdd779bd357b572b0004e1d858019b5aa5694729706c30109a1230f9e53a251a2d015336
|
data/.travis.yml
CHANGED
data/announce.gemspec
CHANGED
|
@@ -19,12 +19,13 @@ Gem::Specification.new do |spec|
|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
20
20
|
spec.require_paths = ['lib']
|
|
21
21
|
|
|
22
|
-
spec.add_development_dependency 'shoryuken'
|
|
22
|
+
spec.add_development_dependency 'shoryuken', '~> 2.0.5'
|
|
23
23
|
spec.add_development_dependency 'bundler'
|
|
24
24
|
spec.add_development_dependency 'rake'
|
|
25
25
|
spec.add_development_dependency 'growl'
|
|
26
26
|
spec.add_development_dependency 'minitest'
|
|
27
27
|
spec.add_development_dependency 'guard'
|
|
28
|
+
spec.add_development_dependency 'listen', '~> 3.2.0'
|
|
28
29
|
spec.add_development_dependency 'guard-minitest'
|
|
29
30
|
spec.add_development_dependency 'dotenv'
|
|
30
31
|
spec.add_development_dependency 'simplecov'
|
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "announce"
|
|
2
|
+
require "announce/message"
|
|
3
3
|
|
|
4
|
-
# publish, subscribe,
|
|
5
|
-
#
|
|
6
|
-
# you
|
|
4
|
+
# publish, subscribe, & configure_broker are the 3 required methods for adapters
|
|
5
|
+
# the base adapter also has helpful base classes, but they are not necessary
|
|
6
|
+
# you can write an adapter from scratch, but these 3 class methods are required.
|
|
7
7
|
module Announce
|
|
8
8
|
module Adapters
|
|
9
9
|
class BaseAdapter
|
|
10
|
-
|
|
11
10
|
class << self
|
|
12
|
-
|
|
11
|
+
# required
|
|
13
12
|
def publish(subject, action, body, options = {})
|
|
14
13
|
topic = adapter_constantize(:topic).new(subject, action, options)
|
|
15
|
-
msg =
|
|
14
|
+
msg =
|
|
15
|
+
Announce::Message.new(subject: subject, action: action, body: body)
|
|
16
16
|
topic.publish(msg.to_message, options)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
# required
|
|
19
20
|
def subscribe(worker_class, subject, actions = [], options = {})
|
|
20
21
|
subscriber = adapter_constantize(:subscriber).new
|
|
21
22
|
subscriber.subscribe(worker_class, subject, actions, options)
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
# required
|
|
24
26
|
def configure_broker(options)
|
|
25
27
|
broker_manager = adapter_constantize(:broker_manager).new(options)
|
|
26
28
|
broker_manager.configure
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
def adapter_constantize(name)
|
|
30
|
-
|
|
32
|
+
a_klass = Announce.options[:adapter].to_s.camelize
|
|
33
|
+
klass = name.to_s.camelize
|
|
34
|
+
"::Announce::Adapters::#{a_klass}Adapter::#{klass}".constantize
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
|
|
@@ -41,8 +45,8 @@ module Announce
|
|
|
41
45
|
attr_accessor :options
|
|
42
46
|
|
|
43
47
|
# uses the configuration
|
|
44
|
-
def initialize(options =
|
|
45
|
-
@options = options
|
|
48
|
+
def initialize(options = {})
|
|
49
|
+
@options = Announce.options.merge(options)
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
# actually configure the broker queues, topics, and subscriptions
|
|
@@ -62,6 +66,10 @@ module Announce
|
|
|
62
66
|
raise NotImplementedError.new("You must implement create.")
|
|
63
67
|
end
|
|
64
68
|
|
|
69
|
+
def verify
|
|
70
|
+
raise NotImplementedError.new("You must implement verify.")
|
|
71
|
+
end
|
|
72
|
+
|
|
65
73
|
def self.name_for(subject, action)
|
|
66
74
|
[prefix, namespace, subject, action].join(delimiter)
|
|
67
75
|
end
|
|
@@ -93,8 +101,7 @@ module Announce
|
|
|
93
101
|
end
|
|
94
102
|
end
|
|
95
103
|
|
|
96
|
-
class Topic < Destination
|
|
97
|
-
end
|
|
104
|
+
class Topic < Destination; end
|
|
98
105
|
|
|
99
106
|
class Queue < Destination
|
|
100
107
|
def self.name_for(subject, action)
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "announce/adapters/base_adapter"
|
|
2
2
|
|
|
3
3
|
module Announce
|
|
4
4
|
module Adapters
|
|
5
5
|
class InlineAdapter < BaseAdapter
|
|
6
|
-
|
|
7
6
|
def self.subscriptions
|
|
8
7
|
@@subscriptions ||= {}
|
|
9
8
|
end
|
|
@@ -34,8 +33,7 @@ module Announce
|
|
|
34
33
|
end
|
|
35
34
|
end
|
|
36
35
|
|
|
37
|
-
class Queue < BaseAdapter::Queue
|
|
38
|
-
end
|
|
36
|
+
class Queue < BaseAdapter::Queue; end
|
|
39
37
|
end
|
|
40
38
|
end
|
|
41
39
|
end
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "shoryuken"
|
|
2
|
+
require "announce/adapters/base_adapter"
|
|
3
3
|
|
|
4
4
|
module Announce
|
|
5
5
|
module Adapters
|
|
6
6
|
class ShoryukenAdapter < BaseAdapter
|
|
7
|
-
|
|
8
7
|
class AnnounceWorker #:nodoc:
|
|
9
8
|
include Shoryuken::Worker
|
|
10
9
|
|
|
11
10
|
shoryuken_options body_parser: :json, auto_delete: true
|
|
12
11
|
|
|
13
12
|
# overriden in register_class
|
|
14
|
-
def job_class
|
|
15
|
-
end
|
|
13
|
+
def job_class; end
|
|
16
14
|
|
|
17
15
|
def perform(sqs_msg, hash)
|
|
18
16
|
job = job_class.new(hash)
|
|
@@ -21,7 +19,6 @@ module Announce
|
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
class Subscriber < BaseAdapter::Subscriber
|
|
24
|
-
|
|
25
22
|
def subscribe(worker_class, subject, actions, options)
|
|
26
23
|
Array(actions).each do |action|
|
|
27
24
|
queue_name = Queue.name_for(subject, action)
|
|
@@ -42,22 +39,31 @@ module Announce
|
|
|
42
39
|
|
|
43
40
|
def active_job?
|
|
44
41
|
defined?(::ActiveJob) &&
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
defined?(ActiveJob::QueueAdapters::ShoryukenAdapter) &&
|
|
43
|
+
ActiveJob::Base.queue_adapter ==
|
|
44
|
+
ActiveJob::QueueAdapters::ShoryukenAdapter
|
|
47
45
|
end
|
|
48
46
|
end
|
|
49
47
|
|
|
50
48
|
class BrokerManager < BaseAdapter::BrokerManager
|
|
51
|
-
|
|
52
49
|
# actually configure the broker queues, topics, and subscriptions
|
|
53
50
|
def configure
|
|
51
|
+
if options[:verify_only]
|
|
52
|
+
Announce.logger.warn(
|
|
53
|
+
"Running Announce BrokerManager configure in verify_only mode."
|
|
54
|
+
)
|
|
55
|
+
Announce.logger.warn(
|
|
56
|
+
"Resources will be logged, not created; please verify they exist."
|
|
57
|
+
)
|
|
58
|
+
end
|
|
54
59
|
configure_publishing && configure_subscribing
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def configure_publishing
|
|
58
63
|
(options[:publish] || {}).each do |subject, actions|
|
|
59
64
|
Array(actions).each do |action|
|
|
60
|
-
ShoryukenAdapter::Topic.new(subject, action, options)
|
|
65
|
+
topic = ShoryukenAdapter::Topic.new(subject, action, options)
|
|
66
|
+
options[:verify_only] ? topic.verify : topic.create
|
|
61
67
|
end
|
|
62
68
|
end
|
|
63
69
|
true
|
|
@@ -68,9 +74,15 @@ module Announce
|
|
|
68
74
|
Array(actions).each do |action|
|
|
69
75
|
topic = ShoryukenAdapter::Topic.new(subject, action, options)
|
|
70
76
|
queue = ShoryukenAdapter::Queue.new(subject, action, options)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
if options[:verify_only]
|
|
78
|
+
topic.verify
|
|
79
|
+
queue.verify
|
|
80
|
+
topic.verify_subscription(queue)
|
|
81
|
+
else
|
|
82
|
+
topic.create
|
|
83
|
+
queue.create
|
|
84
|
+
topic.subscribe(queue)
|
|
85
|
+
end
|
|
74
86
|
end
|
|
75
87
|
end
|
|
76
88
|
true
|
|
@@ -78,7 +90,6 @@ module Announce
|
|
|
78
90
|
end
|
|
79
91
|
|
|
80
92
|
class Topic < BaseAdapter::Topic
|
|
81
|
-
|
|
82
93
|
def publish(message, options = {})
|
|
83
94
|
Shoryuken::Client.topics(name).send_message(message, options)
|
|
84
95
|
end
|
|
@@ -87,17 +98,28 @@ module Announce
|
|
|
87
98
|
sns.create_topic(name: name)[:topic_arn]
|
|
88
99
|
end
|
|
89
100
|
|
|
101
|
+
def verify
|
|
102
|
+
Announce.logger.warn("Verify SNS Topic: #{arn}")
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def verify_subscription(queue)
|
|
106
|
+
Announce.logger.warn(
|
|
107
|
+
"Verify Subscription:\n"\
|
|
108
|
+
" from SNS Topic: #{arn}\n"\
|
|
109
|
+
" to SQS Queue: #{queue.arn}"
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
|
|
90
113
|
def subscribe(queue)
|
|
91
|
-
subscription_arn =
|
|
92
|
-
topic_arn: arn,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
)[:subscription_arn]
|
|
114
|
+
subscription_arn =
|
|
115
|
+
sns.subscribe(topic_arn: arn, protocol: "sqs", endpoint: queue.arn)[
|
|
116
|
+
:subscription_arn
|
|
117
|
+
]
|
|
96
118
|
|
|
97
119
|
sns.set_subscription_attributes(
|
|
98
120
|
subscription_arn: subscription_arn,
|
|
99
|
-
attribute_name:
|
|
100
|
-
attribute_value:
|
|
121
|
+
attribute_name: "RawMessageDelivery",
|
|
122
|
+
attribute_value: "true"
|
|
101
123
|
)
|
|
102
124
|
subscription_arn
|
|
103
125
|
end
|
|
@@ -114,14 +136,25 @@ module Announce
|
|
|
114
136
|
end
|
|
115
137
|
|
|
116
138
|
class Queue < BaseAdapter::Queue
|
|
139
|
+
DLQ_SUFFIX = "failures".freeze
|
|
117
140
|
|
|
118
141
|
def create
|
|
119
|
-
create_attributes = default_options.merge((options[:queues] || {}).stringify_keys)
|
|
120
|
-
|
|
121
142
|
dlq_arn = create_dlq
|
|
122
|
-
create_attributes['RedrivePolicy'] = %Q{{"maxReceiveCount":"10", "deadLetterTargetArn":"#{dlq_arn}"}"}
|
|
123
143
|
|
|
124
|
-
|
|
144
|
+
create_attributes =
|
|
145
|
+
default_options.merge((options[:queues] || {}).stringify_keys)
|
|
146
|
+
create_attributes["RedrivePolicy"] =
|
|
147
|
+
'{"maxReceiveCount":"10", "deadLetterTargetArn":"' + dlq_arn + '"}'
|
|
148
|
+
|
|
149
|
+
sqs.create_queue(queue_name: name, attributes: create_attributes)[
|
|
150
|
+
:queue_url
|
|
151
|
+
]
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def verify
|
|
155
|
+
Announce.logger.warn(
|
|
156
|
+
"Verify SQS Queue: #{arn}\n\t with DLQ: #{dlq_arn}"
|
|
157
|
+
)
|
|
125
158
|
end
|
|
126
159
|
|
|
127
160
|
def arn
|
|
@@ -131,34 +164,40 @@ module Announce
|
|
|
131
164
|
end
|
|
132
165
|
|
|
133
166
|
def create_dlq
|
|
134
|
-
dlq_name = "#{name}_failures"
|
|
135
|
-
|
|
136
167
|
dlq_options = {
|
|
137
|
-
|
|
138
|
-
|
|
168
|
+
"MaximumMessageSize" => (256 * 1024).to_s,
|
|
169
|
+
"MessageRetentionPeriod" => (2 * 7 * 24 * 60 * 60).to_s
|
|
170
|
+
# 2 weeks in seconds
|
|
139
171
|
}
|
|
140
172
|
|
|
141
|
-
dlq = sqs.create_queue(
|
|
142
|
-
queue_name: dlq_name,
|
|
143
|
-
attributes: dlq_options
|
|
144
|
-
)
|
|
173
|
+
dlq = sqs.create_queue(queue_name: dlq_name, attributes: dlq_options)
|
|
145
174
|
|
|
146
|
-
attrs =
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
175
|
+
attrs =
|
|
176
|
+
sqs.get_queue_attributes(
|
|
177
|
+
queue_url: dlq[:queue_url], attribute_names: %w[QueueArn]
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
attrs.attributes["QueueArn"]
|
|
181
|
+
end
|
|
150
182
|
|
|
151
|
-
|
|
183
|
+
def dlq_arn
|
|
184
|
+
[arn, DLQ_SUFFIX].join(self.class.delimiter)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def dlq_name
|
|
188
|
+
[name, DLQ_SUFFIX].join(self.class.delimiter)
|
|
152
189
|
end
|
|
153
190
|
|
|
154
191
|
def default_options
|
|
155
192
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
193
|
+
"DelaySeconds" => "0",
|
|
194
|
+
"MaximumMessageSize" => (256 * 1024).to_s,
|
|
195
|
+
"VisibilityTimeout" => (60 * 60).to_s,
|
|
196
|
+
# 1 hour in seconds
|
|
197
|
+
"ReceiveMessageWaitTimeSeconds" => "0",
|
|
198
|
+
"MessageRetentionPeriod" => (7 * 24 * 60 * 60).to_s,
|
|
199
|
+
# 1 week in seconds
|
|
200
|
+
"Policy" => policy
|
|
162
201
|
}
|
|
163
202
|
end
|
|
164
203
|
|
|
@@ -172,9 +211,7 @@ module Announce
|
|
|
172
211
|
{
|
|
173
212
|
"Sid" => "1",
|
|
174
213
|
"Effect" => "Allow",
|
|
175
|
-
"Principal" => {
|
|
176
|
-
"AWS" => "*"
|
|
177
|
-
},
|
|
214
|
+
"Principal" => { "AWS" => "*" },
|
|
178
215
|
"Action" => "sqs:*",
|
|
179
216
|
"Resource" => arn,
|
|
180
217
|
"Condition" => {
|
|
@@ -195,4 +232,6 @@ module Announce
|
|
|
195
232
|
end
|
|
196
233
|
end
|
|
197
234
|
|
|
198
|
-
|
|
235
|
+
unless Shoryuken::Client.account_id
|
|
236
|
+
Shoryuken::Client.account_id = ENV["AWS_ACCOUNT_ID"]
|
|
237
|
+
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "announce/adapters/base_adapter"
|
|
2
2
|
|
|
3
3
|
module Announce
|
|
4
4
|
module Adapters
|
|
5
5
|
class TestAdapter < BaseAdapter
|
|
6
|
-
|
|
7
6
|
class Subscriber < BaseAdapter::Subscriber
|
|
8
|
-
|
|
9
7
|
@@subscriptions = []
|
|
10
8
|
|
|
11
9
|
def self.subscriptions
|
|
@@ -35,7 +33,6 @@ module Announce
|
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
class Topic < BaseAdapter::Topic
|
|
38
|
-
|
|
39
36
|
@@published_messages = []
|
|
40
37
|
|
|
41
38
|
def self.published_messages
|
|
@@ -50,12 +47,22 @@ module Announce
|
|
|
50
47
|
def create
|
|
51
48
|
true
|
|
52
49
|
end
|
|
50
|
+
|
|
51
|
+
def verify
|
|
52
|
+
Announce.logger.debug("#{self.class.name}: verify #{name}")
|
|
53
|
+
true
|
|
54
|
+
end
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
class Queue < BaseAdapter::Queue
|
|
56
58
|
def create
|
|
57
59
|
true
|
|
58
60
|
end
|
|
61
|
+
|
|
62
|
+
def verify
|
|
63
|
+
Announce.logger.debug("#{self.class.name}: verify #{name}")
|
|
64
|
+
true
|
|
65
|
+
end
|
|
59
66
|
end
|
|
60
67
|
end
|
|
61
68
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "yaml"
|
|
2
|
+
require "erb"
|
|
3
3
|
|
|
4
4
|
module Announce
|
|
5
5
|
class Configuration
|
|
@@ -14,16 +14,18 @@ module Announce
|
|
|
14
14
|
{}.tap do |defaults|
|
|
15
15
|
if defined?(ActiveJob)
|
|
16
16
|
defaults[:queue_name_prefix] = ::ActiveJob::Base.queue_name_prefix
|
|
17
|
-
defaults[:queue_name_delimiter] =
|
|
17
|
+
defaults[:queue_name_delimiter] =
|
|
18
|
+
::ActiveJob::Base.queue_name_delimiter
|
|
18
19
|
defaults[:adapter] = aj_queue_adapter_name
|
|
19
20
|
else
|
|
20
|
-
defaults[:queue_name_prefix] =
|
|
21
|
-
|
|
21
|
+
defaults[:queue_name_prefix] =
|
|
22
|
+
ENV["RAILS_ENV"] || ENV["APP_ENV"] || "development"
|
|
23
|
+
defaults[:queue_name_delimiter] = "_"
|
|
22
24
|
defaults[:adapter] = :inline
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
defaults[:app_name] =
|
|
26
|
-
defaults[:namespace] =
|
|
27
|
+
defaults[:app_name] = "app"
|
|
28
|
+
defaults[:namespace] = "announce"
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
|
|
@@ -35,7 +37,7 @@ module Announce
|
|
|
35
37
|
def initialize(options)
|
|
36
38
|
@options = options
|
|
37
39
|
base = defined?(Rails) ? Rails.root : Dir.pwd
|
|
38
|
-
options[:config_file] ||= File.join(base,
|
|
40
|
+
options[:config_file] ||= File.join(base, "config", "announce.yml")
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
def config_file
|
|
@@ -45,7 +47,9 @@ module Announce
|
|
|
45
47
|
def configure
|
|
46
48
|
defaults = self.class.default_options
|
|
47
49
|
if File.exist?(config_file)
|
|
48
|
-
defaults.merge(
|
|
50
|
+
defaults.merge(
|
|
51
|
+
YAML.safe_load(ERB.new(IO.read(config_file)).result).symbolize_keys
|
|
52
|
+
)
|
|
49
53
|
else
|
|
50
54
|
Announce.logger.warn "PubSub file #{config_file} does not exist"
|
|
51
55
|
defaults
|
data/lib/announce/core_ext.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
begin
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
2
|
+
require "active_support/core_ext/hash/keys"
|
|
3
|
+
require "active_support/core_ext/hash/deep_merge"
|
|
4
|
+
require "active_support/core_ext/hash/slice"
|
|
5
5
|
rescue LoadError
|
|
6
6
|
class Hash
|
|
7
7
|
def stringify_keys
|
|
@@ -36,11 +36,11 @@ rescue LoadError
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
begin
|
|
39
|
-
require
|
|
39
|
+
require "active_support/core_ext/string/inflections"
|
|
40
40
|
rescue LoadError
|
|
41
41
|
class String
|
|
42
42
|
def constantize
|
|
43
|
-
names = self.split(
|
|
43
|
+
names = self.split("::")
|
|
44
44
|
names.shift if names.empty? || names.first.empty?
|
|
45
45
|
|
|
46
46
|
constant = Object
|
|
@@ -54,14 +54,14 @@ rescue LoadError
|
|
|
54
54
|
string = self
|
|
55
55
|
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
|
56
56
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
|
57
|
-
string.gsub!(/\//,
|
|
57
|
+
string.gsub!(/\//, "::")
|
|
58
58
|
string
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def underscore
|
|
62
62
|
camel_cased_word = self
|
|
63
63
|
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
|
|
64
|
-
word = camel_cased_word.to_s.gsub(/::/,
|
|
64
|
+
word = camel_cased_word.to_s.gsub(/::/, "/")
|
|
65
65
|
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
|
66
66
|
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
|
67
67
|
word.tr!("-", "_")
|
data/lib/announce/message.rb
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "securerandom"
|
|
2
|
+
require "json"
|
|
2
3
|
|
|
3
4
|
module Announce
|
|
4
5
|
class Message
|
|
5
|
-
|
|
6
6
|
attr_accessor :options
|
|
7
7
|
|
|
8
|
-
def initialize(options={})
|
|
9
|
-
@options =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@options =
|
|
10
|
+
{
|
|
11
|
+
"message_id" => ::SecureRandom.uuid,
|
|
12
|
+
"app" => app,
|
|
13
|
+
"sent_at" => Time.now.utc
|
|
14
|
+
}.merge(options).stringify_keys
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def app
|
data/lib/announce/publisher.rb
CHANGED
data/lib/announce/railtie.rb
CHANGED
data/lib/announce/subscriber.rb
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
module Announce
|
|
2
2
|
module Subscriber
|
|
3
|
-
|
|
4
3
|
def self.included(base)
|
|
5
|
-
base.class_eval
|
|
6
|
-
attr_accessor :subject, :action, :message
|
|
7
|
-
end
|
|
4
|
+
base.class_eval { attr_accessor :subject, :action, :message }
|
|
8
5
|
|
|
9
6
|
base.extend(ClassMethods)
|
|
10
7
|
end
|
|
11
8
|
|
|
12
9
|
module ClassMethods
|
|
13
|
-
def subscribe_to(subject, actions=[], options = {})
|
|
10
|
+
def subscribe_to(subject, actions = [], options = {})
|
|
14
11
|
Announce.subscribe(self, subject, actions, options)
|
|
15
12
|
end
|
|
16
13
|
end
|
|
@@ -25,19 +22,20 @@ module Announce
|
|
|
25
22
|
@subject = message[:subject]
|
|
26
23
|
@action = message[:action]
|
|
27
24
|
|
|
28
|
-
if [message, subject, action].any?
|
|
29
|
-
raise "
|
|
25
|
+
if [message, subject, action].any?(&:nil?)
|
|
26
|
+
raise "Missing message, subject, or action for '#{event.inspect}'"
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
if respond_to?(delegate_method)
|
|
33
30
|
public_send(delegate_method, message[:body])
|
|
34
31
|
else
|
|
35
|
-
raise "`#{self.class.name}`
|
|
32
|
+
raise "`#{self.class.name}` subscribed, but doesn't implement " \
|
|
33
|
+
"`#{delegate_method}` for '#{event.inspect}'"
|
|
36
34
|
end
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
def delegate_method(message = @message)
|
|
40
|
-
[
|
|
38
|
+
["receive", message[:subject], message[:action]].join("_")
|
|
41
39
|
end
|
|
42
40
|
end
|
|
43
41
|
end
|
data/lib/announce/testing.rb
CHANGED
data/lib/announce/version.rb
CHANGED
data/lib/announce.rb
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "logger"
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
3
|
+
require "announce/configuration"
|
|
4
|
+
require "announce/core_ext"
|
|
5
|
+
require "announce/message"
|
|
6
|
+
require "announce/publisher"
|
|
7
|
+
require "announce/subscriber"
|
|
8
|
+
require "announce/version"
|
|
9
|
+
require "announce/railtie" if defined?(Rails)
|
|
10
10
|
|
|
11
11
|
module Announce
|
|
12
12
|
class << self
|
|
13
|
-
|
|
14
|
-
def publish(subject, action, message, options={})
|
|
13
|
+
def publish(subject, action, message, options = {})
|
|
15
14
|
adapter_class.publish(subject, action, message, options)
|
|
16
15
|
end
|
|
17
16
|
|
|
@@ -21,8 +20,8 @@ module Announce
|
|
|
21
20
|
adapter_class.subscribe(worker_class, subject, actions, options)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
def configure_broker
|
|
25
|
-
adapter_class.configure_broker(options)
|
|
23
|
+
def configure_broker(opts = {})
|
|
24
|
+
adapter_class.configure_broker(options.merge(opts))
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def options
|
|
@@ -37,15 +36,12 @@ module Announce
|
|
|
37
36
|
def adapter_class
|
|
38
37
|
announce_adapter = Announce.options[:adapter]
|
|
39
38
|
require "announce/adapters/#{announce_adapter.to_s.downcase}_adapter"
|
|
40
|
-
"::Announce::Adapters::#{announce_adapter.to_s.camelize}Adapter"
|
|
39
|
+
"::Announce::Adapters::#{announce_adapter.to_s.camelize}Adapter"
|
|
40
|
+
.constantize
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def logger
|
|
44
|
-
@logger ||=
|
|
45
|
-
Rails.logger
|
|
46
|
-
else
|
|
47
|
-
Logger.new(STDOUT)
|
|
48
|
-
end
|
|
44
|
+
@logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
|
49
45
|
end
|
|
50
46
|
|
|
51
47
|
def logger=(l)
|
data/lib/tasks/announce.rake
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
namespace :announce do
|
|
2
2
|
|
|
3
3
|
desc 'Configure the broker destinations'
|
|
4
|
-
task :
|
|
4
|
+
task configure_broker: [:environment] do
|
|
5
5
|
Announce.configure
|
|
6
6
|
Announce.configure_broker
|
|
7
7
|
end
|
|
8
|
+
|
|
9
|
+
task verify_config: [:environment] do
|
|
10
|
+
Announce.configure
|
|
11
|
+
Announce.configure_broker(verify_only: true)
|
|
12
|
+
end
|
|
8
13
|
end
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: announce
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kuklewicz
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: shoryuken
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 2.0.5
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 2.0.5
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +94,20 @@ dependencies:
|
|
|
94
94
|
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: listen
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 3.2.0
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 3.2.0
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: guard-minitest
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -188,7 +202,7 @@ homepage: https://github.com/PRX/announce
|
|
|
188
202
|
licenses:
|
|
189
203
|
- MIT
|
|
190
204
|
metadata: {}
|
|
191
|
-
post_install_message:
|
|
205
|
+
post_install_message:
|
|
192
206
|
rdoc_options: []
|
|
193
207
|
require_paths:
|
|
194
208
|
- lib
|
|
@@ -203,9 +217,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
203
217
|
- !ruby/object:Gem::Version
|
|
204
218
|
version: '0'
|
|
205
219
|
requirements: []
|
|
206
|
-
rubyforge_project:
|
|
207
|
-
rubygems_version: 2.
|
|
208
|
-
signing_key:
|
|
220
|
+
rubyforge_project:
|
|
221
|
+
rubygems_version: 2.5.1
|
|
222
|
+
signing_key:
|
|
209
223
|
specification_version: 4
|
|
210
224
|
summary: Announce is for pubsub of messages
|
|
211
225
|
test_files: []
|