Sha256: da41213cc18d53b9e005668dbd8e6b6a6d09777b7a5d30cdd82c158eee028d3b

Contents?: true

Size: 1.61 KB

Versions: 1

Compression:

Stored size: 1.61 KB

Contents

module Clockwork
	class Event
		def initialize(span, options={}, &block)
			@secs = parse_span(span)
			@at = parse_at(options[:at])
			@last = nil
			@block = block
		end

		def time?(t)
			ellapsed_ready = (@last.nil? or (t - @last).to_i >= @secs)
			time_ready = (@at.nil? or (t.hour == @at[0] and t.min == @at[1]))
			ellapsed_ready and time_ready
		end

		def run(t)
			@block.call
			@last = t
		rescue => e
			STDERR.puts exception_message(e)
		end

		def exception_message(e)
			msg = [ "Exception #{e.class} -> #{e.message}" ]

			base = File.expand_path(Dir.pwd) + '/'
			e.backtrace.each do |t|
				msg << "   #{File.expand_path(t).gsub(/#{base}/, '')}"
			end

			msg.join("\n")
		end

		class FailedToParse < RuntimeError; end

		def parse_span(span)
			m = span.match(/^(\d+)([smhd])$/)
			raise FailedToParse, span unless m
			ordinal, magnitude = m[1].to_i, m[2]
			ordinal * magnitude_multiplier[magnitude]
		end

		def magnitude_multiplier
			{
				's' => 1,
				'm' => 60,
				'h' => 60*60,
				'd' => 24*60*60
			}
		end

		def parse_at(at)
			return unless at
			m = at.match(/^(\d\d):(\d\d)$/)
			raise FailedToParse, at unless m
			hour, min = m[1].to_i, m[2].to_i
			raise FailedToParse, at if hour >= 24 or min >= 60
			[ hour, min ]
		end
	end

	extend self

	def every(span, options={}, &block)
		event = Event.new(span, options, &block)
		@@events ||= []
		@@events << event
		event
	end

	def run
		loop do
			tick
			sleep 1
		end
	end

	def tick(t=Time.now)
		to_run = @@events.select do |event|
			event.time?(t)
		end

		to_run.each do |event|
			event.run(t)
		end

		to_run
	end

	def clear!
		@@events = []
	end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
clockwork-0.1.1 lib/clockwork.rb