Class: Wurk::TimerLoop

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

Overview

Mutex/CV "tick every N seconds until told to stop" primitive shared by every leader-gated periodic component (History, Metrics::Rollup, Metrics::QueueRollup). Each of those used to hand-roll the same @mutex/@sleeper/@done dance; this is that dance, extracted once.

The host owns thread spawning (it needs its own safe_thread from Component for logger/handle_exception context) and the leader-gate check inside its tick — TimerLoop only owns the interval wait and the start/terminate signaling around it:

@timer = Wurk::TimerLoop.new(interval)
@thread ||= safe_thread('my-loop') { @timer.run { tick } }
def terminate = @timer.terminate

Constant Summary collapse

JOIN_TIMEOUT =

Deadline every periodic component gives its loop thread when stopping. Bounded rather than an open-ended join: a tick blocked on a wedged Redis must not hold the process's whole shutdown open. Also used by Scheduled::Poller, which hand-rolls its wait (the interval is randomized per iteration) but stops on the same terms.

5

Instance Method Summary collapse

Constructor Details

#initialize(interval) ⇒ TimerLoop

Returns a new instance of TimerLoop.



25
26
27
28
29
30
# File 'lib/wurk/timer_loop.rb', line 25

def initialize(interval)
  @interval = interval
  @done = false
  @mutex = ::Mutex.new
  @sleeper = ::ConditionVariable.new
end

Instance Method Details

#resetObject

Clears a previous #terminate. Hosts call this before respawning, so a start-after-stop cycle spawns a thread that ticks instead of one that sees the stale done flag and exits immediately.



53
54
55
# File 'lib/wurk/timer_loop.rb', line 53

def reset
  @mutex.synchronize { @done = false }
end

#runObject

Waits one interval, then yields repeatedly (waiting between calls) until #terminate is called. Matches the existing components' "don't tick immediately on boot" behavior.



35
36
37
38
39
40
41
# File 'lib/wurk/timer_loop.rb', line 35

def run
  wait
  until @done
    yield
    wait
  end
end

#terminateObject



43
44
45
46
47
48
# File 'lib/wurk/timer_loop.rb', line 43

def terminate
  @mutex.synchronize do
    @done = true
    @sleeper.signal
  end
end

#waitObject



57
58
59
60
61
# File 'lib/wurk/timer_loop.rb', line 57

def wait
  @mutex.synchronize do
    @sleeper.wait(@mutex, @interval) unless @done
  end
end