clockwork 1.0.0 → 1.0.2
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/.ruby-version +1 -0
- data/README.md +1 -1
- data/clockwork.gemspec +1 -1
- data/lib/clockwork.rb +0 -19
- data/lib/clockwork/database_events/event.rb +1 -1
- data/test/database_events/support/active_record_fake.rb +66 -0
- data/test/database_events/sync_performer_test.rb +67 -53
- data/test/database_events/test_helpers.rb +16 -59
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4da3864c6de51bceab841eca257ffbc2926525a3
|
4
|
+
data.tar.gz: ff3ff9e0e1bef436a100785f818e57253bcc6f1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bbbb9668d0b1aa9526217188e50d6d5e44b493c25c7be369f98371038667434bbcd392a615ba73ec120001da0f0a89bb3faaf395245228484566029bdb6def5
|
7
|
+
data.tar.gz: dc8a6b4a47b174293f92e91066fb74d7c4ab1ad1310eb5c6c11d6706e381f8e435095e9b8d4f5ebbe8c9ed85bc7617f87b695c7153172a5f219c920e0997b91b
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.0
|
data/README.md
CHANGED
@@ -116,7 +116,7 @@ Here we're using an `ActiveRecord` model called `ClockworkDatabaseEvent` to stor
|
|
116
116
|
|
117
117
|
```ruby
|
118
118
|
require 'clockwork'
|
119
|
-
require 'clockwork/
|
119
|
+
require 'clockwork/database_events'
|
120
120
|
require_relative './config/boot'
|
121
121
|
require_relative './config/environment'
|
122
122
|
|
data/clockwork.gemspec
CHANGED
data/lib/clockwork.rb
CHANGED
@@ -53,22 +53,3 @@ module Clockwork
|
|
53
53
|
|
54
54
|
extend Methods
|
55
55
|
end
|
56
|
-
|
57
|
-
unless 1.respond_to?(:seconds)
|
58
|
-
class Numeric
|
59
|
-
def seconds; self; end
|
60
|
-
alias :second :seconds
|
61
|
-
|
62
|
-
def minutes; self * 60; end
|
63
|
-
alias :minute :minutes
|
64
|
-
|
65
|
-
def hours; self * 3600; end
|
66
|
-
alias :hour :hours
|
67
|
-
|
68
|
-
def days; self * 86400; end
|
69
|
-
alias :day :days
|
70
|
-
|
71
|
-
def weeks; self * 604800; end
|
72
|
-
alias :week :weeks
|
73
|
-
end
|
74
|
-
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ActiveRecordFake
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_variable_set(:@items, [])
|
5
|
+
base.instance_variable_set(:@next_id, 1)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
attr_accessor :id
|
11
|
+
|
12
|
+
def initialize options={}
|
13
|
+
@id = options.fetch(:id) { self.class.get_next_id }
|
14
|
+
set_attribute_values_from_options options.reject{|key, value| key == :id }
|
15
|
+
self.class.add self
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete!
|
19
|
+
self.class.remove(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update options={}
|
23
|
+
set_attribute_values_from_options options
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
def create *args
|
28
|
+
new *args
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_all
|
32
|
+
@items.clear
|
33
|
+
reset_id
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def all
|
38
|
+
@items.dup
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
def add instance
|
43
|
+
@items << instance
|
44
|
+
end
|
45
|
+
|
46
|
+
def remove instance
|
47
|
+
@items.delete(instance)
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_next_id
|
51
|
+
id = @next_id
|
52
|
+
@next_id += 1
|
53
|
+
id
|
54
|
+
end
|
55
|
+
|
56
|
+
def reset_id
|
57
|
+
@next_id = 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def set_attribute_values_from_options options
|
64
|
+
options.each{|attr, value| self.send("#{attr}=".to_sym, value) }
|
65
|
+
end
|
66
|
+
end
|
@@ -13,8 +13,8 @@ module DatabaseEvents
|
|
13
13
|
|
14
14
|
setup do
|
15
15
|
@now = Time.now
|
16
|
-
|
17
|
-
|
16
|
+
DatabaseEventModel.delete_all
|
17
|
+
DatabaseEventModel2.delete_all
|
18
18
|
|
19
19
|
Clockwork.manager = @manager = Clockwork::DatabaseEvents::Manager.new
|
20
20
|
class << @manager
|
@@ -29,7 +29,7 @@ module DatabaseEvents
|
|
29
29
|
|
30
30
|
describe "arguments" do
|
31
31
|
def test_does_not_raise_error_with_valid_arguments
|
32
|
-
@subject.setup(model:
|
32
|
+
@subject.setup(model: DatabaseEventModel, every: 1.minute) {}
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_raises_argument_error_if_model_is_not_set
|
@@ -41,7 +41,7 @@ module DatabaseEvents
|
|
41
41
|
|
42
42
|
def test_raises_argument_error_if_every_is_not_set
|
43
43
|
error = assert_raises KeyError do
|
44
|
-
@subject.setup(model:
|
44
|
+
@subject.setup(model: DatabaseEventModel) {}
|
45
45
|
end
|
46
46
|
assert_equal error.message, ":every must be set to the database sync frequency"
|
47
47
|
end
|
@@ -54,35 +54,35 @@ module DatabaseEvents
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def test_fetches_and_registers_event_from_database
|
57
|
-
|
58
|
-
setup_sync(model:
|
57
|
+
DatabaseEventModel.create(:frequency => 10)
|
58
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
59
59
|
|
60
60
|
tick_at(@now, :and_every_second_for => 1.second)
|
61
61
|
|
62
|
-
assert_equal ["
|
62
|
+
assert_equal ["DatabaseEventModel:1"], @events_run
|
63
63
|
end
|
64
64
|
|
65
65
|
def test_multiple_events_from_database_can_be_registered
|
66
|
-
|
67
|
-
|
68
|
-
setup_sync(model:
|
66
|
+
DatabaseEventModel.create(:frequency => 10)
|
67
|
+
DatabaseEventModel.create(:frequency => 10)
|
68
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
69
69
|
|
70
70
|
tick_at(@now, :and_every_second_for => 1.second)
|
71
71
|
|
72
|
-
assert_equal ["
|
72
|
+
assert_equal ["DatabaseEventModel:1", "DatabaseEventModel:2"], @events_run
|
73
73
|
end
|
74
74
|
|
75
75
|
def test_event_from_database_does_not_run_again_before_frequency_specified_in_database
|
76
|
-
model =
|
77
|
-
setup_sync(model:
|
76
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
77
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
78
78
|
|
79
79
|
tick_at(@now, :and_every_second_for => model.frequency - 1.second)
|
80
80
|
assert_equal 1, @events_run.length
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_event_from_database_runs_repeatedly_with_frequency_specified_in_database
|
84
|
-
model =
|
85
|
-
setup_sync(model:
|
84
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
85
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
86
86
|
|
87
87
|
tick_at(@now, :and_every_second_for => (2 * model.frequency) + 1.second)
|
88
88
|
|
@@ -90,21 +90,19 @@ module DatabaseEvents
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def test_reloaded_events_from_database_run_repeatedly
|
93
|
-
model =
|
94
|
-
setup_sync(model:
|
93
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
94
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
95
95
|
|
96
96
|
tick_at(@now, :and_every_second_for => @sync_frequency - 1)
|
97
|
-
|
98
|
-
model.update(:name => "DatabaseEventModelClass:1:Reloaded")
|
99
|
-
|
97
|
+
model.update(:name => "DatabaseEventModel:1:Reloaded")
|
100
98
|
tick_at(@now + @sync_frequency, :and_every_second_for => model.frequency * 2)
|
101
99
|
|
102
|
-
assert_equal ["
|
100
|
+
assert_equal ["DatabaseEventModel:1:Reloaded", "DatabaseEventModel:1:Reloaded"], @events_run[-2..-1]
|
103
101
|
end
|
104
102
|
|
105
103
|
def test_reloading_events_from_database_with_modified_frequency_will_run_with_new_frequency
|
106
|
-
model =
|
107
|
-
setup_sync(model:
|
104
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
105
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
108
106
|
|
109
107
|
tick_at(@now, :and_every_second_for => @sync_frequency - 1.second)
|
110
108
|
model.update(:frequency => 5)
|
@@ -117,8 +115,8 @@ module DatabaseEvents
|
|
117
115
|
end
|
118
116
|
|
119
117
|
def test_stops_running_deleted_events_from_database
|
120
|
-
model =
|
121
|
-
setup_sync(model:
|
118
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
119
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
122
120
|
|
123
121
|
tick_at(@now, :and_every_second_for => (@sync_frequency - 1.second))
|
124
122
|
before = @events_run.dup
|
@@ -130,20 +128,20 @@ module DatabaseEvents
|
|
130
128
|
end
|
131
129
|
|
132
130
|
def test_event_from_database_with_edited_name_switches_to_new_name
|
133
|
-
model =
|
134
|
-
setup_sync(model:
|
131
|
+
model = DatabaseEventModel.create(:frequency => 10.seconds)
|
132
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
135
133
|
|
136
134
|
tick_at @now, :and_every_second_for => @sync_frequency - 1.second
|
137
135
|
@events_run.clear
|
138
|
-
model.update(:name => "
|
136
|
+
model.update(:name => "DatabaseEventModel:1_modified")
|
139
137
|
tick_at @now + @sync_frequency, :and_every_second_for => (model.frequency * 2)
|
140
138
|
|
141
|
-
assert_equal ["
|
139
|
+
assert_equal ["DatabaseEventModel:1_modified", "DatabaseEventModel:1_modified"], @events_run
|
142
140
|
end
|
143
141
|
|
144
142
|
def test_event_from_database_with_edited_frequency_switches_to_new_frequency
|
145
|
-
model =
|
146
|
-
setup_sync(model:
|
143
|
+
model = DatabaseEventModel.create(:frequency => 10)
|
144
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
147
145
|
|
148
146
|
tick_at @now, :and_every_second_for => @sync_frequency - 1.second
|
149
147
|
@events_run.clear
|
@@ -154,8 +152,8 @@ module DatabaseEvents
|
|
154
152
|
end
|
155
153
|
|
156
154
|
def test_event_from_database_with_edited_at_runs_at_new_at
|
157
|
-
model =
|
158
|
-
setup_sync(model:
|
155
|
+
model = DatabaseEventModel.create(:frequency => 1.day, :at => '10:30')
|
156
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
159
157
|
|
160
158
|
assert_will_run 'jan 1 2010 10:30:00'
|
161
159
|
assert_wont_run 'jan 1 2010 09:30:00'
|
@@ -167,19 +165,35 @@ module DatabaseEvents
|
|
167
165
|
assert_wont_run 'jan 1 2010 10:30:00'
|
168
166
|
end
|
169
167
|
|
170
|
-
|
171
|
-
|
172
|
-
|
168
|
+
context "when #name is defined" do
|
169
|
+
def test_daily_event_from_database_with_at_should_only_run_once
|
170
|
+
DatabaseEventModel.create(:frequency => 1.day, :at => next_minute(@now).strftime('%H:%M'))
|
171
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
173
172
|
|
174
|
-
|
175
|
-
|
173
|
+
# tick from now, though specified :at time
|
174
|
+
tick_at(@now, :and_every_second_for => (2 * @sync_frequency) + 1.second)
|
175
|
+
|
176
|
+
assert_equal 1, @events_run.length
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "when #name is not defined" do
|
181
|
+
|
182
|
+
def test_daily_event_from_database_with_at_should_only_run_once
|
183
|
+
DatabaseEventModelWithoutName.create(:frequency => 1.day, :at => next_minute(next_minute(@now)).strftime('%H:%M'))
|
184
|
+
setup_sync(model: DatabaseEventModelWithoutName, :every => @sync_frequency, :events_run => @events_run)
|
185
|
+
|
186
|
+
# tick from now, though specified :at time
|
187
|
+
tick_at(@now, :and_every_second_for => (2 * @sync_frequency) + 1.second)
|
188
|
+
|
189
|
+
assert_equal 1, @events_run.length
|
190
|
+
end
|
176
191
|
|
177
|
-
assert_equal 1, @events_run.length
|
178
192
|
end
|
179
193
|
|
180
|
-
def
|
181
|
-
|
182
|
-
setup_sync(model:
|
194
|
+
def test_event_from_database_with_comma_separated_at_leads_to_multiple_event_ats
|
195
|
+
DatabaseEventModel.create(:frequency => 1.day, :at => '16:20, 18:10')
|
196
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
183
197
|
|
184
198
|
tick_at @now, :and_every_second_for => 1.second
|
185
199
|
|
@@ -193,15 +207,15 @@ module DatabaseEvents
|
|
193
207
|
end
|
194
208
|
|
195
209
|
def test_syncing_multiple_database_models_works
|
196
|
-
|
197
|
-
setup_sync(model:
|
210
|
+
DatabaseEventModel.create(:frequency => 10)
|
211
|
+
setup_sync(model: DatabaseEventModel, :every => @sync_frequency, :events_run => @events_run)
|
198
212
|
|
199
|
-
|
200
|
-
setup_sync(model:
|
213
|
+
DatabaseEventModel2.create(:frequency => 10)
|
214
|
+
setup_sync(model: DatabaseEventModel2, :every => @sync_frequency, :events_run => @events_run)
|
201
215
|
|
202
216
|
tick_at(@now, :and_every_second_for => 1.second)
|
203
217
|
|
204
|
-
assert_equal ["
|
218
|
+
assert_equal ["DatabaseEventModel:1", "DatabaseEventModel2:1"], @events_run
|
205
219
|
end
|
206
220
|
end
|
207
221
|
|
@@ -211,8 +225,8 @@ module DatabaseEvents
|
|
211
225
|
end
|
212
226
|
|
213
227
|
def test_the_event_only_runs_once_within_the_model_frequency_period
|
214
|
-
|
215
|
-
setup_sync(model:
|
228
|
+
DatabaseEventModel.create(:frequency => 5.minutes)
|
229
|
+
setup_sync(model: DatabaseEventModel, :every => 1.minute, :events_run => @events_run)
|
216
230
|
|
217
231
|
tick_at(@now, :and_every_second_for => 5.minutes)
|
218
232
|
|
@@ -224,8 +238,8 @@ module DatabaseEvents
|
|
224
238
|
setup do
|
225
239
|
@events_run = []
|
226
240
|
|
227
|
-
|
228
|
-
setup_sync(model:
|
241
|
+
DatabaseEventModel.create(:frequency => 10)
|
242
|
+
setup_sync(model: DatabaseEventModel, :every => 1.minute, :events_run => @events_run)
|
229
243
|
end
|
230
244
|
|
231
245
|
def test_it_does_not_raise_an_error
|
@@ -250,8 +264,8 @@ module DatabaseEvents
|
|
250
264
|
@events_run = []
|
251
265
|
@utc_time_now = Time.now.utc
|
252
266
|
|
253
|
-
|
254
|
-
setup_sync(model:
|
267
|
+
DatabaseEventModel.create(:frequency => 1.days, :at => @utc_time_now.strftime('%H:%M'), :tz => 'America/Montreal')
|
268
|
+
setup_sync(model: DatabaseEventModel, :every => 1.minute, :events_run => @events_run)
|
255
269
|
end
|
256
270
|
|
257
271
|
def test_it_does_not_raise_an_error
|
@@ -1,10 +1,13 @@
|
|
1
|
+
require_relative 'support/active_record_fake'
|
2
|
+
|
1
3
|
def setup_sync(options={})
|
2
4
|
model_class = options.fetch(:model) { raise KeyError, ":model must be set to the model class" }
|
3
5
|
frequency = options.fetch(:every) { raise KeyError, ":every must be set to the database sync frequency" }
|
4
6
|
events_run = options.fetch(:events_run) { raise KeyError, ":events_run must be provided"}
|
5
7
|
|
6
8
|
Clockwork::DatabaseEvents::SyncPerformer.setup model: model_class, every: frequency do |model|
|
7
|
-
|
9
|
+
name = model.respond_to?(:name) ? model.name : model.to_s
|
10
|
+
events_run << name
|
8
11
|
end
|
9
12
|
end
|
10
13
|
|
@@ -31,71 +34,25 @@ def normalize_time t
|
|
31
34
|
end
|
32
35
|
|
33
36
|
|
34
|
-
class
|
35
|
-
|
36
|
-
|
37
|
-
class << self
|
38
|
-
def create *args
|
39
|
-
new *args
|
40
|
-
end
|
41
|
-
|
42
|
-
def add instance
|
43
|
-
@events << instance
|
44
|
-
end
|
45
|
-
|
46
|
-
def remove instance
|
47
|
-
@events.delete(instance)
|
48
|
-
end
|
49
|
-
|
50
|
-
def next_id
|
51
|
-
id = @next_id
|
52
|
-
@next_id += 1
|
53
|
-
id
|
54
|
-
end
|
55
|
-
|
56
|
-
def reset_id
|
57
|
-
@next_id = 1
|
58
|
-
end
|
59
|
-
|
60
|
-
def delete_all
|
61
|
-
@events.clear
|
62
|
-
reset_id
|
63
|
-
end
|
64
|
-
|
65
|
-
def all
|
66
|
-
@events.dup
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def initialize options={}
|
71
|
-
@id = options.fetch(:id) { self.class.next_id }
|
72
|
-
@name = options.fetch(:name) { nil }
|
73
|
-
@at = options.fetch(:at) { nil }
|
74
|
-
@frequency = options.fetch(:frequency) { raise KeyError, ":every must be supplied" }
|
75
|
-
@tz = options.fetch(:tz) { nil }
|
76
|
-
|
77
|
-
self.class.add self
|
78
|
-
end
|
37
|
+
class DatabaseEventModel
|
38
|
+
include ActiveRecordFake
|
39
|
+
attr_accessor :name, :frequency, :at, :tz
|
79
40
|
|
80
41
|
def name
|
81
42
|
@name || "#{self.class}:#{id}"
|
82
43
|
end
|
44
|
+
end
|
83
45
|
|
84
|
-
|
85
|
-
|
86
|
-
|
46
|
+
class DatabaseEventModel2
|
47
|
+
include ActiveRecordFake
|
48
|
+
attr_accessor :name, :frequency, :at, :tz
|
87
49
|
|
88
|
-
def
|
89
|
-
|
50
|
+
def name
|
51
|
+
@name || "#{self.class}:#{id}"
|
90
52
|
end
|
91
53
|
end
|
92
54
|
|
93
|
-
class
|
94
|
-
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
class DatabaseEventModelClass2 < ActiveRecordFake
|
99
|
-
@events = []
|
100
|
-
@next_id = 1
|
55
|
+
class DatabaseEventModelWithoutName
|
56
|
+
include ActiveRecordFake
|
57
|
+
attr_accessor :frequency, :at
|
101
58
|
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.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-11-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tzinfo
|
@@ -136,6 +136,7 @@ extra_rdoc_files:
|
|
136
136
|
- README.md
|
137
137
|
files:
|
138
138
|
- ".gitignore"
|
139
|
+
- ".ruby-version"
|
139
140
|
- ".travis.yml"
|
140
141
|
- Gemfile
|
141
142
|
- LICENSE
|
@@ -159,6 +160,7 @@ files:
|
|
159
160
|
- lib/clockwork/manager.rb
|
160
161
|
- test/at_test.rb
|
161
162
|
- test/clockwork_test.rb
|
163
|
+
- test/database_events/support/active_record_fake.rb
|
162
164
|
- test/database_events/sync_performer_test.rb
|
163
165
|
- test/database_events/test_helpers.rb
|
164
166
|
- test/event_test.rb
|
@@ -183,13 +185,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
185
|
version: '0'
|
184
186
|
requirements: []
|
185
187
|
rubyforge_project:
|
186
|
-
rubygems_version: 2.2.
|
188
|
+
rubygems_version: 2.2.2
|
187
189
|
signing_key:
|
188
190
|
specification_version: 4
|
189
191
|
summary: A scheduler process to replace cron.
|
190
192
|
test_files:
|
191
193
|
- test/at_test.rb
|
192
194
|
- test/clockwork_test.rb
|
195
|
+
- test/database_events/support/active_record_fake.rb
|
193
196
|
- test/database_events/sync_performer_test.rb
|
194
197
|
- test/database_events/test_helpers.rb
|
195
198
|
- test/event_test.rb
|