Class: Schedulero
- Inherits:
-
Object
- Object
- Schedulero
- Includes:
- Utils
- Defined in:
- lib/utils.rb,
lib/schedulero.rb
Defined Under Namespace
Modules: Utils
Instance Attribute Summary collapse
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
-
#tasks ⇒ Object
readonly
Returns the value of attribute tasks.
Instance Method Summary collapse
-
#at(name, hours, proc = nil, &block) ⇒ Object
run task at specific hours.
-
#every(name, seconds, proc = nil, &block) ⇒ Object
add task.
- #init_log(log_file) ⇒ Object
- #init_state(state_file) ⇒ Object
-
#initialize(state_file: nil, log_file: true, silent: false) ⇒ Schedulero
constructor
A new instance of Schedulero.
-
#log_errror(name) ⇒ Object
show and log error.
-
#run ⇒ Object
run all tasks once, safe.
- #run_forever(interval: 3) ⇒ Object
-
#safe_run(block) ⇒ Object
run in rescue mode, kill if still running.
- #show(text) ⇒ Object
Methods included from Utils
#humanize_seconds, #quick_overview
Constructor Details
#initialize(state_file: nil, log_file: true, silent: false) ⇒ Schedulero
Returns a new instance of Schedulero.
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/schedulero.rb', line 15 def initialize state_file: nil, log_file: true, silent: false @silent = silent @tasks = {} @running = {} @count = 0 init_log log_file init_state state_file end |
Instance Attribute Details
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
13 14 15 |
# File 'lib/schedulero.rb', line 13 def logger @logger end |
#tasks ⇒ Object (readonly)
Returns the value of attribute tasks.
13 14 15 |
# File 'lib/schedulero.rb', line 13 def tasks @tasks end |
Instance Method Details
#at(name, hours, proc = nil, &block) ⇒ Object
run task at specific hours
67 68 69 70 |
# File 'lib/schedulero.rb', line 67 def at name, hours, proc=nil, &block proc ||= block @tasks[name] = { at: hours , func: proc, name: name } end |
#every(name, seconds, proc = nil, &block) ⇒ Object
add task
61 62 63 64 |
# File 'lib/schedulero.rb', line 61 def every name, seconds, proc=nil, &block proc ||= block @tasks[name] = { interval: seconds , func: proc, name: name } end |
#init_log(log_file) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/schedulero.rb', line 35 def init_log log_file # log file @log_file = case log_file when String log_file when false nil else "./log/schedulero.log" end show 'Log file : %s' % @log_file @logger = Logger.new @log_file @logger.formatter = proc do |severity, datetime, progname, msg| severity = severity == 'INFO' ? '' : "(#{severity}) " "[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}]: #{severity}#{msg}\n" end end |
#init_state(state_file) ⇒ Object
26 27 28 29 30 31 32 33 |
# File 'lib/schedulero.rb', line 26 def init_state state_file # state file state_file ||= "./tmp/schedulero.json" show 'State file: %s' % state_file @state_file = Pathname.new state_file @state_file.write '{}' unless @state_file.exist? end |
#log_errror(name) ⇒ Object
show and log error
156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/schedulero.rb', line 156 def log_errror name msg = if $! '%s: %s (%s)' % [name, $!., $!.class] else name end show msg.red @logger.error(msg) end |
#run ⇒ Object
run all tasks once, safe
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/schedulero.rb', line 83 def run state = JSON.load @state_file.read state['_pid'] ||= Process.pid state['_last_run'] ||= Time.now.to_i diff = Time.now.to_i - state['_last_run'] # if another process is controlling state, exit if state['_pid'] != Process.pid && diff < 10 show "Another process [#{state['_pid']}] is controlling state before #{diff} sec, skipping. I am (#{Process.pid})".red return end for name, block in @tasks state[name] ||= 0 now = Time.now.to_i if block[:at] # run at specific times hour_now = Time.now.hour hours = block[:at].class == Array ? block[:at] : [block[:at]] if hours.include?(hour_now) && (Time.now.to_i - state[name] > 3700) state[name] = now safe_run block end else # run in intervals seconds = block[:interval] diff = (state[name].to_i + seconds.to_i) - now if diff < 0 state[name] = now safe_run block else show 'skipping "%s" for %s' % [name, humanize_seconds(diff)] end end end state['_last_run'] = Time.now.to_i state['_pid'] = Process.pid @state_file.write state.to_json end |
#run_forever(interval: 3) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/schedulero.rb', line 72 def run_forever interval: 3 Thread.new do loop do show 'looping ...' run sleep interval end end end |
#safe_run(block) ⇒ Object
run in rescue mode, kill if still running
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/schedulero.rb', line 130 def safe_run block name = block[:name] show 'Running "%s"' % name.green @logger.info 'Run: %s' % name if block[:running] log_errror "Task [#{block[:name]}] is still running, killing..." Thread.kill(block[:running]) end thread = Thread.start(block) do |b| block[:running] = thread begin @count += 1 b[:func].call @count rescue log_errror b[:name] end b[:running] = false end end |
#show(text) ⇒ Object
55 56 57 58 |
# File 'lib/schedulero.rb', line 55 def show text return if @silent puts 'Schedulero: %s' % text end |