Class: ModSpox::Timer

Inherits:
Pool
  • Object
show all
Defined in:
lib/mod_spox/Timer.rb

Instance Attribute Summary

Attributes inherited from Pool

#proc, #queue

Instance Method Summary collapse

Methods inherited from Pool

#destroy, #start_pool

Constructor Details

#initialize(pipeline) ⇒ Timer

pipeline

message pipeline

Create a new Timer



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/mod_spox/Timer.rb', line 14

def initialize(pipeline)
    super()
    @pipeline = pipeline
    @timers = Array.new
    Logger.log("Created queue: #{@queue} in timer", 10)
    @monitor = Monitors::Timer.new
    @thread = nil
    @stop_timer = false
    @owners = {}
    @owners_lock = Mutex.new
    {:Internal_TimerAdd => :add_message,
     :Internal_TimerRemove => :remove_message,
     :Internal_TimerClear => :clear}.each_pair do |type,method|
        @pipeline.hook(self, method, type)
    end
    start_pool
end

Instance Method Details

#add(period, once = false, data = nil, &func) ⇒ Object

period

seconds between running action

once

only run action once

data

data to be available

&func

data block to run

Adds a new action to the timer



70
71
72
73
74
75
# File 'lib/mod_spox/Timer.rb', line 70

def add(period, once=false, data=nil, &func)
    action = Action.new(self, period, data, once, &func)
    @timers << action
    wakeup
    return action
end

#add_action(action) ⇒ Object

action

Action to add to timer’s queue

Adds a new action to the timer



79
80
81
82
83
# File 'lib/mod_spox/Timer.rb', line 79

def add_action(action)
    raise Exceptions::InvalidType.new('An Action object must be supplied') unless action.is_a?(Action)
    @timers << action
    wakeup
end

#add_message(message) ⇒ Object

message

TimerAdd message

Add a recurring code block



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/mod_spox/Timer.rb', line 40

def add_message(message)
    Logger.log("New block is being added to the timer", 15)
    action = nil
    @owners_lock.synchronize do
        action = add(message.period, message.once, message.data, &message.block)
        @owners[message.requester.name.to_sym] = [] unless @owners.has_key?(message.requester.name.to_sym)
        @owners[message.requester.name.to_sym] << action
    end
    begin
        @pipeline << Messages::Internal::TimerResponse.new(message.requester, action, true, message.id)
        Logger.log("New block was successfully added to the timer", 15)
    rescue Object => boom
        Logger.log("Failed to add block to timer: #{boom}", 10)
        @pipeline << Messages::Internal::TimerResponse.new(message.requester, action, false, message.id)
    end
end

#clear(message = nil) ⇒ Object

Clears all actions in the timer’s queue



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/mod_spox/Timer.rb', line 120

def clear(message=nil)
    if(message.nil? || message.plugin.nil?)
        @queue.clear
        @timers.clear
        @owners.clear
    else
        @owners_lock.synchronize do
            if(@owners.has_key?(message.plugin))
                @owners[message.plugin].each do |action|
                    remove(action)
                end
            end
        end
    end
end

#remove(action) ⇒ Object

action

Action to remove from timer’s queue

Removes and action from the timer



87
88
89
90
91
# File 'lib/mod_spox/Timer.rb', line 87

def remove(action)
    raise Exceptions::InvalidType.new('An Action object must be supplied') unless action.is_a?(Action)
    @timers.delete(action)
    wakeup
end

#remove_message(message) ⇒ Object

message

TimerRemove message

Remove an action from the timer



59
60
61
62
63
# File 'lib/mod_spox/Timer.rb', line 59

def remove_message(message)
    remove(message.action)
    Logger.log("Action has been removed from the Timer", 15)
    @pipeline << Messages::Internal::TimerResponse.new(nil, message.action, false, message.id)
end

#startObject

Starts the timer



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mod_spox/Timer.rb', line 94

def start
    raise Exceptions::AlreadyRunning.new('Timer is already running') unless @thread.nil?
    @thread = Thread.new{
        until @stop_timer do
            to_sleep = nil
            @timers.each do |a|
                to_sleep = a.remaining if to_sleep.nil?
                to_sleep = a.remaining if !a.remaining.nil? && a.remaining < to_sleep
            end
            Logger.log("Timer is set to sleep for #{to_sleep.nil? ? 'forever' : "#{to_sleep} seconds"}", 15)
            actual_sleep = @monitor.wait(to_sleep)
            tick(actual_sleep)
            Logger.log("Timer was set to sleep for #{to_sleep.nil? ? 'forever' : "#{to_sleep} seconds"} seconds. Actual sleep time: #{actual_sleep} seconds", 15)
        end
    }
end

#stopObject

Stops the timer



112
113
114
115
116
117
# File 'lib/mod_spox/Timer.rb', line 112

def stop
    raise Exceptions::NotRunning.new('Timer is not running') if @thread.nil?
    @stop_timer = true
    wakeup
    @thread.join
end

#wakeupObject

Wakes the timer up early



33
34
35
36
# File 'lib/mod_spox/Timer.rb', line 33

def wakeup
    Logger.log("Timer has been explicitly told to wakeup", 15)
    @monitor.wakeup unless @thread.nil?
end