Class: Keeper::Keeper

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

Overview

A thread-safe blocking event pattern for your pleasure.

Examples:

events = Keeper::Keeper.new

[:pang, :boom, :pow].each_with_index do |event, i|
  this_many = i + 1
  this_many.times do |i|
    Thread.new do
      events.wait_for(event)
      puts "#{event}:#{i}!"
      events.fire(event == :pang ? :boom : :pow)
    end
  end
  puts "#{this_many} threads waiting for #{event}"
end

print "Pause for effect"
3.times { sleep 1 and print "." }
puts

events.fire(:pang)
Thread.list.reject { |th| th == Thread.current }.map(&:join)

Instance Method Summary collapse

Constructor Details

#initializeKeeper

Create a new Keeper::Keeper instance.


34
35
36
37
# File 'lib/keeper.rb', line 34

def initialize
  @waiting = {}
  @mootex  = Mutex.new
end

Instance Method Details

#fire(event) ⇒ Keeper

Fires the given event, waking up the waiting threads.

Parameters:

  • event (Symbol)

Returns:


43
44
45
46
47
48
49
# File 'lib/keeper.rb', line 43

def fire(event)
  @mootex.synchronize do
    condition = @waiting.delete(event)
    condition.broadcast unless condition.nil?
  end
  self
end

#wait_for(event) ⇒ Keeper

Waits for the given event to fire.

Parameters:

  • event (Symbol)

Returns:


55
56
57
58
59
60
# File 'lib/keeper.rb', line 55

def wait_for(event)
  @mootex.synchronize do
    (@waiting[event] ||= ConditionVariable.new).wait(@mootex)
  end
  self
end

#waitingArray<Symbol>

A list of all events currently being waited for.

Returns:

  • (Array<Symbol>)

65
66
67
# File 'lib/keeper.rb', line 65

def waiting
  @mootex.synchronize { @waiting.keys }
end