Class: RCron

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/rcron/task.rb,
lib/rcron/alarm.rb,
lib/rcron/parser.rb,
lib/rcron/timeout.rb,
lib/rcron/version.rb,
lib/rcron/scheduler.rb

Defined Under Namespace

Modules: Parser Classes: Alarm, Task, Timeout

Constant Summary collapse

VERSION =
"0.1.2"

Instance Method Summary collapse

Constructor Details

#initializeRCron

Returns a new instance of RCron.



10
11
12
13
14
# File 'lib/rcron/scheduler.rb', line 10

def initialize
  @tasks    = []
  @mutex    = Mutex.new
  @sleeping = false
end

Instance Method Details

#enq(name, schedule, options = {}, &block) ⇒ RCron::Task Also known as: q

Enqueues a task to be run

Parameters:

  • name (String)

    Name of the task

  • schedule (String)

    Cron-format schedule string

  • options (Hash) (defaults to: {})

    Additional options for the task. :exclusive and :timeout.

Returns:

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rcron/scheduler.rb', line 21

def enq name, schedule, options = {}, &block
  raise ArgumentError.new("Block not given") unless block_given?

  new_task = nil
  @mutex.synchronize do
    @tasks << new_task = Task.send(:new,
                    self, name, schedule,
                    options[:exclusive], options[:timeout],
                    &block)
  end
  return new_task
end

#start(logger = Logger.new($stdout)) ⇒ Object

Starts the scheduler

Parameters:

  • logger (defaults to: Logger.new($stdout))

    Logger instance. Default is a Logger to standard output.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rcron/scheduler.rb', line 37

def start logger = Logger.new($stdout)
  unless [:info, :warn, :error].all? { |m| logger.respond_to? m }
    raise ArgumentError.new("Invalid Logger")
  end

  @logger = logger
  @thread = Thread.current

  info "rcron started"

  now = Time.now
  while @tasks.length > 0
    # At every minute
    next_tick = Time.at( (now + 60 - now.sec).to_i )
    interval = @tasks.select(&:running?).map(&:timeout).compact.min
    begin
      @mutex.synchronize { @sleeping = true }
      #puts [ next_tick - now, interval ].compact.min
      sleep [ next_tick - now, interval ].compact.min
      @mutex.synchronize { @sleeping = false }
    rescue RCron::Alarm => e
      # puts 'woke up'
    end

    # Join completed threads
    @tasks.select(&:running?).each do |t|
      t.send :join
    end

    # Removed dequeued tasks
    @tasks.reject { |e| e.running? || e.queued? }.each do |t|
      @mutex.synchronize { @tasks.delete t }
    end

    # Start new task threads if it's time
    now = Time.now
    @tasks.select { |e| e.queued? && e.scheduled?(now) }.each do |t|
      if t.running? && t.exclusive?
        warn "[#{t.name}] already running exclusively"
        next
      end

      info "[#{t.name}] started"
      t.send :start, now
    end if now >= next_tick
  end#while
  info "rcron completed"
end

#tabString

Crontab-like tasklist

Returns:

  • (String)


88
89
90
# File 'lib/rcron/scheduler.rb', line 88

def tab
  @tasks.map { |t| "#{t.schedule_expression} #{t.name}" }.join($/)
end