Class: PSched::Operation

Inherits:
Object
  • Object
show all
Defined in:
lib/psched.rb

Overview

Implements a recurring operation.

Examples:

General usage. Note the sleep call.

op = PSched::Operation.new(0.5)
op.start(10) do |i|
  puts "Ping #{i}"
end

Signal.trap("SIGINT") do
  print "Stopping recurring process..."
  op.stop
  puts "done!"
end

sleep(0.2) while op.active?  # THIS IS IMPORTANT!!!

Author:

  • Paolo Bosetti

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(step) ⇒ Operation

Initializer

Parameters:

  • step (Numeric)

    the timestep in seconds



97
98
99
100
101
102
103
# File 'lib/psched.rb', line 97

def initialize(step)
  @step          = step
  @active        = false
  @lock          = false
  @strict_timing = false
  @tet           = 0
end

Instance Attribute Details

#start_timeObject (readonly)

Returns the value of attribute start_time.



93
# File 'lib/psched.rb', line 93

attr_reader :step, :tet, :start_time

#stepObject

The time step in seconds



93
94
95
# File 'lib/psched.rb', line 93

def step
  @step
end

#strict_timingObject

If true, raise a RealTimeError when TET >= step (default to false)



85
86
87
# File 'lib/psched.rb', line 85

def strict_timing
  @strict_timing
end

#tetObject (readonly)

The Task Execution Time



93
# File 'lib/psched.rb', line 93

attr_reader :step, :tet, :start_time

Class Method Details

.prioritize(nice = -20)) ⇒ Object

TODO:

better return message and error management

Changes scheduling priority of the current process

Parameters:

  • nice (Fixnum) (defaults to: -20))

    sets the nice level (-20..+20)



77
78
79
80
# File 'lib/psched.rb', line 77

def self.prioritize(nice = -20)
  result = PSched.setpriority(:prio_process,0,nice)
  puts "Setting max priority: #{result == 0 ? 'success' : 'failure (missing sudo?)'}"
end

Instance Method Details

#active?Boolean

Tells id the recurring operation is active or not.

Returns:

  • (Boolean)

    the status of the recurring alarm operation



122
# File 'lib/psched.rb', line 122

def active?; @active; end

#scheduleObject

Note:

Usually, there's no need to call this, since #step= automatically calls it after having set the +@step+ attribute.

Updates scheduling of pending alarms.



115
116
117
118
# File 'lib/psched.rb', line 115

def schedule
  usecs = @step * 1E6
  PSched::ualarm(usecs, usecs)
end

#start(n_iter = nil) {|i, t, tet| ... } ⇒ Object

Starts a recurring operation, described by the passed block. If the block returns the symbol :stop, the recurrin operation gets disabled.

Parameters:

  • n_iter (Fixnum, nil) (defaults to: nil)

    the maximum number of iterations. If nil it loops indefinitedly

Yield Parameters:

  • i (Fixnum)

    the number of elapsed iterations

  • t (Float)

    the time elapsed since the beginning of current Operation

  • tet (Float)

    the Task Execution Time of previous step

Raises:

  • (ArgumentError)

    unless a block is given

  • (RealTimeError)

    if TET exceeds @step



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/psched.rb', line 134

def start(n_iter=nil)
  raise ArgumentError, "Need a block!" unless block_given?
  @active = true
  i = 0
  @start_time = Time.now
  Signal.trap(:ALRM) do
    # If there is still a pending step, raises an error containing
    # information about the CURRENT step
    if @lock then
      if @strict_timing
        @lock = false
        raise RealTimeError.new({:tet => @tet, :step => @step, :i => i, :time => Time.now})
      end
    else
      start = Time.now
      @lock = true
      result = yield(i, Time.now - @start_time, @tet)
      i += 1
      self.stop if (n_iter and i >= n_iter)
      self.stop if (result.kind_of? Symbol and result == :stop)
      @tet = Time.now - start
      @lock = false
    end
  end
  self.schedule
end

#stopObject

Stops the recurring process by resetting alarm and disabling management of SIGALRM signal.



163
164
165
166
167
168
# File 'lib/psched.rb', line 163

def stop
  PSched::ualarm(0, 0)
  Signal.trap(:ALRM, "DEFAULT")
  @active = false
  @lock = false
end