clockwork 1.3.1 → 2.0.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: 66489a780e645c6b88fe4fe8548faaa80615d85c
4
- data.tar.gz: ad94d2f1a2f376d7f5931d177267b91ec6b69841
3
+ metadata.gz: 6614568ab73c78b0be1866b355ba1cd288cce5a6
4
+ data.tar.gz: a083d36f8fc30fb7b55f86278b1fd1e3577d4915
5
5
  SHA512:
6
- metadata.gz: 9b1409ea965916002991e9fd1a38d2453350994d027aa9b114a7f4feee4edb1a902ac07076c691d84e462fc9b697fe13989858f524184311d44d3717c7887aba
7
- data.tar.gz: 085f2739c059e90b8ea5875c0fb9b2eb161a7e09114cdd5db9a116a171fb5615db066278e65bfd641b78b1bac4cd77255438e8c27d94679d26bda66d4e2aa518
6
+ metadata.gz: dffa0ee3bcd26a2febaafebac063f71a46857001654b3748b292601f4134a9f64c0186b626bb72bc4c4d39eaec1a41e3c162d6ca5b64d53de248176854cd7915
7
+ data.tar.gz: 169d1db6499306e74dd86c89767e92818ffcc3d55873ac9dd04ddec9fe8b2d5648cb685e1dfbac4d3ad7bff4e467fcd2046e9c4cb0c680aef079906b354fd76a
data/README.md CHANGED
@@ -142,9 +142,9 @@ module Clockwork
142
142
  end
143
143
  ```
144
144
 
145
- This tells clockwork to fetch all `ClockworkDatabaseEvent` instances from the database, creating an internal clockwork event for each one, configured based on the instance's `frequency`, `at` and optionally `name` and `tz` methods. It also says to reload the events from the database every `1.minute`; we need pick up any changes in the database frequently (choose a sensible reload frequency by changing the `every:` option).
145
+ This tells clockwork to fetch all `ClockworkDatabaseEvent` instances from the database, and create an internal clockwork event for each one. Each clockwork event will be configured based on the instance's `frequency` and, optionally, its `at`, `name`, `if?` and `tz` methods. The code above also says to reload the events from the database every `1.minute`; we need pick up any changes in the database frequently (choose a sensible reload frequency by changing the `every:` option).
146
146
 
147
- When one of the events is ready to be run (based on it's `frequency`, `at` and possible `tz` methods), clockwork arranges for the block passed to `sync_database_events` to be run. The above example shows how you could use either DelayedJob or Sidekiq to simply kick off a worker job. This approach is good because the ideal is to use clockwork as a simple scheduler, and avoid making it carry out any long-running tasks.
147
+ When one of the events is ready to be run (based on it's `frequency`, and possible `at`, `if?` and `tz` methods), clockwork arranges for the block passed to `sync_database_events` to be run. The above example shows how you could use either DelayedJob or Sidekiq to kick off a worker job. This approach is good because the ideal is to use clockwork as a simple scheduler, and avoid making it carry out any long-running tasks.
148
148
 
149
149
  ### Your Model Classes
150
150
 
@@ -158,10 +158,14 @@ When one of the events is ready to be run (based on it's `frequency`, `at` and p
158
158
 
159
159
  - `frequency` returning the how frequently (in seconds) the database event should be run
160
160
 
161
- - `at` return nil or `''` if not using `:at`, or otherwise any acceptable clockwork `:at` string
161
+ - `attributes` returning a hash of [attribute name] => [attribute value] values (or really anything that we can use store on registering the event, and then compare again to see if the state has changed later)
162
+
163
+ - (optionally) `at` return any acceptable clockwork `:at` string
162
164
 
163
165
  - (optionally) `name` returning the name for the event (used to identify it in the Clcockwork output)
164
166
 
167
+ - (optionally) `if?` returning either true or false, depending on whether the database event should run at the given time (this method will be passed the time as a parameter, much like the standard clockwork `:if`)
168
+
165
169
  - (optionally) `tz` returning the timezone to use (default is the local timezone)
166
170
 
167
171
  #### Example Setup
@@ -220,6 +224,28 @@ end
220
224
  ...
221
225
  ```
222
226
 
227
+ #### Example use of `if?`
228
+
229
+ Database events support the ability to run events if certain conditions are met. This can be used to only run events on a given day, week, or month, or really any criteria you could conceive. Best of all, these criteria e.g. which day to
230
+ run it on can be attributes on your Model, and therefore change dynamically as you change the Model in the database.
231
+
232
+ So for example, if you had a Model that had a `day` and `month` integer attribute, you could specify that the Database event should only run on a particular day of a particular month as follows:
233
+
234
+ ```ruby
235
+ # app/models/clockwork_database_event.rb
236
+ class ClockworkDatabaseEvent < ActiveRecord::Base
237
+
238
+ ...
239
+
240
+ def if?(time)
241
+ time.day == day && time.month == month
242
+ end
243
+
244
+ ...
245
+ end
246
+ ```
247
+
248
+
223
249
  Event Parameters
224
250
  ----------
225
251
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "clockwork"
3
- s.version = "1.3.1"
3
+ s.version = "2.0.0"
4
4
 
5
5
  s.authors = ["Adam Wiggins", "tomykaira"]
6
6
  s.license = 'MIT'
@@ -4,12 +4,13 @@ module Clockwork
4
4
 
5
5
  class Event < Clockwork::Event
6
6
 
7
- attr_accessor :event_store, :at
7
+ attr_accessor :event_store, :model_attributes
8
8
 
9
- def initialize(manager, period, job, block, event_store, options={})
9
+ def initialize(manager, period, job, block, event_store, model_attributes, options={})
10
10
  super(manager, period, job, block, options)
11
11
  @event_store = event_store
12
12
  @event_store.register(self, job)
13
+ @model_attributes = model_attributes
13
14
  end
14
15
 
15
16
  def name
@@ -14,9 +14,7 @@ module Clockwork
14
14
  def has_changed?(model)
15
15
  return true if event.nil?
16
16
 
17
- (has_name? && name != model.name) ||
18
- frequency != model.frequency ||
19
- ats != model_ats(model)
17
+ event.model_attributes != model.attributes
20
18
  end
21
19
 
22
20
  def unregister
@@ -27,33 +25,12 @@ module Clockwork
27
25
 
28
26
  attr_reader :events, :manager
29
27
 
28
+ # All events in the same collection (for a model instance) are equivalent
29
+ # so we can use any of them. Only their @at variable will be different,
30
+ # but we don't care about that here.
30
31
  def event
31
32
  events.first
32
33
  end
33
-
34
- def has_name?
35
- event.job_has_name?
36
- end
37
-
38
- def name
39
- event.name
40
- end
41
-
42
- def frequency
43
- event.frequency
44
- end
45
-
46
- def ats
47
- events.collect(&:at).compact
48
- end
49
-
50
- def model_ats(model)
51
- at_strings_for(model).collect{|at| At.parse(at) }
52
- end
53
-
54
- def at_strings_for(model)
55
- model.at.to_s.split(',').map(&:strip)
56
- end
57
34
  end
58
35
  end
59
36
  end
@@ -112,11 +112,16 @@ module Clockwork
112
112
  options = {
113
113
  :from_database => true,
114
114
  :synchronizer => self,
115
- :at => at_strings_for(model)
116
115
  }
117
116
 
117
+ options[:at] = at_strings_for(model) if model.respond_to?(:at)
118
+ options[:if] = ->(time){ model.if?(time) } if model.respond_to?(:if?)
118
119
  options[:tz] = model.tz if model.respond_to?(:tz)
119
120
 
121
+ # store the state of the model at time of registering so we can
122
+ # easily compare and determine if state has changed later
123
+ options[:model_attributes] = model.attributes
124
+
120
125
  options
121
126
  end
122
127
 
@@ -10,7 +10,11 @@ module Clockwork
10
10
 
11
11
  def register(period, job, block, options)
12
12
  @events << if options[:from_database]
13
- Clockwork::DatabaseEvents::Event.new(self, period, job, (block || handler), options.fetch(:synchronizer), options)
13
+ synchronizer = options.fetch(:synchronizer)
14
+ model_attributes = options.fetch(:model_attributes)
15
+
16
+ Clockwork::DatabaseEvents::Event.
17
+ new(self, period, job, (block || handler), synchronizer, model_attributes, options)
14
18
  else
15
19
  Clockwork::Event.new(self, period, job, block || handler, options)
16
20
  end
@@ -23,6 +23,10 @@ module ActiveRecordFake
23
23
  set_attribute_values_from_options options
24
24
  end
25
25
 
26
+ def attributes
27
+ Hash[instance_variables.map { |name| [name, instance_variable_get(name)] } ]
28
+ end
29
+
26
30
  module ClassMethods
27
31
  def create *args
28
32
  new *args
@@ -10,8 +10,6 @@ require_relative 'test_helpers'
10
10
  describe Clockwork::DatabaseEvents::Synchronizer do
11
11
  before do
12
12
  @now = Time.now
13
- DatabaseEventModel.delete_all
14
- DatabaseEventModel2.delete_all
15
13
 
16
14
  Clockwork.manager = @manager = Clockwork::DatabaseEvents::Manager.new
17
15
  class << @manager
@@ -21,6 +19,9 @@ describe Clockwork::DatabaseEvents::Synchronizer do
21
19
 
22
20
  after do
23
21
  Clockwork.clear!
22
+ DatabaseEventModel.delete_all
23
+ DatabaseEventModel2.delete_all
24
+ DatabaseEventModelWithIf.delete_all
24
25
  end
25
26
 
26
27
  describe "setup" do
@@ -254,6 +255,37 @@ describe Clockwork::DatabaseEvents::Synchronizer do
254
255
  end
255
256
  end
256
257
 
258
+ describe "with model that responds to `if?`" do
259
+
260
+ before do
261
+ @events_run = []
262
+ end
263
+
264
+ describe "when model.if? is true" do
265
+ it 'runs' do
266
+ DatabaseEventModelWithIf.create(:if_state => true, :frequency => 10)
267
+ setup_sync(model: DatabaseEventModelWithIf, :every => 1.minute, :events_run => @events_run)
268
+
269
+ tick_at(@now, :and_every_second_for => 9.seconds)
270
+
271
+ assert_equal 1, @events_run.length
272
+ end
273
+ end
274
+
275
+ describe "when model.if? is false" do
276
+ it 'does not run' do
277
+ DatabaseEventModelWithIf.create(:if_state => false, :frequency => 10, :name => 'model with if?')
278
+ setup_sync(model: DatabaseEventModelWithIf, :every => 1.minute, :events_run => @events_run)
279
+
280
+ tick_at(@now, :and_every_second_for => 1.minute)
281
+
282
+ # require 'byebug'
283
+ # byebug if events_run.length > 0
284
+ assert_equal 0, @events_run.length
285
+ end
286
+ end
287
+ end
288
+
257
289
  describe "with task that responds to `tz`" do
258
290
  before do
259
291
  @events_run = []
@@ -55,4 +55,17 @@ end
55
55
  class DatabaseEventModelWithoutName
56
56
  include ActiveRecordFake
57
57
  attr_accessor :frequency, :at
58
+ end
59
+
60
+ class DatabaseEventModelWithIf
61
+ include ActiveRecordFake
62
+ attr_accessor :name, :frequency, :at, :tz, :if_state
63
+
64
+ def name
65
+ @name || "#{self.class}:#{id}"
66
+ end
67
+
68
+ def if?(time)
69
+ @if_state
70
+ end
58
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clockwork
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wiggins