goalkeeper 0.3.0 → 0.3.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/CHANGES.md +4 -0
- data/README.md +176 -8
- data/lib/goalkeeper/goal.rb +3 -3
- data/lib/goalkeeper/version.rb +1 -1
- data/test/goalkeeper/goal_test.rb +12 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2218b1dbfd25948dd08869e05472cf1e5b12947
|
4
|
+
data.tar.gz: 56e2989786f574f8424b8d5674d85f5cbc2a9f2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d3cfa5ad03262197bcaadca3d008568bb7228896e8f0453f5425e4e05fa163c4ece7bcbe9873bb4fb74ca4a58464c52e78b3f03905b844fe788c15da1a680f
|
7
|
+
data.tar.gz: f3a7a95b5dee458012e67b7958df75e03c805f0c7368e39777dfb8ac24543451531b316c5fed981290a7b79b953427c647e635acb0c74284c6ee4a04366766c6
|
data/CHANGES.md
ADDED
data/README.md
CHANGED
@@ -1,11 +1,58 @@
|
|
1
1
|
# Goalkeeper
|
2
2
|
|
3
|
-
Goalkeeper is a simple
|
3
|
+
Goalkeeper is a simple library for tracking if, and when, a Goal has
|
4
|
+
been met. A Set of goals can be combined to check if all of them
|
5
|
+
have been completed.
|
4
6
|
|
5
|
-
|
7
|
+
This could be used as a checklist for process completion.
|
6
8
|
|
9
|
+
### Examples
|
7
10
|
|
8
|
-
|
11
|
+
Check if your application ran its daily backup
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# send the report and mark the report as sent
|
15
|
+
def backup
|
16
|
+
# ... backup code ...
|
17
|
+
Goalkeeper.met!("backup:#{Date.today}")
|
18
|
+
end
|
19
|
+
|
20
|
+
# elsewhere warn if any customer has not had a report sent
|
21
|
+
def did_backup_today?
|
22
|
+
Goalkeeper.met?("backup:#{Date.today}")
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
Wait for a Set of Goals to be met before starting another.
|
27
|
+
```ruby
|
28
|
+
# The email can't be sent until the 'prices' and 'awards' are downloaded
|
29
|
+
def email_report
|
30
|
+
set = Goalkeeper::Set.new.
|
31
|
+
add("prices:#{Date.today}").
|
32
|
+
add("awards:#{Date.today}")
|
33
|
+
|
34
|
+
if set.met?
|
35
|
+
log.info "Downloads completed by #{set.met_at}"
|
36
|
+
deliver
|
37
|
+
else
|
38
|
+
log.info "#{set.unmet.map(&:label).join(', ')} have not been downloaded"
|
39
|
+
retry_later
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# elsewhere the code to get the data and mark it complete
|
44
|
+
def download_prices
|
45
|
+
# ... download code ...
|
46
|
+
Goalkeeper.met!('prices:#{Date.today}')
|
47
|
+
end
|
48
|
+
|
49
|
+
def download_awards
|
50
|
+
# ... download code ...
|
51
|
+
Goalkeeper.met!('awards:#{Date.today}')
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
### Installation
|
9
56
|
|
10
57
|
Add this line to your application's Gemfile:
|
11
58
|
|
@@ -21,9 +68,131 @@ Or install it yourself as:
|
|
21
68
|
|
22
69
|
$ gem install goalkeeper
|
23
70
|
|
24
|
-
|
71
|
+
### Usage
|
72
|
+
|
73
|
+
Its goes likes this...
|
74
|
+
|
75
|
+
You might never need to reference the Goal class. Most everything can be done via Goalkeeper and Goalkeeper::Set.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
Goalkeeper.met? "label" #=> false
|
79
|
+
Goalkeeper.met! "label" #=> <Goalkeeper::Goal>
|
80
|
+
Goalkeeper.met? "label" #=> true
|
81
|
+
```
|
82
|
+
|
83
|
+
But lets have a granular example. Lets ensure we wakeup New Years Day 2020.
|
84
|
+
The Goal will be named 'wakeup:2020-01-01'
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
g = Goalkeeper::Goal.new('wakeup:2020-01-01')
|
88
|
+
g.met? #=> false
|
89
|
+
```
|
90
|
+
|
91
|
+
Time flies... it is New Years Day 2020.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
g.met! # or Goalkeeper.met!('wakeup:2020-01-01')
|
95
|
+
g.met? #=> true
|
96
|
+
g.met_at #=> 2020-01-01 05:01:31 -0500
|
97
|
+
```
|
98
|
+
|
99
|
+
Now if our application checks our goal, it will be met.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
Goalkeeper.met?('wakeup:2020-01-01') #=> true
|
103
|
+
# or
|
104
|
+
Goalkeeper::Goal.new('wakeup:2020-01-01').met? #=> true
|
105
|
+
```
|
106
|
+
|
107
|
+
Note: Once a Goal is 'met' the 'met\_at' timestamp will not change, unless
|
108
|
+
'clear!' is called.
|
109
|
+
|
110
|
+
We are probably only interested in this goal being complete for a limited
|
111
|
+
time, so it will expire and be removed from Redis.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
g.ttl #=> 86400 (1 day)
|
115
|
+
```
|
116
|
+
|
117
|
+
If you need to reference the Redis key
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
g.key #=> Goalkeeper:wakeup:2020-01-01
|
121
|
+
```
|
122
|
+
|
123
|
+
Finally deleting the Goal is simple
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
g.clear!
|
127
|
+
g.met? #=> false
|
128
|
+
```
|
129
|
+
|
130
|
+
#### Sets
|
131
|
+
|
132
|
+
Perhaps you have a series of Goals you want to track, and see if they all have been met, or not.
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
set = Goalkeeper::Set.new
|
136
|
+
set.add('goal1').add('goal2')
|
137
|
+
set.met? #=> false
|
138
|
+
```
|
139
|
+
|
140
|
+
Lets have 1 goal met:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
Goalkeeper.met!('goal1')
|
144
|
+
```
|
145
|
+
|
146
|
+
But our set is not met yet
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
set.met? #=> false
|
150
|
+
```
|
151
|
+
|
152
|
+
See which goals are met, or unmet
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
set.met #=> [#<Goalkeeper::Goal @label="goal1">]
|
156
|
+
set.unmet #=> [#<Goalkeeper::Goal @label="goal2">]
|
157
|
+
```
|
158
|
+
|
159
|
+
Lets complete our set.
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
Goalkeeper.met!('goal1')
|
163
|
+
set.met? #=> true
|
164
|
+
```
|
165
|
+
|
166
|
+
See the time the final goal was met
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
set.met_at #=> 2015-01-01 08:02:15 -0500
|
170
|
+
```
|
171
|
+
|
172
|
+
#### Customization
|
173
|
+
|
174
|
+
Customize the redis client by setting it in your application
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
Goalkeeper.redis = your_redis_client
|
178
|
+
```
|
179
|
+
|
180
|
+
Each record has a default expiration of 24 hours, but this can be modified.
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
Goalkeeper.expiration = number_of_seconds
|
184
|
+
```
|
185
|
+
|
186
|
+
Redis keys are stored under the default namespace of "Goalkeeper:". The
|
187
|
+
namespace can be configured:
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
Goalkeeper.namespace = string
|
191
|
+
```
|
192
|
+
|
193
|
+
## API
|
25
194
|
|
26
|
-
|
195
|
+
#### Goal
|
27
196
|
| method | description | example |
|
28
197
|
| -------- | ------ | ----- |
|
29
198
|
| new(label) | Creates a new Goal with the unique label | `g = Goal.new('process')` |
|
@@ -35,15 +204,13 @@ Or install it yourself as:
|
|
35
204
|
| clear! | Deletes the `met` record. Goal is now unmet. | `g.clear!` |
|
36
205
|
|
37
206
|
|
38
|
-
|
207
|
+
#### Set
|
39
208
|
| method | description | example |
|
40
209
|
| -------- | ------ | ----- |
|
41
210
|
| new | creates an empty set of goals. | `s = set.new` |
|
42
211
|
| add(label) | Adds a new Goal the Set. _chainable_ | `s.add('process.a').add('process.b')` |
|
43
212
|
| met? | Returns true if _all_ the Set's Goals have been met. | `s.met? #=> false` |
|
44
|
-
| met! | Calls `met!` on all Goals. | `s.met! #=> Time.now` |
|
45
213
|
| met\_at | Returns the most recent met_at for the Set's Goals. Nil if no Goal met. | `s.met_at #=> 2015-02-09 22:24:07 -0500` |
|
46
|
-
| clear! | Calls `clear!` on all Goals. | `s.clear!` |
|
47
214
|
| met | Returns a new Set with all Goals which have been met. | `s.met #=> Set(...)` |
|
48
215
|
| unmet | Returns a new Set with all Goals which have not been met. | `s.unmet` #=> Set(...) |
|
49
216
|
|
@@ -51,6 +218,7 @@ Or install it yourself as:
|
|
51
218
|
| method | description | example |
|
52
219
|
| -------- | ------ | ----- |
|
53
220
|
| ::met!(label) | Creates a new Goal and marks it met. | `Goalkeeper.met!('process') #=> <Goalkeepr::Goal>`
|
221
|
+
| ::met?(label) | Checks if the label has been met or not | `Goalkeeper.met?('process') #=> true`
|
54
222
|
|
55
223
|
## Contributing
|
56
224
|
|
data/lib/goalkeeper/goal.rb
CHANGED
@@ -9,10 +9,10 @@ module Goalkeeper
|
|
9
9
|
# the TTL value for the Redis record. Defalts to Goalkeeper.expiration
|
10
10
|
attr_reader :expiration
|
11
11
|
|
12
|
-
# +label+ is a unique string to identify this Goal.
|
12
|
+
# +label+ is a unique string to identify this Goal. If multiple args are passed they are joined and seperated by ':'
|
13
13
|
# +expiration+ number secconds. This can be set to override the gobal expiration.
|
14
|
-
def initialize(label, expiration: Goalkeeper.expiration)
|
15
|
-
@label = label
|
14
|
+
def initialize(*label, expiration: Goalkeeper.expiration)
|
15
|
+
@label = label.join(":")
|
16
16
|
@expiration = expiration
|
17
17
|
end
|
18
18
|
|
data/lib/goalkeeper/version.rb
CHANGED
@@ -11,6 +11,18 @@ describe Goalkeeper::Goal do
|
|
11
11
|
assert_equal "test", goal.label
|
12
12
|
end
|
13
13
|
|
14
|
+
describe "label" do
|
15
|
+
it "can be a string" do
|
16
|
+
g = Goalkeeper::Goal.new("a_string")
|
17
|
+
assert_equal 'a_string', g.label
|
18
|
+
end
|
19
|
+
|
20
|
+
it "will join multiple args into a string seperated by ':'" do
|
21
|
+
g = Goalkeeper::Goal.new("a", :b, Object)
|
22
|
+
assert_equal 'a:b:Object', g.label
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
14
26
|
it "has a namespaced key" do
|
15
27
|
assert_equal "Goalkeeper:test", goal.key
|
16
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: goalkeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Weir
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -61,6 +61,7 @@ extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
63
|
- ".gitignore"
|
64
|
+
- CHANGES.md
|
64
65
|
- Gemfile
|
65
66
|
- LICENSE
|
66
67
|
- README.md
|