class RR::TaskSweeper

Monitors and cancels stalled tasks

Attributes

last_ping[RW]

Time of last ping

terminated[RW]

Set to true if the executed task has timed out

thread[RW]

The task executing thread

timeout_period[RW]

Time in seconds after which a task is considered stalled. Timer is reset by calling ping.

Public Class Methods

new(timeout_period) click to toggle source

Creates a new TaskSweeper

  • timeout_period: timeout value in seconds

# File lib/rubyrep/task_sweeper.rb, line 40
def initialize(timeout_period)
  self.timeout_period = timeout_period
  self.terminated = false
  self.last_ping = Time.now
end
timeout(timeout_period) { |sweeper| ... } click to toggle source

Executes the give block in a separate Thread. Returns if block is finished or stalled. The block must call regular ping to announce it is not stalled.

  • timeout_period: Maximum time (in seonds) without ping, after which a task is considered stalled.

Returns the created sweeper (allows checking if task was terminated).

# File lib/rubyrep/task_sweeper.rb, line 12
def self.timeout(timeout_period)
  sweeper = TaskSweeper.new(timeout_period)
  sweeper.send(:timeout) {yield sweeper}
  sweeper
end

Public Instance Methods

join() click to toggle source

Waits without timeout till the task executing thread is finished

# File lib/rubyrep/task_sweeper.rb, line 34
def join
  thread && thread.join
end
ping() click to toggle source

Must be called by the executed task to announce it is still alive

# File lib/rubyrep/task_sweeper.rb, line 23
def ping
  self.last_ping = Time.now
end
terminated?() click to toggle source

Returns true if the task was timed out. The terminated task is expected to free all resources and exit.

# File lib/rubyrep/task_sweeper.rb, line 29
def terminated?
  terminated
end

Protected Instance Methods

timeout() { || ... } click to toggle source

Executes the given block and times it out if stalled.

# File lib/rubyrep/task_sweeper.rb, line 58
def timeout
  exception = nil
  self.thread = Thread.new do
    begin
      yield
    rescue Exception => e
      # save exception so it can be rethrown outside of the thread
      exception = e
    end
  end
  while self.thread.join(self.timeout_period) == nil do
    if self.last_ping < Time.now - self.timeout_period
      self.terminated = true
      break
    end
  end
  raise exception if exception
end