Class: Tickwork::Manager
- Inherits:
-
Object
show all
- Defined in:
- lib/tickwork/manager.rb
Defined Under Namespace
Classes: DuplicateJobName, NoDataStoreDefined, NoHandlerDefined
Constant Summary
collapse
- MANAGER_KEY =
'__manager'
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
Returns a new instance of Manager.
11
12
13
14
15
16
17
|
# File 'lib/tickwork/manager.rb', line 11
def initialize
@events = []
@callbacks = {}
@config = default_configuration
@handler = nil
@error_handler = nil
end
|
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
9
10
11
|
# File 'lib/tickwork/manager.rb', line 9
def config
@config
end
|
Instance Method Details
#clear! ⇒ Object
134
135
136
|
# File 'lib/tickwork/manager.rb', line 134
def clear!
data_store.write(data_store_key, nil)
end
|
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/tickwork/manager.rb', line 23
def configure
yield(config)
[:max_threads, :tick_size, :max_ticks, :max_catchup].each do |int_config_key|
config[int_config_key] = config[int_config_key].to_i
end
if config[:sleep_timeout]
config[:logger].warn 'INCORRECT USAGE: sleep_timeout is not used'
if config[:sleep_timeout] < 1
config[:logger].warn 'sleep_timeout must be >= 1 second'
end
end
if config[:data_store].nil?
raise NoDataStoreDefined.new
end
if config[:tick_size] > 60
config[:logger].warn 'tick_size is greater than 60. Events scheduled for a specific time may be missed'
end
end
|
#data_store ⇒ Object
65
66
67
|
# File 'lib/tickwork/manager.rb', line 65
def data_store
config[:data_store]
end
|
#data_store_key ⇒ Object
89
90
91
|
# File 'lib/tickwork/manager.rb', line 89
def data_store_key
@data_store_key ||= config[:namespace] + MANAGER_KEY
end
|
#default_configuration ⇒ Object
42
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/tickwork/manager.rb', line 42
def default_configuration
{
logger: Logger.new(STDOUT),
thread: false,
max_threads: 10,
namespace: '_tickwork_',
tick_size: 60, max_ticks: 10,
max_catchup: 3600 }
end
|
#error_handler(&block) ⇒ Object
60
61
62
63
|
# File 'lib/tickwork/manager.rb', line 60
def error_handler(&block)
@error_handler = block if block_given?
@error_handler
end
|
#every(period, job, options = {}, &block) ⇒ Object
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/tickwork/manager.rb', line 74
def every(period, job, options={}, &block)
if period < config[:tick_size]
config[:logger].warn 'period is smaller than tick size. will fail to schedule all events'
end
if options[:at].respond_to?(:each)
every_with_multiple_times(period, job, options, &block)
else
register(period, job, block, options)
end
end
|
#fire_callbacks(event, *args) ⇒ Object
85
86
87
|
# File 'lib/tickwork/manager.rb', line 85
def fire_callbacks(event, *args)
@callbacks[event].nil? || @callbacks[event].all? { |h| h.call(*args) }
end
|
#handle_error(e) ⇒ Object
142
143
144
|
# File 'lib/tickwork/manager.rb', line 142
def handle_error(e)
error_handler.call(e) if error_handler
end
|
#handler(&block) ⇒ Object
54
55
56
57
58
|
# File 'lib/tickwork/manager.rb', line 54
def handler(&block)
@handler = block if block_given?
raise NoHandlerDefined unless @handler
@handler
end
|
#log(msg) ⇒ Object
146
147
148
|
# File 'lib/tickwork/manager.rb', line 146
def log(msg)
config[:logger].info(msg)
end
|
#log_error(e) ⇒ Object
138
139
140
|
# File 'lib/tickwork/manager.rb', line 138
def log_error(e)
config[:logger].error(e)
end
|
#on(event, options = {}, &block) ⇒ Object
69
70
71
72
|
# File 'lib/tickwork/manager.rb', line 69
def on(event, options={}, &block)
raise "Unsupported callback #{event}" unless [:before_tick, :after_tick, :before_run, :after_run].include?(event.to_sym)
(@callbacks[event.to_sym]||=[]) << block
end
|
#run ⇒ Object
pretty straight forward if you think about it run the ticks from the last time we ran to our max but don’t run ticks in the future
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/tickwork/manager.rb', line 96
def run
raise NoDataStoreDefined.new if data_store.nil?
log "Starting clock for #{@events.size} events: [ #{@events.map(&:to_s).join(' ')} ]"
last = last_t = data_store.read(data_store_key)
last ||= Time.now.to_i - config[:tick_size]
if !config[:max_catchup].nil? && config[:max_catchup] > 0 && last < Time.now.to_i - config[:max_catchup]
last = Time.now.to_i - config[:max_catchup] - config[:tick_size]
end
ticks = 0
tick_time = last + config[:tick_size]
while ticks < config[:max_ticks] && tick_time <= Time.now.to_i do
tick(tick_time)
last = tick_time
tick_time += config[:tick_size]
ticks += 1
end
data_store.write(data_store_key, last)
last
end
|
#thread_available? ⇒ Boolean
19
20
21
|
# File 'lib/tickwork/manager.rb', line 19
def thread_available?
Thread.list.select { |t| t['creator'] == self }.count < config[:max_threads]
end
|
#tick(t = Time.now.to_i) ⇒ Object
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/tickwork/manager.rb', line 119
def tick(t=Time.now.to_i)
t = Time.at(t) if (fire_callbacks(:before_tick))
events = events_to_run(t)
events.each do |event|
if (fire_callbacks(:before_run, event, t))
event.run(t)
fire_callbacks(:after_run, event, t)
end
end
end
fire_callbacks(:after_tick)
events
end
|