reactor 0.16.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes.md +4 -0
- data/Gemfile.lock +6 -6
- data/README.md +22 -1
- data/lib/reactor/models/concerns/publishable.rb +18 -8
- data/lib/reactor/testing/matchers.rb +15 -0
- data/lib/reactor/version.rb +1 -1
- data/spec/models/concerns/publishable_spec.rb +61 -7
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc723686f416100ec5c50b2ff2ccd1893f4c3076
|
4
|
+
data.tar.gz: 876912b1d837da0b05da0349249811d31e3b82ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47a87bcef246a5440a573976eac9eb4cc8051938322e0142379ae5f9bff742d97a42fc37ba042380e2895598bc58cc6508c426fb2abf85e2e79fad8a892f8980
|
7
|
+
data.tar.gz: e8c40d4a7d339263074a3ad2240204f581f43069879d65fc38987f6d5bcd8cc5f83c090278e728fae608c9f81d7a2b1e76140622dbfd5bfc42c62f53a78556f0
|
data/Changes.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
reactor (0.
|
4
|
+
reactor (0.17.0)
|
5
5
|
rails
|
6
6
|
sidekiq (> 4.0)
|
7
7
|
|
@@ -70,11 +70,11 @@ GEM
|
|
70
70
|
mime-types (3.1)
|
71
71
|
mime-types-data (~> 3.2015)
|
72
72
|
mime-types-data (3.2016.0521)
|
73
|
-
mini_portile2 (2.
|
73
|
+
mini_portile2 (2.3.0)
|
74
74
|
minitest (5.10.2)
|
75
75
|
nio4r (2.1.0)
|
76
|
-
nokogiri (1.8.
|
77
|
-
mini_portile2 (~> 2.
|
76
|
+
nokogiri (1.8.1)
|
77
|
+
mini_portile2 (~> 2.3.0)
|
78
78
|
pry (0.10.4)
|
79
79
|
coderay (~> 1.1.0)
|
80
80
|
method_source (~> 0.8.1)
|
@@ -142,7 +142,7 @@ GEM
|
|
142
142
|
sprockets (3.7.1)
|
143
143
|
concurrent-ruby (~> 1.0)
|
144
144
|
rack (> 1, < 3)
|
145
|
-
sprockets-rails (3.2.
|
145
|
+
sprockets-rails (3.2.1)
|
146
146
|
actionpack (>= 4.0)
|
147
147
|
activesupport (>= 4.0)
|
148
148
|
sprockets (>= 3.0.0)
|
@@ -174,4 +174,4 @@ DEPENDENCIES
|
|
174
174
|
test_after_commit
|
175
175
|
|
176
176
|
BUNDLED WITH
|
177
|
-
1.15.
|
177
|
+
1.15.4
|
data/README.md
CHANGED
@@ -64,12 +64,19 @@ end
|
|
64
64
|
publishes :reminder_sent, at: :reminder_email_time, watch: :created_at
|
65
65
|
```
|
66
66
|
|
67
|
-
Scheduled events can check conditionally fire -- eg: in 2 days fire reminder_email if the user hasn't already responded.
|
67
|
+
Scheduled events can check conditionally fire -- eg: in 2 days fire reminder_email if the user hasn't already responded. Note that this check will occur at the time the event is intended to fire, after which the state of the model may have changed.
|
68
68
|
|
69
69
|
```ruby
|
70
70
|
publishes :reminder_sent, at: :reminder_email_time, if: -> { user.responded == false }
|
71
71
|
```
|
72
72
|
|
73
|
+
It is also possible to conditionally trigger events so that the check happens within the context of the model, at the moment an update occurs, rather than later in the context of the Reactor::Event
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
publishes :model_changed_in_some_important_way, enqueue_if: -> { important_change_occurred? }
|
77
|
+
```
|
78
|
+
|
79
|
+
|
73
80
|
#### Subscribable
|
74
81
|
|
75
82
|
You can now bind any block to an event in your models like so
|
@@ -234,6 +241,20 @@ end
|
|
234
241
|
|
235
242
|
for your testing convenience.
|
236
243
|
|
244
|
+
#### Matchers
|
245
|
+
|
246
|
+
You can clean up some event assertions with these somewhat imperfect matchers.
|
247
|
+
|
248
|
+
```
|
249
|
+
# DRY up strict event & data assertions.
|
250
|
+
expect { some_thing }.to publish_event(:some_event, actor: this_user, target: this_object)
|
251
|
+
```
|
252
|
+
|
253
|
+
```
|
254
|
+
# DRY up multi-event assertions. Unfortunately can't test key-values with this at the moment.
|
255
|
+
expect { some_thing }.to publish_events(:some_event, :another_event)
|
256
|
+
```
|
257
|
+
|
237
258
|
|
238
259
|
### Production Deployments
|
239
260
|
|
@@ -39,19 +39,29 @@ module Reactor::Publishable
|
|
39
39
|
|
40
40
|
def reschedule(name, data)
|
41
41
|
if data[:at]
|
42
|
-
|
43
|
-
data.
|
44
|
-
|
45
|
-
|
46
|
-
target: ( data[:target] ? self : nil),
|
47
|
-
was: previous_changes[data[:at]].try(:first) || send("#{data[:at]}_was"))
|
42
|
+
event = event_data_for_signature(data).merge(
|
43
|
+
was: previous_changes[data[:at]].try(:first) || send("#{data[:at]}_was")
|
44
|
+
)
|
45
|
+
Reactor::Event.reschedule(name, event) if should_fire_reactor_event?(data)
|
48
46
|
end
|
49
47
|
end
|
50
48
|
|
51
49
|
def schedule_events
|
52
50
|
self.class.events.each do |name, data|
|
53
51
|
event = event_data_for_signature(data)
|
54
|
-
Reactor::Event.publish
|
52
|
+
Reactor::Event.publish(name, event) if should_fire_reactor_event?(data)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def should_fire_reactor_event?(data, handler_name = :enqueue_if)
|
57
|
+
handler = data[handler_name]
|
58
|
+
case handler
|
59
|
+
when Proc
|
60
|
+
instance_exec(&handler)
|
61
|
+
when Symbol
|
62
|
+
send(handler)
|
63
|
+
when NilClass
|
64
|
+
true
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
@@ -60,6 +70,6 @@ module Reactor::Publishable
|
|
60
70
|
actor: (signature[:actor] ? send(signature[:actor]) : self),
|
61
71
|
target: (signature[:target] ? self : nil),
|
62
72
|
at: (signature[:at] ? send(signature[:at]) : nil)
|
63
|
-
).except(:watch)
|
73
|
+
).except(:watch, :enqueue_if)
|
64
74
|
end
|
65
75
|
end
|
@@ -1,3 +1,10 @@
|
|
1
|
+
#
|
2
|
+
# DRY up strict event & data assertions.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# expect { some_thing }.to publish_event(:some_event, actor: this_user, target: this_object)
|
7
|
+
#
|
1
8
|
RSpec::Matchers.define :publish_event do |name, data = {}|
|
2
9
|
supports_block_expectations
|
3
10
|
|
@@ -12,6 +19,14 @@ RSpec::Matchers.define :publish_event do |name, data = {}|
|
|
12
19
|
end
|
13
20
|
end
|
14
21
|
|
22
|
+
|
23
|
+
#
|
24
|
+
# DRY up multi-event assertions. Unfortunately can't test key-values with this at the moment.
|
25
|
+
#
|
26
|
+
# Example:
|
27
|
+
#
|
28
|
+
# expect { some_thing }.to publish_events(:some_event, :another_event)
|
29
|
+
#
|
15
30
|
RSpec::Matchers.define :publish_events do |*names|
|
16
31
|
supports_block_expectations
|
17
32
|
|
data/lib/reactor/version.rb
CHANGED
@@ -15,7 +15,8 @@ class Publisher < ActiveRecord::Base
|
|
15
15
|
publishes :bell
|
16
16
|
publishes :ring, at: :ring_timeout, watch: :start_at
|
17
17
|
publishes :begin, at: :start_at, additional_info: 'curtis was here'
|
18
|
-
publishes :conditional_event_on_save, at: :start_at,
|
18
|
+
publishes :conditional_event_on_save, at: :start_at, enqueue_if: -> { we_want_it }
|
19
|
+
publishes :conditional_event_on_publish, at: :start_at, if: -> { we_want_it }
|
19
20
|
publishes :woof, actor: :pet, target: :self
|
20
21
|
end
|
21
22
|
|
@@ -87,14 +88,14 @@ describe Reactor::Publishable do
|
|
87
88
|
)
|
88
89
|
end
|
89
90
|
|
90
|
-
context 'conditional firing' do
|
91
|
+
context 'conditional firing at publish time' do
|
91
92
|
before do
|
92
93
|
Sidekiq::Testing.fake!
|
93
94
|
Sidekiq::Worker.clear_all
|
94
|
-
TestSubscriber.create! event_name: :
|
95
|
+
TestSubscriber.create! event_name: :conditional_event_on_publish
|
95
96
|
publisher
|
96
97
|
job = Reactor::Event.jobs.detect do |job|
|
97
|
-
job['class'] == 'Reactor::Event' && job['args'].first == '
|
98
|
+
job['class'] == 'Reactor::Event' && job['args'].first == 'conditional_event_on_publish'
|
98
99
|
end
|
99
100
|
@job_args = job['args']
|
100
101
|
end
|
@@ -108,7 +109,7 @@ describe Reactor::Publishable do
|
|
108
109
|
publisher.start_at = 3.day.from_now
|
109
110
|
allow(Reactor::Event).to receive(:perform_at)
|
110
111
|
publisher.save!
|
111
|
-
expect(Reactor::Event).to have_received(:perform_at).with(publisher.start_at, :
|
112
|
+
expect(Reactor::Event).to have_received(:perform_at).with(publisher.start_at, :conditional_event_on_publish, anything())
|
112
113
|
|
113
114
|
Reactor::Event.perform(@job_args[0], @job_args[1])
|
114
115
|
end
|
@@ -125,7 +126,7 @@ describe Reactor::Publishable do
|
|
125
126
|
old_start_at = publisher.start_at
|
126
127
|
publisher.start_at = 3.day.from_now
|
127
128
|
allow(Reactor::Event).to receive(:publish)
|
128
|
-
expect(Reactor::Event).to receive(:publish).with(:
|
129
|
+
expect(Reactor::Event).to receive(:publish).with(:conditional_event_on_publish, {
|
129
130
|
at: publisher.start_at,
|
130
131
|
actor: publisher,
|
131
132
|
target: nil,
|
@@ -138,7 +139,7 @@ describe Reactor::Publishable do
|
|
138
139
|
it 'keeps the if intact when scheduling' do
|
139
140
|
start_at = 3.days.from_now
|
140
141
|
allow(Reactor::Event).to receive(:publish)
|
141
|
-
expect(Reactor::Event).to receive(:publish).with(:
|
142
|
+
expect(Reactor::Event).to receive(:publish).with(:conditional_event_on_publish, {
|
142
143
|
at: start_at,
|
143
144
|
actor: anything,
|
144
145
|
target: nil,
|
@@ -148,6 +149,59 @@ describe Reactor::Publishable do
|
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
152
|
+
context 'conditional firing on save' do
|
153
|
+
before do
|
154
|
+
Sidekiq::Testing.fake!
|
155
|
+
Sidekiq::Worker.clear_all
|
156
|
+
TestSubscriber.create! event_name: :conditional_event_on_save
|
157
|
+
publisher
|
158
|
+
job = Reactor::Event.jobs.detect do |job|
|
159
|
+
job['class'] == 'Reactor::Event' && job['args'].first == 'conditional_event_on_save'
|
160
|
+
end
|
161
|
+
@job_args = job ? job['args'] : []
|
162
|
+
end
|
163
|
+
|
164
|
+
after do
|
165
|
+
Sidekiq::Testing.inline!
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'does not call the subscriber when if is set to false' do
|
169
|
+
old_start_at = publisher.start_at
|
170
|
+
publisher.we_want_it = false
|
171
|
+
publisher.start_at = 3.days.from_now
|
172
|
+
allow(Reactor::Event).to receive(:publish)
|
173
|
+
expect(Reactor::Event).to_not receive(:reschedule).with(:conditional_event_on_save)
|
174
|
+
expect(Reactor::Event).to_not receive(:publish).with(:conditional_event_on_save)
|
175
|
+
publisher.save!
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'does rescheduling' do
|
179
|
+
old_start_at = publisher.start_at
|
180
|
+
publisher.we_want_it = true
|
181
|
+
publisher.start_at = 3.day.from_now
|
182
|
+
allow(Reactor::Event).to receive(:publish)
|
183
|
+
expect(Reactor::Event).to receive(:publish).with(:conditional_event_on_save, {
|
184
|
+
at: publisher.start_at,
|
185
|
+
actor: publisher,
|
186
|
+
target: nil,
|
187
|
+
was: old_start_at,
|
188
|
+
})
|
189
|
+
publisher.save!
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'does conditional scheduling scheduling' do
|
193
|
+
start_at = 3.days.from_now
|
194
|
+
allow(Reactor::Event).to receive(:publish)
|
195
|
+
expect(Reactor::Event).to receive(:publish).with(:conditional_event_on_save, {
|
196
|
+
at: start_at,
|
197
|
+
actor: anything,
|
198
|
+
target: nil,
|
199
|
+
})
|
200
|
+
Publisher.create!(start_at: start_at, we_want_it: true)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
|
151
205
|
it 'supports immediate events (on create) that get fired once' do
|
152
206
|
Reactor.with_subscriber_enabled(Reactor::Subscriber) do
|
153
207
|
TestSubscriber.create! event_name: :bell
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- winfred
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-12-18 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -266,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
266
266
|
version: '0'
|
267
267
|
requirements: []
|
268
268
|
rubyforge_project:
|
269
|
-
rubygems_version: 2.6.
|
269
|
+
rubygems_version: 2.6.11
|
270
270
|
signing_key:
|
271
271
|
specification_version: 4
|
272
272
|
summary: Sidekiq/ActiveRecord pubsub lib
|