zhong 0.1.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bbe00de7a1e1f5b55ac8a34b0e1d0a13ac372217
4
- data.tar.gz: d05ad774898928e6748e59c0d274485414c9f529
3
+ metadata.gz: 902b025d6f1afe4edfa0f2cb6f6639bc0ff558ff
4
+ data.tar.gz: 939fedf9667d0dc26f7fb1adcddedd5cbe76deba
5
5
  SHA512:
6
- metadata.gz: 00ccb9f93043e62773fde4d74f1e9c045a1b18ee18ab7ce1a49137cb64b6b9d8ead36127ef4052d2c3fe5b538680d81000daef5ea44e3be2e8134f4fe5d39f59
7
- data.tar.gz: 663b373808754bf6c22c78174aa853bbab0d198068bd6aa1b46f586d53ed00430efb437575d54403540c902e3c391d2f68015f8fc7f6e149a6cfa9cc1347a1af
6
+ metadata.gz: 16ce76fbea779cffa736f3c48f99bca3fa0ac0ba27e46261f20c41c037143317cb406715e8e866da4495dcf33a20a11830a37b6bd1b41ac9d64c39568c7e1896
7
+ data.tar.gz: 85abd697abfe5fa1ffd7513ae8e146f34c3360234f2685f9f89aec5224b259d086e25097614836ba90ebe8bc2347b8ea324051d87ea5e6813acc845267de96bf
@@ -1,3 +1,8 @@
1
+ ## 0.2.0
2
+
3
+ - Configuring Redis and the heartbeat key now correctly updates even after Zhong is configured initially.
4
+ - Some cleanup in how config is stored in general.
5
+
1
6
  ## 0.1.9
2
7
 
3
8
  - Much more performant heartbeat checks (thanks, @sherinkurian).
data/README.md CHANGED
@@ -53,12 +53,42 @@ Zhong.schedule do
53
53
  puts "#{job} ran?: #{ran}"
54
54
  end
55
55
 
56
+ on(:before_disable) do |job|
57
+ puts "#{job} is going to be disabled"
58
+ end
59
+
60
+ on(:after_disable) do |job|
61
+ puts "#{job} disabled"
62
+ end
63
+
64
+ on(:before_enable) do |job|
65
+ puts "#{job} is going to be enabled"
66
+ end
67
+
68
+ on(:after_enable) do |job|
69
+ puts "#{job} enabled"
70
+ end
71
+
56
72
  error_handler do |e, job|
57
73
  puts "dang, #{job} messed up: #{e}"
58
74
  end
59
75
  end
60
76
  ```
61
77
 
78
+ ## Web UI
79
+
80
+ Zhong comes with a web application that can display jobs, their last run and
81
+ enable/disable them.
82
+
83
+ ### Rails
84
+
85
+ Add the following to your config/routes.rb:
86
+
87
+ ```ruby
88
+ require 'zhong/web'
89
+ mount Zhong::Web, at: "zhong"
90
+ ```
91
+
62
92
  ## History
63
93
 
64
94
  View the [changelog](https://github.com/nickelser/zhong/blob/master/CHANGELOG.md).
@@ -1,12 +1,16 @@
1
1
  module Zhong
2
2
  class Job
3
- attr_reader :name, :category, :last_ran, :logger, :at, :every, :id
3
+ extend Forwardable
4
+ def_delegators Zhong, :redis, :tz, :logger, :heartbeat_key
4
5
 
5
- def initialize(job_name, config = {}, &block)
6
+ attr_reader :name, :category, :last_ran, :at, :every, :id
7
+
8
+ def initialize(job_name, config = {}, callbacks = {}, &block)
6
9
  @name = job_name
7
10
  @category = config[:category]
8
11
  @logger = config[:logger]
9
12
  @config = config
13
+ @callbacks = callbacks
10
14
 
11
15
  @at = config[:at] ? At.parse(config[:at], grace: config.fetch(:grace, 15.minutes)) : nil
12
16
  @every = config[:every] ? Every.parse(config[:every]) : nil
@@ -15,8 +19,6 @@ module Zhong
15
19
 
16
20
  @block = block
17
21
 
18
- @redis = config[:redis]
19
- @tz = config[:tz]
20
22
  @if = config[:if]
21
23
  @long_running_timeout = config[:long_running_timeout]
22
24
  @running = false
@@ -88,20 +90,24 @@ module Zhong
88
90
  end
89
91
 
90
92
  def refresh_last_ran
91
- last_ran_val = @redis.get(last_ran_key)
93
+ last_ran_val = redis.get(last_ran_key)
92
94
  @last_ran = last_ran_val ? Time.at(last_ran_val.to_i) : nil
93
95
  end
94
96
 
95
97
  def disable
96
- @redis.set(disabled_key, "true")
98
+ fire_callbacks(:before_disable, self)
99
+ redis.set(disabled_key, "true")
100
+ fire_callbacks(:after_disable, self)
97
101
  end
98
102
 
99
103
  def enable
100
- @redis.del(disabled_key)
104
+ fire_callbacks(:before_enable, self)
105
+ redis.del(disabled_key)
106
+ fire_callbacks(:after_enable, self)
101
107
  end
102
108
 
103
109
  def disabled?
104
- !@redis.get(disabled_key).nil?
110
+ !redis.get(disabled_key).nil?
105
111
  end
106
112
 
107
113
  def to_s
@@ -115,7 +121,7 @@ module Zhong
115
121
  end
116
122
 
117
123
  def clear
118
- @redis.del(last_ran_key)
124
+ redis.del(last_ran_key)
119
125
  end
120
126
 
121
127
  def last_ran_key
@@ -136,10 +142,16 @@ module Zhong
136
142
 
137
143
  private
138
144
 
145
+ def fire_callbacks(event, *args)
146
+ @callbacks[event].to_a.map do |callback|
147
+ callback.call(*args)
148
+ end.compact.all? # do not skip on nils
149
+ end
150
+
139
151
  # if the @at value is changed across runs, the last_run becomes invalid
140
152
  # so clear it
141
153
  def clear_last_ran_if_at_changed
142
- previous_at_msgpack = @redis.get(desired_at_key)
154
+ previous_at_msgpack = redis.get(desired_at_key)
143
155
 
144
156
  if previous_at_msgpack
145
157
  previous_at = At.deserialize(previous_at_msgpack)
@@ -150,7 +162,7 @@ module Zhong
150
162
  end
151
163
  end
152
164
 
153
- @redis.set(desired_at_key, @at.serialize)
165
+ redis.set(desired_at_key, @at.serialize)
154
166
  end
155
167
 
156
168
  def run_every?(time)
@@ -167,7 +179,7 @@ module Zhong
167
179
 
168
180
  def ran!(time)
169
181
  @last_ran = time
170
- @redis.set(last_ran_key, @last_ran.to_i)
182
+ redis.set(last_ran_key, @last_ran.to_i)
171
183
  end
172
184
 
173
185
  def redis_lock
@@ -1,13 +1,14 @@
1
1
  module Zhong
2
2
  class Scheduler
3
- attr_reader :config, :redis, :jobs, :logger
3
+ extend Forwardable
4
+
5
+ def_delegators Zhong, :redis, :tz, :logger, :heartbeat_key
6
+ attr_reader :jobs
4
7
 
5
8
  DEFAULT_CONFIG = {
6
9
  timeout: 0.5,
7
10
  grace: 15.minutes,
8
- long_running_timeout: 5.minutes,
9
- tz: nil,
10
- heartbeat_key: "zhong:heartbeat",
11
+ long_running_timeout: 5.minutes
11
12
  }.freeze
12
13
 
13
14
  def initialize(config = {})
@@ -15,9 +16,6 @@ module Zhong
15
16
  @callbacks = {}
16
17
  @config = DEFAULT_CONFIG.merge(config)
17
18
 
18
- @logger = @config[:logger]
19
- @redis = @config[:redis]
20
- @tz = @config[:tz]
21
19
  @category = nil
22
20
  @error_handler = nil
23
21
  @running = false
@@ -44,7 +42,7 @@ module Zhong
44
42
  def every(period, name, opts = {}, &block)
45
43
  raise "must specify a period for #{name} (#{caller.first})" unless period
46
44
 
47
- job = Job.new(name, opts.merge(@config).merge(every: period, category: @category), &block)
45
+ job = Job.new(name, opts.merge(@config).merge(every: period, category: @category), @callbacks, &block)
48
46
 
49
47
  raise "duplicate job #{job}" if jobs.key?(job.id)
50
48
 
@@ -57,7 +55,10 @@ module Zhong
57
55
  end
58
56
 
59
57
  def on(event, &block)
60
- raise "unknown callback #{event}" unless [:before_tick, :after_tick, :before_run, :after_run].include?(event.to_sym)
58
+ unless [:before_tick, :after_tick, :before_run, :after_run, :before_disable,
59
+ :after_disable, :before_enable, :after_enable].include?(event.to_sym)
60
+ raise "unknown callback #{event}"
61
+ end
61
62
  (@callbacks[event.to_sym] ||= []) << block
62
63
  end
63
64
 
@@ -112,9 +113,9 @@ module Zhong
112
113
  end
113
114
 
114
115
  def redis_time
115
- s, ms = @redis.time # returns [seconds since epoch, microseconds]
116
+ s, ms = redis.time # returns [seconds since epoch, microseconds]
116
117
  now = Time.at(s + ms / (10**6))
117
- @tz ? now.in_time_zone(@tz) : now
118
+ tz ? now.in_time_zone(tz) : now
118
119
  end
119
120
 
120
121
  private
@@ -144,7 +145,7 @@ module Zhong
144
145
  end
145
146
 
146
147
  def heartbeat(time)
147
- @redis.hset(config[:heartbeat_key], heartbeat_field, time.to_i)
148
+ redis.hset(heartbeat_key, heartbeat_field, time.to_i)
148
149
  end
149
150
 
150
151
  def heartbeat_field
@@ -1,3 +1,3 @@
1
1
  module Zhong
2
- VERSION = "0.1.9".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
@@ -24,7 +24,27 @@ class TestLibrary < Minitest::Test
24
24
  assert_equal true, Zhong.any_running?
25
25
  assert_in_delta Zhong.redis_time.to_f, Time.now.to_f, 1
26
26
  assert_in_delta Zhong.redis_time.to_f, Zhong.latest_heartbeat.to_f, 1
27
+ refute_empty Zhong.all_heartbeats
27
28
  Zhong.stop
28
29
  t.join
29
30
  end
31
+
32
+ def test_redis_change
33
+ Zhong.schedule { nil }
34
+ t = Thread.new { Zhong.start }
35
+ sleep(1)
36
+ assert_equal true, Zhong.any_running?
37
+ test_redis = Zhong.redis
38
+ Zhong.stop
39
+ t.join
40
+ Zhong.redis = Redis.new(url: "redis://localhost/15")
41
+ refute Zhong.any_running?(5.seconds)
42
+ t = Thread.new { Zhong.start }
43
+ sleep(1)
44
+ assert_equal true, Zhong.any_running?
45
+ assert_in_delta Zhong.redis_time.to_f, Time.now.to_f, 1
46
+ Zhong.stop
47
+ Zhong.redis = test_redis
48
+ t.join
49
+ end
30
50
  end
@@ -32,8 +32,13 @@ class TestWeb < Minitest::Test
32
32
  end
33
33
 
34
34
  def test_disable_job
35
+ test_before_disable = 0
36
+ test_after_disable = 0
37
+
35
38
  Zhong.schedule do
36
39
  every(30.seconds, "test_disable_web_job") { nil }
40
+ on(:before_disable) { test_before_disable += 1 }
41
+ on(:after_disable) { test_after_disable += 1 }
37
42
  end
38
43
 
39
44
  job = Zhong.scheduler.find_by_name("test_disable_web_job")
@@ -48,11 +53,18 @@ class TestWeb < Minitest::Test
48
53
  assert_contains "every 30 seconds", last_response.body
49
54
  assert_contains 'name="enable"', last_response.body
50
55
  assert_equal true, job.disabled?
56
+ assert_equal 1, test_before_disable
57
+ assert_equal 1, test_after_disable
51
58
  end
52
59
 
53
60
  def test_enable_job
61
+ test_before_enable = 0
62
+ test_after_enable = 0
63
+
54
64
  Zhong.schedule do
55
65
  every(12.hours, "test_enable_web_job") { nil }
66
+ on(:before_enable) { test_before_enable += 1 }
67
+ on(:after_enable) { test_after_enable += 1 }
56
68
  end
57
69
 
58
70
  job = Zhong.scheduler.find_by_name("test_enable_web_job")
@@ -67,6 +79,8 @@ class TestWeb < Minitest::Test
67
79
  assert_contains "every 12 hours", last_response.body
68
80
  assert_contains 'name="disable"', last_response.body
69
81
  assert_equal false, job.disabled?
82
+ assert_equal 1, test_before_enable
83
+ assert_equal 1, test_after_enable
70
84
  end
71
85
 
72
86
  def test_heartbeat
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zhong
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Elser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-08 00:00:00.000000000 Z
11
+ date: 2016-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: suo
@@ -288,4 +288,3 @@ test_files:
288
288
  - test/test_library.rb
289
289
  - test/test_scheduler.rb
290
290
  - test/test_web.rb
291
- has_rdoc: