zhong 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: