| Class | Dsadmin::Admind::Cron |
| In: |
lib/dsadmin/admind/Cron.rb
|
| Parent: | Object |
Internal task scheduler.
A replacement for cron(8) adapted to our special needs:
This is intended to run as a "background service" (singleton) on the master admind instance. Scheduling has a granularity/precision of 60s.
Note: "Normal" clients should not access the Cron instance directly, but instead use a CronProxy, which will then automatically forward everything to the "real" Cron, no matter if it‘s running locally or on a different machine.
| See also: | class CronjobSpec |
| See also: | class CronProxy |
| See also: | class Dsadmin::Common::TimeSpec |
| See also: | class RetryPolicy |
| RETRY_REG15 | = | RetryPolicy.new(:regular, [15]) | Common retry policy: Every 15 mins | |
| RETRY_EXP15 | = | RetryPolicy.new(:exponential, [15]) | Common retry policy: After 15 mins, then doubling that interval each time | |
| RETRY_ONCE15 | = | RetryPolicy.new(:fixed, [15]) | Common retry policy: Once, after 15 mins | |
| RETRY_REG015 | = | RetryPolicy.new(:regular, [0, 15]) | Common retry policy: Retry immediately, then every 15 mins | |
| RETRY_EXP015 | = | RetryPolicy.new(:exponential, [0, 15]) | Common retry policy: Retry immediately, then after 15 mins, then doubling that interval each time |
| thread | [R] |
# File lib/dsadmin/admind/Cron.rb, line 398
398: def initialize
399: @jobs = Hash.new # jobid => Cronjob
400: @mutex = Mutex.new
401: @running_id = 0
402: @shutdown = false
403: end
Add and schedule a job (given as a CronjobSpec).
| Returns: | The job‘s ID |
# File lib/dsadmin/admind/Cron.rb, line 302
302: def add(aCronjobSpec)
303: requireKindOf(CronjobSpec, aCronjobSpec)
304: id = nil
305:
306: @mutex.synchronize {
307: while(@jobs.has_key?(@running_id))
308: @running_id += 1
309: end
310: id = @running_id
311:
312: @jobs[id] = Cronjob.new(aCronjobSpec)
313: s = aCronjobSpec
314: log.notice("Scheduling '#{s.request.uri}' for execution at/every #{s.timespec.to_s}")
315: }
316:
317: return id
318: end
Force the specified job to be executed now (in a seperate thread).
If the job is already running, nothing happens.
# File lib/dsadmin/admind/Cron.rb, line 356
356: def forcerun(aJobID)
357: return if @shutdown
358:
359: @mutex.synchronize {
360: checkNotNil(@jobs[aJobID])
361: @jobs[aJobID].force_run()
362: }
363: end
Pause scheduling of the specified cronjob.
This means no further execution of it is triggered until resume is called for it. This does not pause a currently running job — only its further scheduling.
# File lib/dsadmin/admind/Cron.rb, line 336
336: def pause(aJobID)
337: @mutex.synchronize {
338: checkNotNil(@jobs[aJobID])
339: @jobs[aJobID].pause()
340: }
341: end
Get a list of scheduled tasks and their status (Array of Hashes)
# File lib/dsadmin/admind/Cron.rb, line 367
367: def ps
368: res = Array.new
369:
370: @mutex.synchronize do
371: @jobs.each do |key, job|
372: entry = {
373: 'jobid' => key,
374: 'uri' => job.uri,
375: 'user' => job.username,
376: 'last_run_time' => job.last_run_time,
377: 'last_end_time' => job.last_end_time,
378: 'next_run_time' => job.next_run_time,
379: 'success_count' => job.success_count,
380: 'failure_count' => job.failure_count,
381: 'delay_count' => job.delay_count,
382: 'state' => job.state_s,
383: 'last_result' => job.last_result_s
384: }
385:
386: res << entry
387: end
388: end
389:
390: return res
391: end
Remove the specified cronjob. If the job is running, this does not abort it.
# File lib/dsadmin/admind/Cron.rb, line 322
322: def remove(aJobID)
323: # abort(aJobID)
324: @mutex.synchronize {
325: checkNotNil(@jobs[aJobID])
326: @jobs.delete(aJobID)
327: }
328: end
# File lib/dsadmin/admind/Cron.rb, line 293
293: def running?
294: return thread && (thread.alive?)
295: end
# File lib/dsadmin/admind/Cron.rb, line 287
287: def shutdown
288: @shutdown = true
289: thread.wakeup if running?
290: end
Main loop
# File lib/dsadmin/admind/Cron.rb, line 407
407: def runMain
408: while(! @shutdown)
409: t_start = sys.now.to_i
410: visitJobs
411: t_end = sys.now.to_i
412: t_sleep = 60 - (t_end - t_start)
413: #puts "Next pass in #{t_sleep} seconds"
414: sleep(t_sleep) if(t_sleep > 0)
415: end
416: end