clockwork 0.7.3 → 0.7.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fae14bd8566db2cb7c3be8c5c9625b01dc66ae00
4
- data.tar.gz: ecbed0c0a9cf6017a0e62f62da9cfb67112624da
3
+ metadata.gz: bb04c64391be1de07e805c05256430c06c1d0da6
4
+ data.tar.gz: 3804849a9e343ce52d62609390da392ccb2c6274
5
5
  SHA512:
6
- metadata.gz: c75686b464777f74d87ca6b15d3ac1d57ee83f190e22d32c6b585fecb86c5192575f90d6151588e9454f7d3f8054bd1c63f3fa4d6a3a067f1d93bbd10a14fe4a
7
- data.tar.gz: c68c69e967a99422394197ed570c2c0ce0968e73a7495ec44a55158b99a6c6450a84fd3160d4707d95c5385ddc00b584f4fb350a6b0566b44222f8201215c504
6
+ metadata.gz: d3adf3511969f14520a4d3273dbf3555d690a8a2cb467e217825ce66f8cae9d8cae3c1431f31784ff987061c6acff1c8e081b91bebac858e96ac8013d071a67d
7
+ data.tar.gz: 06a2920e423ecf3f656b2b5f10ad5a8a32cf5bff46a55a12416b94f77bd484b3bf443a3cfdde7267e89a011cc282ef2580ae883191b167918f23cc6e9383c833
data/README.md CHANGED
@@ -136,7 +136,7 @@ module Clockwork
136
136
  end
137
137
  ```
138
138
 
139
- This tells clockwork to fetch all MyScheduledTask instances from the database, and create an event for each, configured based on the instances' `frequency`, `name`, and `at` methods. It also says to reload the tasks from the database every 1.minute - we need to frequently do this as they could have changed (but you can choose a sensible reload frequency by changing the `every:` option). Note that the database sync event will always run on the minute-boundary (i.e. HH:MM::00), and that events which have been synced from the database won't be run in that same clock cycle (this prevents a task from the database being run twice).
139
+ This tells clockwork to fetch all MyScheduledTask instances from the database, and create an event for each, configured based on the instances' `frequency`, `name`, and `at` methods. It also says to reload the tasks from the database every 1.minute - we need to frequently do this as they could have changed (but you can choose a sensible reload frequency by changing the `every:` option).
140
140
 
141
141
  Rails ActiveRecord models are a perfect candidate for the model class, but you could use something else. The only requirements are:
142
142
 
@@ -144,7 +144,7 @@ Rails ActiveRecord models are a perfect candidate for the model class, but you c
144
144
  2. the instances returned respond to:
145
145
  `frequency` returning the how frequently (in seconds) the database task should be run
146
146
  `name` returning the task's job name (this is what gets passed into the block above)
147
- `at` return nil or '' if not using :at, or any acceptable clockwork :at string
147
+ `at` return nil or `''` if not using `:at`, or otherwise any acceptable clockwork `:at` string
148
148
 
149
149
  Here's an example of one way of setting up your ActiveRecord models, using Sidekiq for background tasks, and making the model class a worker:
150
150
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "clockwork"
3
- s.version = "0.7.3"
3
+ s.version = "0.7.4"
4
4
 
5
5
  s.authors = ["Adam Wiggins", "tomykaira"]
6
6
  s.license = 'MIT'
@@ -8,14 +8,71 @@ module Clockwork
8
8
 
9
9
  extend Methods
10
10
 
11
- class ManagerWithDatabaseTasks < Manager
11
+ class DatabaseEventSyncPerformer
12
+
13
+ def initialize(manager, model, proc)
14
+ @manager = manager
15
+ @model = model
16
+ @block = proc
17
+ @events = {}
18
+ end
19
+
20
+ # Ensure clockwork events reflect database tasks
21
+ # Adds any new tasks, modifies updated ones, and delets removed ones
22
+ def sync
23
+ model_ids_that_exist = []
24
+
25
+ @model.all.each do |db_task|
26
+ model_ids_that_exist << db_task.id
27
+
28
+ if !event_exists_for_task(db_task) || db_task_has_changed(db_task)
29
+ create_event_for_database_task(db_task)
30
+ end
31
+ end
32
+
33
+ remove_deleted_database_tasks(model_ids_that_exist)
34
+ end
35
+
36
+ def events
37
+ @events.values
38
+ end
12
39
 
13
- SECOND_TO_RUN_DATABASE_SYNC_AT = 0
40
+ def add_event(e, task_id)
41
+ @events[task_id] = e
42
+ end
43
+
44
+ protected
45
+
46
+ def create_event_for_database_task(db_task)
47
+ options = {
48
+ :from_database => true,
49
+ :db_task_id => db_task.id,
50
+ :performer => self,
51
+ :at => db_task.at.blank? ? nil : db_task.at.split(',')
52
+ }
53
+
54
+ @manager.every db_task.frequency, db_task.name, options, &@block
55
+ end
56
+
57
+ def event_exists_for_task(db_task)
58
+ @events[db_task.id]
59
+ end
60
+
61
+ def remove_deleted_database_tasks(model_ids_that_exist)
62
+ @events.reject!{|db_task_id, _| !model_ids_that_exist.include?(db_task_id) }
63
+ end
64
+
65
+ def db_task_has_changed(task)
66
+ event = @events[task.id]
67
+ task.name != event.job || task.frequency != event.instance_variable_get(:@period)
68
+ end
69
+ end
70
+
71
+ class ManagerWithDatabaseTasks < Manager
14
72
 
15
73
  def initialize
16
74
  super
17
- @events_from_database = []
18
- @next_sync_database_tasks_identifier = 0
75
+ @database_event_sync_performers = []
19
76
  end
20
77
 
21
78
  def sync_database_tasks(options={}, &block)
@@ -24,64 +81,33 @@ module Clockwork
24
81
  end
25
82
  raise ArgumentError.new(":every must be greater or equal to 1.minute") if options[:every] < 1.minute
26
83
 
27
- model = options[:model]
28
- frequency = options[:every]
29
- sync_task_id = get_sync_task_id
30
-
31
- # Prevent database tasks from running in same cycle as the database sync,
32
- # as this can lead to the same task being run twice
33
- options_to_run_database_sync_in_own_cycle = { :if => lambda { |t| t.sec == SECOND_TO_RUN_DATABASE_SYNC_AT } }
84
+ sync_performer = DatabaseEventSyncPerformer.new(self, options[:model], block)
85
+ @database_event_sync_performers << sync_performer
34
86
 
35
87
  # create event that syncs clockwork events with database events
36
- every frequency, "sync_database_tasks_for_model_#{model}", options_to_run_database_sync_in_own_cycle do
37
- reload_events_from_database sync_task_id, model, &block
88
+ every options[:every], "sync_database_tasks_for_model_#{options[:model]}" do
89
+ sync_performer.sync
38
90
  end
39
91
  end
40
92
 
93
+ private
41
94
 
42
- protected
43
-
44
- # sync_task_id's are used to group the database events from a particular sync_database_tasks call
45
- # This method hands out the ids, incrementing the id to keep them unique.
46
- def get_sync_task_id
47
- current_sync_task_id = @next_sync_database_tasks_identifier
48
- @next_sync_database_tasks_identifier += 1
49
- current_sync_task_id
50
- end
51
-
52
- def reload_events_from_database(sync_task_id, model, &block)
53
- @events_from_database[sync_task_id] = []
54
-
55
- model.all.each do |db_task|
56
- options = { from_database: true, :sync_task_id => sync_task_id }
57
- options[:at] = db_task.at.split(',') unless db_task.at.blank?
58
-
59
- # If database tasks can be scheduled in same clock cycle that database syncs occur
60
- # then previous copy of database sync task will be stored and set to run (in #tick events variable)
61
- # *before* we then delete all database tasks. This causes the task to be run at HH:00 (previous copy)
62
- # and at HH:01 (newly fetched copy).
63
- option_to_prevent_database_tasks_running_in_same_cycle_as_sync = { :if => lambda{|t| t.sec != SECOND_TO_RUN_DATABASE_SYNC_AT } }
64
- every db_task.frequency,
65
- db_task.name,
66
- options.merge(option_to_prevent_database_tasks_running_in_same_cycle_as_sync),
67
- &block
68
- end
95
+ def events_from_database_as_array
96
+ @database_event_sync_performers.collect{|performer| performer.events}.flatten
69
97
  end
70
98
 
71
- private
72
-
73
99
  def events_to_run(t)
74
- (@events + @events_from_database.flatten).select{|event| event.run_now?(t) }
100
+ (@events + events_from_database_as_array).select{|event| event.run_now?(t) }
75
101
  end
76
102
 
77
103
  def register(period, job, block, options)
78
- event = Event.new(self, period, job, block || handler, options)
79
- if options[:from_database]
80
- @events_from_database[options[:sync_task_id]] << event
81
- else
82
- @events << event
104
+ Event.new(self, period, job, block || handler, options).tap do |e|
105
+ if options[:from_database]
106
+ options[:performer].add_event(e, options[:db_task_id])
107
+ else
108
+ @events << e
109
+ end
83
110
  end
84
- event
85
111
  end
86
112
  end
87
113
  end
@@ -56,135 +56,160 @@ class ManagerWithDatabaseTasksTest < Test::Unit::TestCase
56
56
  end
57
57
  end
58
58
 
59
- setup do
60
- @tasks_run = []
61
- @scheduled_task1 = stub(:frequency => 10, :name => 'ScheduledTask:1', :at => nil)
62
- @scheduled_task2 = stub(:frequency => 10, :name => 'ScheduledTask:2', :at => nil)
63
- @scheduled_task1_modified = stub(:frequency => 5, :name => 'ScheduledTaskModified:1', :at => nil)
64
- ScheduledTask.stubs(:all).returns([@scheduled_task1])
59
+ context "when database reload frequency is greater than task frequency period" do
60
+ setup do
61
+ @tasks_run = []
62
+ @scheduled_task1 = stub(:frequency => 10, :name => 'ScheduledTask:1', :at => nil, :id => 1)
63
+ @scheduled_task2 = stub(:frequency => 10, :name => 'ScheduledTask:2', :at => nil, :id => 2)
64
+ @scheduled_task1_modified = stub(:frequency => 5, :name => 'ScheduledTaskModified:1', :at => nil, :id => 3)
65
+ ScheduledTask.stubs(:all).returns([@scheduled_task1])
65
66
 
66
- @database_reload_frequency = 1.minute
67
+ @database_reload_frequency = 1.minute
67
68
 
68
- @now = Time.now
69
- @next_minute = next_minute(@now) # database sync task only happens on minute boundary
69
+ @now = Time.now
70
70
 
71
- # setup the database sync
72
- @manager.sync_database_tasks model: ScheduledTask, every: @database_reload_frequency do |job_name|
73
- @tasks_run << job_name
71
+ # setup the database sync
72
+ @manager.sync_database_tasks model: ScheduledTask, every: @database_reload_frequency do |job_name|
73
+ @tasks_run << job_name
74
+ end
74
75
  end
75
- end
76
76
 
77
- def test_does_not_fetch_database_tasks_until_next_minute
78
- seconds_upto_and_including_next_minute = (@next_minute - @now).seconds.to_i + 1
79
- tick_at(@now, :and_every_second_for => seconds_upto_and_including_next_minute)
80
- assert_equal [], @tasks_run
81
- end
77
+ def test_fetches_and_registers_database_task
78
+ tick_at(@now, :and_every_second_for => 1.second)
79
+ assert_equal ["ScheduledTask:1"], @tasks_run
80
+ end
82
81
 
83
- def test_fetches_and_registers_database_task
84
- tick_at(@next_minute, :and_every_second_for => 1.second)
85
- assert_equal ["ScheduledTask:1"], @tasks_run
86
- end
82
+ def test_multiple_database_tasks_can_be_registered
83
+ ScheduledTask.stubs(:all).returns([@scheduled_task1, @scheduled_task2])
84
+ tick_at(@now, :and_every_second_for => 1.second)
85
+ assert_equal ["ScheduledTask:1", "ScheduledTask:2"], @tasks_run
86
+ end
87
87
 
88
- def test_multiple_database_tasks_can_be_registered
89
- ScheduledTask.stubs(:all).returns([@scheduled_task1, @scheduled_task2])
90
- tick_at(@next_minute, :and_every_second_for => 1.second)
91
- assert_equal ["ScheduledTask:1", "ScheduledTask:2"], @tasks_run
92
- end
88
+ def test_database_task_does_not_run_again_before_frequency_specified_in_database
89
+ tick_at(@now, :and_every_second_for => @scheduled_task1.frequency - 1.second) # runs at 1
90
+ assert_equal 1, @tasks_run.length
91
+ end
93
92
 
94
- def test_database_task_does_not_run_again_before_frequency_specified_in_database
95
- tick_at(@next_minute, :and_every_second_for => 9.seconds) # runs at 1
96
- assert_equal 1, @tasks_run.length
97
- end
93
+ def test_database_task_runs_repeatedly_with_frequency_specified_in_database
94
+ tick_at(@now, :and_every_second_for => (2 * @scheduled_task1.frequency) + 1.second) # runs at 1, 11, and 21
95
+ assert_equal 3, @tasks_run.length
96
+ end
98
97
 
99
- def test_database_task_runs_repeatedly_with_frequency_specified_in_database
100
- tick_at(@next_minute, :and_every_second_for => 21.seconds) # runs at 1, 11, and 21
101
- assert_equal 3, @tasks_run.length
102
- end
98
+ def test_reloads_tasks_from_database
99
+ ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task2])
100
+ tick_at(@now, :and_every_second_for => @database_reload_frequency.seconds)
101
+ @manager.tick # @scheduled_task2 should run immediately on next tick (then every 10 seconds)
102
+
103
+ assert_equal [
104
+ "ScheduledTask:1",
105
+ "ScheduledTask:1",
106
+ "ScheduledTask:1",
107
+ "ScheduledTask:1",
108
+ "ScheduledTask:1",
109
+ "ScheduledTask:1",
110
+ "ScheduledTask:2"], @tasks_run
111
+ end
103
112
 
104
- def test_reloads_tasks_from_database
105
- ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task2])
106
- tick_at(@next_minute, :and_every_second_for => @database_reload_frequency.seconds)
107
- @manager.tick # @scheduled_task2 should run immediately on next tick (then every 10 seconds)
113
+ def test_reloaded_tasks_run_repeatedly
114
+ ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task2])
115
+ tick_at(@now, :and_every_second_for => @database_reload_frequency.seconds + 11.seconds)
116
+ assert_equal ["ScheduledTask:2", "ScheduledTask:2"], @tasks_run[-2..-1]
117
+ end
108
118
 
109
- assert_equal "ScheduledTask:2", @tasks_run.last
110
- end
119
+ def test_reloading_task_with_modified_frequency_will_run_with_new_frequency
120
+ ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task1_modified])
111
121
 
112
- def test_reloaded_tasks_run_repeatedly
113
- ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task2])
114
- tick_at(@next_minute, :and_every_second_for => @database_reload_frequency.seconds + 11.seconds)
115
- assert_equal ["ScheduledTask:2", "ScheduledTask:2"], @tasks_run[-2..-1]
116
- end
122
+ tick_at(@now, :and_every_second_for => 66.seconds)
117
123
 
118
- def test_stops_running_deleted_database_task
119
- ScheduledTask.stubs(:all).returns([@scheduled_task1], [])
120
- tick_at(@next_minute, :and_every_second_for => @database_reload_frequency.seconds)
121
- before = @tasks_run.dup
124
+ # task1 runs at: 1, 11, 21, 31, 41, 51 (6 runs)
125
+ # database tasks are reloaded at: 60
126
+ # task1_modified runs at: 61 (next tick after reload) and then 66 (2 runs)
127
+ assert_equal 8, @tasks_run.length
128
+ end
122
129
 
123
- # tick through reload, and run for enough ticks that previous task would have run
124
- tick_at(@next_minute + @database_reload_frequency.seconds + 20.seconds)
125
- after = @tasks_run
130
+ def test_stops_running_deleted_database_task
131
+ ScheduledTask.stubs(:all).returns([@scheduled_task1], [])
132
+ tick_at(@now, :and_every_second_for => @database_reload_frequency.seconds)
133
+ before = @tasks_run.dup
126
134
 
127
- assert_equal before, after
128
- end
135
+ # tick through reload, and run for enough ticks that previous task would have run
136
+ tick_at(@now + @database_reload_frequency.seconds + 20.seconds)
137
+ after = @tasks_run
129
138
 
130
- def test_reloading_task_with_modified_frequency_will_run_with_new_frequency
131
- ScheduledTask.stubs(:all).returns([@scheduled_task1], [@scheduled_task1_modified])
139
+ assert_equal before, after
140
+ end
132
141
 
133
- tick_at(@next_minute, :and_every_second_for => 66.seconds)
142
+ def test_edited_tasks_switch_to_new_settings
143
+ tick_at @now, :and_every_second_for => @database_reload_frequency.seconds - 1.second
144
+ modified_task_1 = stub(:frequency => 30, :name => 'ScheduledTask:1_modified', :at => nil, :id => 1)
145
+ ScheduledTask.stubs(:all).returns([modified_task_1])
146
+ tick_at @now + @database_reload_frequency.seconds, :and_every_second_for => @database_reload_frequency.seconds - 1.seconds
147
+ assert_equal [
148
+ "ScheduledTask:1",
149
+ "ScheduledTask:1",
150
+ "ScheduledTask:1",
151
+ "ScheduledTask:1",
152
+ "ScheduledTask:1",
153
+ "ScheduledTask:1",
154
+ "ScheduledTask:1_modified",
155
+ "ScheduledTask:1_modified"
156
+ ], @tasks_run
157
+ end
134
158
 
135
- # task1 runs at: 1, 11, 21, 31, 41, 51 (6 runs)
136
- # database tasks are reloaded at: 60
137
- # task1_modified runs at: 61 (next tick after reload) and then 66 (2 runs)
138
- assert_equal 8, @tasks_run.length
139
- end
159
+ def test_daily_task_with_at_should_only_run_once
160
+ next_minute = next_minute(@now)
161
+ at = next_minute.strftime('%H:%M')
162
+ @scheduled_task_with_at = stub(:frequency => 1.day, :name => 'ScheduledTaskWithAt:1', :at => at, :id => 5)
163
+ ScheduledTask.stubs(:all).returns([@scheduled_task_with_at])
140
164
 
141
- # Catch a bug caused by allowing database tasks to be run in the same clock cycle that the database
142
- # sync occurs. When this happens, a previously scheduled database task will be scheduled to run,
143
- # we then fetch the same task afresh (wiping out the @events_from_database object), but the
144
- # previously scheduled task still runs because #task `events` variable already stored it *before*
145
- # we wiped out the @events_from_database objects.
146
- #
147
- # We have a situation like this:
148
- #
149
- # 12:31:00 #tick loops through events to run
150
- # sync_database_tasks_for_model_ task is run
151
- # fetches database task 1 with :at => 12:32, and schedules it to run (object task 1')
152
- #
153
- # ...
154
- #
155
- # 12:32:00 #tick loops through events that should be run, of which task 1' is included
156
- # sync_database_tasks_for_model_ task is run
157
- # fetches database task 1 with :at => 12:32, and schedules it to run (object task 1'')
158
- # task 1' is run
159
- #
160
- # 12:32:01 #tick loops through events that should be run, of which task 1'' is included
161
- # task 1'' is run
162
- def test_daily_task_with_at_should_not_run_twice_when_already_scheduled
163
- minute_after_next = next_minute(@next_minute)
164
- at = minute_after_next.strftime('%H:%M')
165
- @scheduled_task_with_at = stub(:frequency => 1.day, :name => 'ScheduledTaskWithAt:1', :at => at)
166
- ScheduledTask.stubs(:all).returns([@scheduled_task_with_at])
167
-
168
- # tick from now, though specified :at time
169
- tick_at(@now, :and_every_second_for => (2 * @database_reload_frequency.seconds) + 1.second)
170
-
171
- assert_equal 1, @tasks_run.length
172
- end
165
+ # tick from now, though specified :at time
166
+ tick_at(@now, :and_every_second_for => (2 * @database_reload_frequency.seconds) + 1.second)
167
+
168
+ assert_equal 1, @tasks_run.length
169
+ end
170
+
171
+ def test_having_multiple_sync_database_tasks_will_work
172
+ ScheduledTask.stubs(:all).returns([@scheduled_task1])
173
+
174
+ # setup 2nd database sync
175
+ @scheduled_task_type2 = stub(:frequency => 10, :name => 'ScheduledTaskType2:1', :at => nil, :id => 6)
173
176
 
174
- def test_having_multiple_sync_database_tasks_will_work
175
- ScheduledTask.stubs(:all).returns([@scheduled_task1])
177
+ ScheduledTaskType2.stubs(:all).returns([@scheduled_task_type2])
178
+ @manager.sync_database_tasks model: ScheduledTaskType2, every: @database_reload_frequency do |job_name|
179
+ @tasks_run << job_name
180
+ end
176
181
 
177
- # setup 2nd database sync
178
- @scheduled_task_type2 = stub(:frequency => 10, :name => 'ScheduledTaskType2:1', :at => nil)
182
+ tick_at(@now, :and_every_second_for => 1.second)
179
183
 
180
- ScheduledTaskType2.stubs(:all).returns([@scheduled_task_type2])
181
- @manager.sync_database_tasks model: ScheduledTaskType2, every: @database_reload_frequency do |job_name|
182
- @tasks_run << job_name
184
+ assert_equal ["ScheduledTask:1", "ScheduledTaskType2:1"], @tasks_run
183
185
  end
186
+ end
187
+
188
+ context "when database reload frequency is less than task frequency period" do
189
+ setup do
190
+ @tasks_run = []
191
+ @scheduled_task1 = stub(:frequency => 5.minutes, :name => 'ScheduledTask:1', :at => nil, :id => 1)
192
+ @scheduled_task2 = stub(:frequency => 10, :name => 'ScheduledTask:2', :at => nil, :id => 2)
193
+ @scheduled_task1_modified = stub(:frequency => 5, :name => 'ScheduledTaskModified:1', :at => nil)
194
+ ScheduledTask.stubs(:all).returns([@scheduled_task1])
195
+
196
+ @database_reload_frequency = 1.minute
184
197
 
185
- tick_at(@next_minute, :and_every_second_for => 1.second)
198
+ @now = Time.now
199
+ @next_minute = next_minute(@now) # database sync task only happens on minute boundary
186
200
 
187
- assert_equal ["ScheduledTask:1", "ScheduledTaskType2:1"], @tasks_run
201
+ # setup the database sync
202
+ @manager.sync_database_tasks model: ScheduledTask, every: @database_reload_frequency do |job_name|
203
+ @tasks_run << job_name
204
+ end
205
+ end
206
+
207
+ # For example: if the manager updates every minute, but the task specifies 5 minutes,
208
+ # the task will still run every minute.
209
+ def test_it_only_runs_the_task_once_within_the_task_frequency_period
210
+ tick_at(@now, :and_every_second_for => 5.minutes)
211
+ assert_equal 1, @tasks_run.length
212
+ end
188
213
  end
189
214
  end
190
215
  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: 0.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wiggins
@@ -9,104 +9,104 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-20 00:00:00.000000000 Z
12
+ date: 2014-04-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: tzinfo
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - '>='
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - '>='
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: bundler
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ~>
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '1.3'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ~>
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '1.3'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rake
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '>='
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '>='
67
+ - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: daemons
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - '>='
74
+ - - ">="
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - '>='
81
+ - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: contest
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - '>='
88
+ - - ">="
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - '>='
95
+ - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: mocha
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - '>='
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - '>='
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  description: A scheduler process to replace cron, using a more flexible Ruby syntax
@@ -121,8 +121,8 @@ extensions: []
121
121
  extra_rdoc_files:
122
122
  - README.md
123
123
  files:
124
- - .gitignore
125
- - .travis.yml
124
+ - ".gitignore"
125
+ - ".travis.yml"
126
126
  - Gemfile
127
127
  - README.md
128
128
  - Rakefile
@@ -152,17 +152,17 @@ require_paths:
152
152
  - lib
153
153
  required_ruby_version: !ruby/object:Gem::Requirement
154
154
  requirements:
155
- - - '>='
155
+ - - ">="
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
158
  required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  requirements:
160
- - - '>='
160
+ - - ">="
161
161
  - !ruby/object:Gem::Version
162
162
  version: '0'
163
163
  requirements: []
164
164
  rubyforge_project:
165
- rubygems_version: 2.0.3
165
+ rubygems_version: 2.2.0
166
166
  signing_key:
167
167
  specification_version: 4
168
168
  summary: A scheduler process to replace cron.