Class: Garcon::TimerSet

Inherits:
Object show all
Includes:
ExecutorOptions, RubyExecutor
Defined in:
lib/garcon/task/timer_set.rb

Overview

Executes a collection of tasks, each after a given delay. A master task monitors the set and schedules each task for execution at the appropriate time. Tasks are run on the global task pool or on the supplied executor.

Constant Summary

Constants included from RubyExecutor

RubyExecutor::FALLBACK_POLICY

Instance Attribute Summary

Attributes included from Executor

#fallback_policy

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RubyExecutor

#running?, #shutdown, #shutdown?, #shuttingdown?, #wait_for_termination

Methods included from Executor

#auto_terminate?, #can_overflow?, #serialized?

Constructor Details

#initialize(opts = {}) ⇒ TimerSet

Create a new set of timed tasks.

`ImmediateExecutor` object.

Parameters:

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

    The options used to specify the executor on which to perform actions.

Options Hash (opts):

  • :executor (Executor)

    When set use the given ‘Executor` instance. Three special values are also supported: `:task` returns the global task pool, `:operation` returns the global operation pool, and `:immediate` returns a new



51
52
53
54
55
56
57
58
# File 'lib/garcon/task/timer_set.rb', line 51

def initialize(opts = {})
  @queue          = PriorityQueue.new(order: :min)
  @task_executor  = get_executor_from(opts) || Garcon.global_io_executor
  @timer_executor = SingleThreadExecutor.new
  @condition      = Condition.new
  init_executor
  enable_at_exit_handler!(opts)
end

Class Method Details

.calculate_delay!(delay) ⇒ Float

Schedule a task to be executed after a given delay (in seconds).

Parameters:

  • delay (Float)

    The number of seconds to wait for before executing the task.

Returns:

  • (Float)

    The number of seconds to delay.

Raises:

  • (ArgumentError)

    if the intended execution time is not in the future

  • (ArgumentError)

    if no block is given.



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/garcon/task/timer_set.rb', line 118

def self.calculate_delay!(delay)
  if delay.is_a?(Time)
    if delay <= now
      raise ArgumentError, 'schedule time must be in the future'
    end
    delay.to_f - now.to_f
  else
    if delay.to_f < 0.0
      raise ArgumentError, 'seconds must be greater than zero'
    end
    delay.to_f
  end
end

Instance Method Details

#killObject



102
103
104
# File 'lib/garcon/task/timer_set.rb', line 102

def kill
  shutdown
end

#post(delay, *args) { ... } ⇒ Boolean

Post a task to be execute run after a given delay (in seconds). If the delay is less than 1/100th of a second the task will be immediately post to the executor.

Parameters:

  • delay (Float)

    The number of seconds to wait for before executing the task.

Yields:

  • the task to be performed.

Returns:

  • (Boolean)

    True if the message is post, false after shutdown.

Raises:

  • (ArgumentError)

    f the intended execution time is not in the future.

  • (ArgumentError)

    if no block is given.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/garcon/task/timer_set.rb', line 76

def post(delay, *args, &task)
  raise ArgumentError, 'no block given' unless block_given?
  delay = TimerSet.calculate_delay!(delay)

  mutex.synchronize do
    return false unless running?

    if (delay) <= 0.01
      @task_executor.post(*args, &task)
    else
      @queue.push(Task.new(Garcon.monotonic_time + delay, args, task))
      @timer_executor.post(&method(:process_tasks))
    end
  end

  @condition.signal
  true
end