Class: OmfCommon::Eventloop::Local

Inherits:
OmfCommon::Eventloop show all
Defined in:
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

#initialize(opts = {}, &block) ⇒ Local

Returns a new instance of Local.



14
15
16
17
18
19
# File '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

#after(delay_sec, &block) ⇒ Object

Execute block after some time

Parameters:

  • delay_sec (Float)

    in sec



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

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

#defer(&block) ⇒ Object

Call ‘block’ in the context of a separate thread.



39
40
41
42
43
44
45
46
47
48
49
# File '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

#every(interval_sec, &block) ⇒ Object

Periodically call block every interval_sec

Parameters:

  • interval_sec (Float)

    in sec



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

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

#run(&block) ⇒ Object



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 '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

#stopObject



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

def stop
  @running = false
end