Another dRuby example using single process entry structure
require 'drb/drb'
class Vault
# vault has it's own URI stored
SOCK = '/tmp/drb-prototype_vault.sock'
URI = "drbunix:#{SOCK}"
def initialize
@mutex = Mutex.new
@shared_value = 0
puts 'Vault initialized'
end
def inc
@mutex.synchronize {
@shared_value += 1
}
end
def val
@shared_value
end
end
$ ruby controller.rb
Start
Make sure Vault is up and running
Booting Vault
Vault initialized
Waiting processing forks to finish
[2] value: 0
[2] value: 1
[3] value: 2
[1] value: 3
[2] value: 4
[3] value: 5
[2] value: 6
[3] value: 7
[1] value: 8
[3] value: 9
[2] value: 10
[1] value: 11
[3] value: 12
[1] value: 13
[2] value: 14
[3] value: 15
[2] value: 16
[3] value: 17
[1] value: 18
[3] value: 19
[2] value: 20
[1] value: 21
[2] value: 22
[3] value: 23
[1] value: 24
[3] value: 25
[2] value: 26
[1] value: 27
[1] value: 28
[1] value: 29
Final value: 30
Shutting down vault
All finished
require 'drb/drb'
class Function
def initialize
@vault = DRbObject.new_with_uri Vault::URI
end
def perform
pids = []
(1..3).each do |i|
pids << fork {
vault = DRbObject.new_with_uri Vault::URI
(1..10).each {
sleep rand
puts "[#{i}] value: #{vault.val}"
vault.inc
}
exit 0
}
end
puts 'Waiting processing forks to finish'
pids.each do |pid|
Process.waitpid(pid)
end
puts "Final value: #{@vault.val}"
end
end
require 'fileutils'
require 'timeout'
require 'drb/drb'
require_relative 'vault'
require_relative 'function'
class Controller
def initialize
puts 'Start'
@vault_pid = fork do
# init vault's process
puts 'Booting Vault'
FileUtils.rm_f Vault::SOCK
DRb.start_service Vault::URI, Vault.new
DRb.thread.join
end
Process.detach @vault_pid
# guard the boot process
puts 'Make sure Vault is up and running'
Timeout::timeout(10) {
until File.exists? Vault::SOCK do
sleep 0.1
end
true
}
end
def perform
Function.new.perform
ensure
puts 'Shutting down vault'
Process.kill 'HUP', @vault_pid
puts 'All finished'
end
end
Controller.new.perform