Created
August 31, 2012 02:43
-
-
Save benmoss/3548254 to your computer and use it in GitHub Desktop.
Sleeping barber problem with Celluloid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://en.wikipedia.org/wiki/Sleeping_barber_problem | |
require 'celluloid' | |
class Barbershop | |
include Celluloid | |
include Celluloid::Logger | |
def initialize | |
@waiting_room = WaitingRoom.new | |
@barber = Barber.new(Actor.current) | |
Celluloid::Actor[:waiting_room] = @waiting_room | |
Celluloid::Actor[:barber] = @barber | |
end | |
def enter(customer) | |
info "#{customer.name} has entered" | |
if @waiting_room.full | |
info "no more room for #{customer.name}" | |
else | |
if @barber.asleep | |
info "#{customer.name} is waking the barber" | |
@barber.wake_up!(customer) | |
else | |
info "#{customer.name} is waiting for a haircut" | |
@waiting_room.push!(customer) | |
end | |
end | |
end | |
def next | |
@waiting_room.next | |
end | |
end | |
class WaitingRoom | |
include Celluloid | |
include Celluloid::Logger | |
def initialize | |
@customers = [] | |
end | |
def push(customer) | |
@customers << customer | |
end | |
def full | |
@customers.size >= 3 | |
end | |
def next | |
@customers.pop | |
end | |
def customers | |
@customers | |
end | |
end | |
class Barber | |
include Celluloid | |
include Celluloid::Logger | |
attr_reader :served_count | |
def initialize(barbershop) | |
@barbershop = barbershop | |
@asleep = true | |
@served_count = 0 | |
end | |
def asleep | |
!!@asleep | |
end | |
def wake_up(customer) | |
@customer = customer | |
@asleep = false | |
cut_hair(customer) | |
while customer = @barbershop.next | |
cut_hair(customer) | |
end | |
info "nobody left, going back to sleep" | |
@asleep = true | |
end | |
def cut_hair(customer) | |
info "cutting #{customer.name}..." | |
rand(2).times do | |
sleep(1) | |
end | |
info "#{customer.name} has finished their haircut" | |
@served_count += 1 | |
end | |
end | |
class Customer | |
attr_reader :name | |
def initialize(name) | |
@name = name | |
end | |
end | |
b = Barbershop.new | |
1.upto(20).each do |i| | |
b.enter(Customer.new(i)) | |
sleep(rand(30) / 10) | |
end | |
loop do | |
puts "Total cut: #{Celluloid::Actor[:barber].served_count}" | |
sleep(1) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment