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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8362bfb2d624d7faccf2571ebd5bd622cd88945a
4
- data.tar.gz: c62cfe20ff087e4d012dabf64076c034d3e3c702
3
+ metadata.gz: bc723686f416100ec5c50b2ff2ccd1893f4c3076
4
+ data.tar.gz: 876912b1d837da0b05da0349249811d31e3b82ea
5
5
  SHA512:
6
- metadata.gz: 0f026cd77012cd13c06be293f02ef47ff82a660294f449aab2c4e191cffb048aec4f791497ab0f67a8e2680a58c0fbee17ee6b0197ba0d1e946b2452ff13b7d1
7
- data.tar.gz: fe1f845c5f003447464de076ba4a5e5dcc8c5f64a0dea9164730628f5c1f9fd713d7ca918af73e1daf717143c465b15963737fbe5a594fec5a010fad4154a1ea
6
+ metadata.gz: 47a87bcef246a5440a573976eac9eb4cc8051938322e0142379ae5f9bff742d97a42fc37ba042380e2895598bc58cc6508c426fb2abf85e2e79fad8a892f8980
7
+ data.tar.gz: e8c40d4a7d339263074a3ad2240204f581f43069879d65fc38987f6d5bcd8cc5f83c090278e728fae608c9f81d7a2b1e76140622dbfd5bfc42c62f53a78556f0
data/Changes.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Reactor Change Log
2
2
 
3
+ 0.17.0
4
+ ----------
5
+ `publishes` method in publishable now accepts `:enqueue_if` option
6
+
3
7
  0.16.0
4
8
  ----------
5
9
  Subscribers can now deprecate themselves for safe removal from production deployments.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- reactor (0.16.1)
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.2.0)
73
+ mini_portile2 (2.3.0)
74
74
  minitest (5.10.2)
75
75
  nio4r (2.1.0)
76
- nokogiri (1.8.0)
77
- mini_portile2 (~> 2.2.0)
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.0)
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.3
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
- Reactor::Event.reschedule name,
43
- data.merge(
44
- at: send(data[:at]),
45
- actor: ( data[:actor] ? send(data[:actor]) : self ),
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 name, event
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
 
@@ -1,3 +1,3 @@
1
1
  module Reactor
2
- VERSION = "0.16.1"
2
+ VERSION = "0.17.0"
3
3
  end
@@ -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, if: -> { we_want_it }
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: :conditional_event_on_save
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 == 'conditional_event_on_save'
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, :conditional_event_on_save, anything())
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(:conditional_event_on_save, {
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(:conditional_event_on_save, {
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.16.1
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-08-18 00:00:00.000000000 Z
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.12
269
+ rubygems_version: 2.6.11
270
270
  signing_key:
271
271
  specification_version: 4
272
272
  summary: Sidekiq/ActiveRecord pubsub lib