Class: OmfCommon::Eventloop::Local

Inherits:
OmfCommon::Eventloop show all
Defined in:
omf_common/lib/omf_common/eventloop/local_evl.rb

Overview

Implements a simple eventloop which only deals with timer events

Instance Method Summary (collapse)

Methods inherited from OmfCommon::Eventloop

init, instance, #join, #on_int_signal, #on_stop, #on_term_signal

Constructor Details

- (Local) initialize(opts = {}, &block)

Returns a new instance of Local



14
15
16
17
18
19
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 14

def initialize(opts = {}, &block)
  super
  @tasks =  []
  @running = false
  after(0, &block) if block
end

Instance Method Details

- (Object) after(delay_sec, &block)

Execute block after some time

Parameters:

  • delay_sec (Float)

    in sec



25
26
27
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 25

def after(delay_sec, &block)
  @tasks << [Time.now + delay_sec, block]
end

- (Object) defer(&block)

Call 'block' in the context of a separate thread.



39
40
41
42
43
44
45
46
47
48
49
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 39

def defer(&block)
  @logger.note("DEFER")
  Thread.new do
    begin
      block.call()
    rescue  => ex
      @logger.error "Exception '#{ex}'"
      @logger.debug ex.backtract.join("\n\t")
    end
  end
end

- (Object) every(interval_sec, &block)

Periodically call block every interval_sec

Parameters:

  • interval_sec (Float)

    in sec



33
34
35
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 33

def every(interval_sec, &block)
  @tasks << [Time.now + interval_sec, block, :periodic => interval_sec]
end

- (Object) run(&block)



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
85
86
87
88
89
90
91
92
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 56

def run(&block)
  after(0, &block) if block
  return if @running
  @running = true

  while @running do
    now = Time.now
    @tasks = @tasks.sort
    while @tasks[0] && @tasks[0][0] <= now
      # execute
      t = @tasks.shift
      debug "Executing Task #{t}"
      block = t[1]
      block.arity == 0 ? block.call : block.call(self)
      now = Time.now
      # Check if periodic
      if interval = ((t[2] || {})[:periodic])
        if (next_time = t[0] + interval) < now
          warn "Falling behind with periodic task #{t[1]}"
          next_time = now + interval
        end
        @tasks << [next_time, t[1], :periodic => interval]
      end
    end
    # by now, there could have been a few more tasks added, so let's sort again
    @tasks = @tasks.sort
    if @tasks.empty?
      # done
      @running = false
    else
      if (delay = @tasks[0][0] - Time.now) > 0
        debug "Sleeping #{delay}"
        sleep delay
      end
    end
  end
end

- (Object) stop



52
53
54
# File 'omf_common/lib/omf_common/eventloop/local_evl.rb', line 52

def stop
  @running = false
end