stagger 0.1.1 → 0.2.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 +4 -4
- data/.hound.yml +2 -0
- data/README.md +27 -3
- data/lib/stagger.rb +9 -4
- data/lib/stagger/version.rb +1 -1
- data/spec/stagger_spec.rb +45 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f219ca29cb8639825bccec42c9f37267e80609d0
|
4
|
+
data.tar.gz: 5d61f7cdecbe5ead509e5d933959cc071215d4de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8607c7cc1731e7dbf0d90d4de769ab7339b494a14a518cb2ffe186a5cb605e1f702be938a39ac118a9a96c9edead217c827b4f90931f649f8099ada01e8f9e2
|
7
|
+
data.tar.gz: 7343e17149e12f843eb5be374cd7fb64b99f1355ee3180ebdebce24b7b99deef18d9b4dc16dab25f81c43cdc1e91f489984e03e3b59682a8366a393b20046610
|
data/.hound.yml
ADDED
data/README.md
CHANGED
@@ -9,7 +9,10 @@ days.
|
|
9
9
|
On the surface, this tasks seems simple, but when you have a lot of
|
10
10
|
tasks,
|
11
11
|
that should be scheduled across business days, that span several weeks,
|
12
|
-
it gets complicated.
|
12
|
+
it gets complicated. When you have both plain ruby `Time` and
|
13
|
+
`ActiveSupport::TimeWithZone`, it gets even more hairy.
|
14
|
+
|
15
|
+
Stagger has good test coverage, I covered all cases
|
13
16
|
I could think of with specs.
|
14
17
|
|
15
18
|
Stagger has no runtime dependencies.
|
@@ -24,12 +27,22 @@ emails = get_emails()
|
|
24
27
|
schedule = Stagger.distribute(emails, 14)
|
25
28
|
```
|
26
29
|
|
27
|
-
Schedule one item to be sent as soon as possible but on business day only:
|
30
|
+
Schedule one item to be sent as soon as possible but on a business day only:
|
28
31
|
|
29
32
|
```ruby
|
30
33
|
email = get_email() # only one email
|
31
34
|
schedule = Stagger.distribute([email], 1) # i.e. distribute across 1
|
32
35
|
business day
|
36
|
+
|
37
|
+
Schedule one item to be sent after a delay of 5 minutes, but on a business day only:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
email = get_email() # only one email
|
41
|
+
# specify delay in seconds
|
42
|
+
schedule = Stagger.distribute([email], 1, delay: 5 * 60) # i.e. distribute across 1
|
43
|
+
business day
|
44
|
+
```
|
45
|
+
|
33
46
|
```
|
34
47
|
|
35
48
|
Schedule 1000 emails to be sent across next 30 business days:
|
@@ -59,9 +72,20 @@ But when `ActiveSupport` is available, it returns instances of rails'
|
|
59
72
|
In other words, you don't need to do anything when using this gem with
|
60
73
|
Rails.
|
61
74
|
|
75
|
+
## Options
|
76
|
+
|
77
|
+
### Delay
|
78
|
+
|
79
|
+
Specified in seconds, default is 0.
|
80
|
+
Will make the first and subsequent items to be shifted ahead in time.
|
81
|
+
Useful to make for scenarios when first item w/out an initial delay will
|
82
|
+
have been in the past by the time the processing logic will pick it up.
|
83
|
+
If the delay makes the first item to be scheduled on a weekend, it will
|
84
|
+
be sent on Monday at 00 hours.
|
85
|
+
|
62
86
|
## Plans
|
63
87
|
|
64
|
-
Plans to add support for holidays
|
88
|
+
Plans to add support for holidays and working hours in the future.**
|
65
89
|
|
66
90
|
|
67
91
|
## Installation
|
data/lib/stagger.rb
CHANGED
@@ -3,9 +3,14 @@ require "stagger/version"
|
|
3
3
|
module Stagger
|
4
4
|
SECONDS_IN_DAY = 86_400
|
5
5
|
class << self
|
6
|
-
|
6
|
+
# Evenly distributes items acros business days
|
7
|
+
# @param [Array, items] items to stagger
|
8
|
+
# @param [Integer, number_of_days] number of business days to distribute within
|
9
|
+
# @param [Integer, delay] number of seconds to delay the staggering
|
10
|
+
# @return [Array] array of arrays, where first subarray element is a scheduled DateTime, second is the staggered item
|
11
|
+
def distribute(items, number_of_days, delay: 0)
|
7
12
|
return [] if Array(items).empty? || number_of_days.to_i < 1
|
8
|
-
time = get_starting_time
|
13
|
+
time = get_starting_time(delay)
|
9
14
|
period_in_seconds = get_period_in_seconds(items.size, number_of_days, time)
|
10
15
|
items.reduce [] do |arr, item|
|
11
16
|
if business_day?(time)
|
@@ -29,8 +34,8 @@ module Stagger
|
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
|
-
def get_starting_time
|
33
|
-
tc = current_time
|
37
|
+
def get_starting_time(delay)
|
38
|
+
tc = current_time + delay
|
34
39
|
if tc.saturday?
|
35
40
|
at_beginning_of_day(tc) + SECONDS_IN_DAY * 2
|
36
41
|
elsif tc.sunday?
|
data/lib/stagger/version.rb
CHANGED
data/spec/stagger_spec.rb
CHANGED
@@ -47,6 +47,24 @@ RSpec.describe Stagger do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
it 'schedules to run after a delay if today is a business day' do
|
51
|
+
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
52
|
+
Timecop.freeze(t) do
|
53
|
+
# stagger after a delay of 5 minutes
|
54
|
+
pair = Stagger.distribute([1], 1, delay: 300).first
|
55
|
+
expect(pair.last).to eq Time.local(2014, 6, 27, 18, 5)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'schedules to run after a big delay that spans over the weekend' do
|
60
|
+
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
61
|
+
Timecop.freeze(t) do
|
62
|
+
# stagger after a delay of 72 hours
|
63
|
+
pair = Stagger.distribute([1], 1, delay: 72 * 60 * 60).first
|
64
|
+
expect(pair.last).to eq Time.local(2014, 6, 30, 18)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
50
68
|
it 'schedules immediately if today is a business day and number of days > 1' do
|
51
69
|
# a dumb test, actually, but I need to cover it
|
52
70
|
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
@@ -56,6 +74,33 @@ RSpec.describe Stagger do
|
|
56
74
|
end
|
57
75
|
end
|
58
76
|
|
77
|
+
it 'schedules to run after a delay if today is a business day and number of days > 1' do
|
78
|
+
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
79
|
+
Timecop.freeze(t) do
|
80
|
+
# stagger after a delay of 5 minutes
|
81
|
+
pair = Stagger.distribute([1], 2, delay: 300).first
|
82
|
+
expect(pair.last).to eq Time.local(2014, 6, 27, 18, 5)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'schedules to run on Monday business day if delay will schedule the first item run on Saturday' do
|
87
|
+
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
88
|
+
Timecop.freeze(t) do
|
89
|
+
# stagger after a delay of 7 hours
|
90
|
+
pair = Stagger.distribute([1], 1, delay: 7 * 60 * 60).first
|
91
|
+
expect(pair.last).to eq Time.local(2014, 6, 30) # Midnight, Monday
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'schedules to run on Monday business day if delay will schedule the first item run on Sunday' do
|
96
|
+
t = Time.local(2014, 6, 27, 18) # 6pm, Friday
|
97
|
+
Timecop.freeze(t) do
|
98
|
+
# stagger after a delay of 31 hours (1 in the morning of Sunday)
|
99
|
+
pair = Stagger.distribute([1], 1, delay: 31 * 60 * 60).first
|
100
|
+
expect(pair.last).to eq Time.local(2014, 6, 30) # Midnight, Monday
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
59
104
|
it 'schedules to run on Monday (00:00) if today is Sunday' do
|
60
105
|
t = Time.local(2014, 6, 29, 14) # - 2pm, Sunday
|
61
106
|
Timecop.freeze(t) do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Valentin Vasilyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -116,6 +116,7 @@ extensions: []
|
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
118
|
- ".gitignore"
|
119
|
+
- ".hound.yml"
|
119
120
|
- ".rspec"
|
120
121
|
- ".travis.yml"
|
121
122
|
- Gemfile
|
@@ -147,11 +148,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
148
|
version: '0'
|
148
149
|
requirements: []
|
149
150
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.
|
151
|
+
rubygems_version: 2.2.2
|
151
152
|
signing_key:
|
152
153
|
specification_version: 4
|
153
154
|
summary: Gem evenly distributes items across business days
|
154
155
|
test_files:
|
155
156
|
- spec/spec_helper.rb
|
156
157
|
- spec/stagger_spec.rb
|
157
|
-
has_rdoc:
|