when-do 1.0.4 → 1.1.0

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: 8789ce93d5972a22cb28ade88726877ef864f80b
4
- data.tar.gz: d705d5704d4b062791c19e423448f0d9ce890fdd
3
+ metadata.gz: 55089eb7417388181f4a1b23f3011afa7eedcce7
4
+ data.tar.gz: 12a44cd63aa78ee529e78a6915999f15ddee70bc
5
5
  SHA512:
6
- metadata.gz: ee72d32fbda5ff916de43339db4bef73a0ce3a0f420d79af3555e2d6d19329868afbbb0ec5d8a82e4eee6dbb7faf00bd664854791d1e3d6435ff98868a7b2973
7
- data.tar.gz: 9602f916ec76598b8312e33197bd064598c95817182cb7c2a744be428f39ff763c591ca6a4e0fedfae3bad178e7919cbba82e1c581476f9aca8d8770c8af88e7
6
+ metadata.gz: 23b8e2d495469b7b4fabbee4a46431b6518930dbc3f7c9aef5ea3bb2ab6fc19242ccc3b7698425a900730c2823691ea729878a6a0921c335e01ac06ec8d359fe
7
+ data.tar.gz: db0893e786167963253d6e4a69b10cf4b6811404eccaa37125241c8240440ff2dcca1dd14eb81b59e170cdb4536be0231707a623aaf8403e95aa93e8f94318f6
data/README.md CHANGED
@@ -7,7 +7,7 @@ Supports
7
7
  * Dynamic cron schedules
8
8
  * Delayed queueing
9
9
 
10
- Schedules are not cached and can be changed at will. Redundant processes can run without duplication of jobs as long as they point to the same Redis. Jobs will not be double-queued when DST resets time backwards, but will be skipped when DST moves time forward. Leap seconds should be fine.
10
+ Schedules are not cached and can be changed at will. Redundant processes can run without duplication of jobs as long as they point to the same Redis. Jobs will not be double-queued when DST resets time backwards, and will be queued as DST skips over them. Leap seconds are fine.
11
11
 
12
12
  ## Installation
13
13
 
@@ -66,7 +66,7 @@ Check schedules:
66
66
 
67
67
  When.schedules
68
68
 
69
- On my 2013 Macbook Air, 100k schedules can be analyzed in <3 seconds.
69
+ On my 2013 1.3GHz Macbook Air, 100k schedules can be analyzed in <3 seconds.
70
70
 
71
71
  ## Contributing
72
72
 
data/lib/when-do/do.rb CHANGED
@@ -58,21 +58,21 @@ module When
58
58
  end
59
59
  }.abort_on_exception = true
60
60
  else
61
- analyze
61
+ ['HUP', 'INT', 'TERM', 'QUIT'].each { |sig| Signal.trap(sig) { }}
62
+ analyze(Time.now)
63
+ exit
62
64
  end
63
65
  end
64
66
 
65
- def analyze
66
- ['HUP', 'INT', 'TERM', 'QUIT'].each { |sig| Signal.trap(sig) { }}
67
- started_at = Time.now
67
+ def analyze(started_at)
68
68
  if running?(started_at)
69
69
  logger.info('Another process is already analyzing.')
70
70
  else
71
- logger.debug { 'Analyzing.' }
71
+ analyze_dst(started_at) if dst_forward?(started_at)
72
+ logger.debug { "Analyzing #{started_at}." }
72
73
  queue_scheduled(started_at)
73
74
  queue_delayed(started_at)
74
75
  end
75
- exit
76
76
  end
77
77
 
78
78
  def running?(started_at)
@@ -89,6 +89,18 @@ module When
89
89
  check_and_set_analyzed[0]
90
90
  end
91
91
 
92
+ def dst_forward?(started_at)
93
+ started_at.hour - (started_at - 60).hour == 2
94
+ end
95
+
96
+ def analyze_dst(started_at)
97
+ logger.info { "DST forward shift detected. Triggering analysis for #{started_at.hour - 1}:00 through #{started_at.hour - 1}:59"}
98
+ skipped_time = Time.new(started_at.year, started_at.month, started_at.day, started_at.hour - 1, 0, 0, started_at.utc_offset - 3600)
99
+ (0..59).each do |min|
100
+ analyze(skipped_time + min * 60)
101
+ end
102
+ end
103
+
92
104
  def build_day_key(started_at)
93
105
  "#{schedule_key}:#{started_at.to_s.split(' ')[0]}"
94
106
  end
@@ -135,7 +147,7 @@ module When
135
147
  private
136
148
 
137
149
  def sleep_until_next_minute
138
- to_sleep = 62 - Time.now.sec #handle up to 2 leap seconds
150
+ to_sleep = 62 - Time.now.sec # handle up to 2 leap seconds
139
151
  logger.debug { "Sleeping #{to_sleep} seconds."}
140
152
  sleep(to_sleep)
141
153
  end
@@ -3,6 +3,7 @@ require 'when-do/cli'
3
3
 
4
4
  describe When::CLI do
5
5
  let(:cli) { When::CLI.new }
6
+
6
7
  describe '#options' do
7
8
  context 'argv has an option with no following value' do
8
9
  before do
@@ -134,4 +134,93 @@ describe When::Do do
134
134
  .to(2)
135
135
  end
136
136
  end
137
+
138
+ describe '#dst_forward?' do
139
+ context 'started_at is the minute after dst skips forward' do
140
+ let(:started_at) { Time.new(2014, 3, 9, 3) }
141
+
142
+ it 'returns true' do
143
+ expect(when_do.dst_forward?(started_at)).to eq true
144
+ end
145
+ end
146
+
147
+ context 'started_at is the minute before dst skips forward' do
148
+ let(:started_at) { Time.new(2014, 3, 9, 1, 59) }
149
+
150
+ it 'returns false' do
151
+ expect(when_do.dst_forward?(started_at)).to eq false
152
+ end
153
+ end
154
+
155
+ context 'started_at is the minute after dst skips backward' do
156
+ let(:started_at) { Time.new(2014, 11, 2, 1) }
157
+
158
+ it 'returns false' do
159
+ expect(when_do.dst_forward?(started_at)).to eq false
160
+ end
161
+ end
162
+
163
+ context 'started_at is the minute before dst skips backward' do
164
+ let(:started_at) { Time.new(2014, 11, 2, 0, 59) + 3600 }
165
+
166
+ it 'returns false' do
167
+ expect(when_do.dst_forward?(started_at)).to eq false
168
+ end
169
+ end
170
+ end
171
+
172
+ describe '#analyze_dst' do
173
+ it 'calls analyze for each minute of the hour before started_at' do
174
+ hour_before = Time.new(started_at.year, started_at.month, started_at.day, started_at.hour - 1, 0, 0, started_at.utc_offset - 3600)
175
+ (0..59).each do |min|
176
+ expect(when_do).to receive(:analyze).with(hour_before + min * 60).ordered
177
+ end
178
+ when_do.analyze_dst(started_at)
179
+ end
180
+ end
181
+
182
+ describe '#analyze' do
183
+ before do
184
+ when_do.stub(:queue_scheduled)
185
+ when_do.stub(:queue_delayed)
186
+ end
187
+
188
+ context '#running? is false' do
189
+ before do
190
+ when_do.stub(:running?).with(started_at).and_return false
191
+ end
192
+
193
+ it 'calls queue_scheduled' do
194
+ expect(when_do).to receive(:queue_scheduled).with(started_at)
195
+ when_do.analyze(started_at)
196
+ end
197
+
198
+ it 'calls queue_delayed' do
199
+ expect(when_do).to receive(:queue_delayed).with(started_at)
200
+ when_do.analyze(started_at)
201
+ end
202
+
203
+ context '#dst_forward? is true' do
204
+ before do
205
+ when_do.stub(:dst_forward?).with(started_at).and_return true
206
+ end
207
+
208
+ it 'calls analyze_dst' do
209
+ expect(when_do).to receive(:analyze_dst).with(started_at)
210
+ when_do.analyze(started_at)
211
+ end
212
+ end
213
+
214
+ context '#dst_forward? is false' do
215
+ before do
216
+ when_do.stub(:dst_forward?).with(started_at).and_return false
217
+ end
218
+
219
+ it 'does not call analyze_dst' do
220
+ expect(when_do).not_to receive(:analyze_dst).with(started_at)
221
+ when_do.analyze(started_at)
222
+ end
223
+ end
224
+ end
225
+ end
137
226
  end
data/when-do.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "when-do"
7
- spec.version = '1.0.4'
7
+ spec.version = '1.1.0'
8
8
  spec.authors = ["TH"]
9
9
  spec.email = ["tylerhartland7@gmail.com"]
10
10
  spec.description = %q{Queues jobs when you want.}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: when-do
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-13 00:00:00.000000000 Z
11
+ date: 2014-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: when-cron