Skip to content

Commit

Permalink
version 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
nickelser committed May 7, 2015
1 parent c57d56e commit 989106d
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 9 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.1.1

- Handle multiple ats (at: ["mon 8:00, tues 9:30"]).
- Job callbacks (:before_tick, :after_tick, etc).

## 0.1.0

- First release.
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Zhong

Useful, reliable distributed cron.
Useful, reliable distributed cron. Tired of your cron-like scheduler running key jobs twice? Would you like to be able to run your cron server on multiple machines and have it "just work"? Have we got the gem for you.

Zhong uses Redis to acquire exclusive locks on jobs, as well as recording when they last ran. This means that you can rest easy at night, knowing that your customers are getting their monthly Goat Fancy magazine subscriptions and you are rolling around in your piles of money without a care in the world.

# Installation

Expand All @@ -18,13 +20,25 @@ r = Redis.new
Zhong.schedule(redis: r) do |s|
s.category "stuff" do
s.every(5.seconds, "foo") { puts "foo" }
s.every(1.week, "baz", at: "mon 22:45") { puts "baz" }
s.every(1.week, "baz", at: ["mon 22:45", "wed 23:13"]) { puts "baz" }
end

s.category "clutter" do
s.every(1.second, "compute", if: -> (t) { rand < 0.5 }) { puts "something happened" }
s.every(1.second, "compute", if: -> (t) { t.wday == 3 && rand < 0.5 }) { puts "something happened on wednesday" }
end

# note: callbacks that return nil or false will cause event to not run
s.on(:before_tick) do
puts "ding"
true
end

s.on(:after_tick) do
puts "dong"
true
end
end

```

## TODO
Expand Down
17 changes: 17 additions & 0 deletions lib/zhong/at.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def next_at(time = Time.now)
def self.parse(at, grace: 0)
return unless at

# TODO: refactor this mess
if at.respond_to?(:each)
return MultiAt.new(at.map { |a| parse(a, grace: grace) })
end

case at
when /\A([[:alpha:]]+)\s+(.*)\z/
wday = WDAYS[$1]
Expand All @@ -67,4 +72,16 @@ def self.parse(at, grace: 0)
throw FailedToParse, at
end
end

class MultiAt
attr_accessor :ats

def initialize(ats = [])
@ats = ats
end

def next_at(time = Time.now)
ats.map { |at| at.next_at(time) }.min
end
end
end
2 changes: 1 addition & 1 deletion lib/zhong/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def to_s

def next_at
every_time = @every.next_at(@last_ran) if @last_ran && @every
at_time = @at.next_at(time) if @at
at_time = @at.next_at(Time.now) if @at
[every_time, at_time, Time.now].compact.max || "now"
end

Expand Down
33 changes: 29 additions & 4 deletions lib/zhong/scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Scheduler

def initialize(config = {})
@jobs = {}
@callbacks = {}
@config = DEFAULT_CONFIG.merge(config)
@logger = @config[:logger] ||= Util.default_logger
@redis = @config[:redis] ||= Redis.new(ENV["REDIS_URL"])
Expand All @@ -28,7 +29,18 @@ def category(name)
end

def every(period, name, opts = {}, &block)
add(Job.new(name, opts.merge(@config).merge(every: period, category: @category), &block))
job = Job.new(name, opts.merge(@config).merge(every: period, category: @category), &block)
add(job)
end

def error_handler(&block)
@error_handler = block if block_given?
@error_handler
end

def on(event, &block)
fail "Unsupported callback #{event}" unless [:before_tick, :after_tick, :before_run, :after_run].include?(event.to_sym)
(@callbacks[event.to_sym] ||= []) << block
end

def start
Expand All @@ -39,11 +51,20 @@ def start
@logger.info "starting at #{redis_time}"

loop do
now = redis_time
if fire_callbacks(:before_tick)
now = redis_time

jobs.each { |_, job| job.run(now) }
jobs.each do |_, job|
if fire_callbacks(:before_run, job, now)
job.run(now)
fire_callbacks(:after_run, job, now)
end
end

sleep(interval)
fire_callbacks(:after_tick)

sleep(interval)
end

break if @stop
end
Expand All @@ -56,6 +77,10 @@ def stop
Thread.new { @logger.info "stopped" }
end

def fire_callbacks(event, *args)
@callbacks[event].to_a.all? { |h| h.call(*args) }
end

private

def add(job)
Expand Down
2 changes: 1 addition & 1 deletion lib/zhong/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Zhong
VERSION = "0.1.0"
VERSION = "0.1.1"
end

0 comments on commit 989106d

Please sign in to comment.