module Ccp::Kvs::Tokyo::StateMachine

Constants

CLOSED

state machine

LOCKED_BY
READABLE
WRITABLE

Public Instance Methods

C!(locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 62
def C!(locker = nil)
  case state
  when CLOSED   ; # NOP
  when READABLE,
       WRITABLE ; __close__(locker); @state = CLOSED
  else          ; raise "unknown state: #{state}"
  end
end
R(locker = nil) { || ... } click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 89
def R(locker = nil, &block)
  case state
  when CLOSED   ; begin; R!(locker); yield; ensure; close(locker); end
  when READABLE ; yield
  when WRITABLE ; yield
  else          ; raise "unknown state: #{state}"
  end
end
R!(locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 71
def R!(locker = nil)
  case state
  when CLOSED   ; open(HDB::OREADER, locker); @state = READABLE
  when READABLE ; # NOP
  when WRITABLE ; # NOP
  else          ; raise "unknown state: #{state}"
  end
end
W(locker = nil) { || ... } click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 98
def W(locker = nil, &block)
  case state
  when CLOSED   ; begin; W!(locker); yield; ensure; close(locker); end
  when READABLE ; raise "reopen from read to write is not permitted"
    # TODO: close -> W -> close -> R ???
  when WRITABLE ; yield
  else          ; raise "unknown state: #{state}"
  end
end
W!(locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 80
def W!(locker = nil)
  case state
  when CLOSED   ; open(HDB::OCREAT | HDB::OWRITER, locker); @state = WRITABLE
  when READABLE ; C!(locker); W!(locker)
  when WRITABLE ; # NOP
  else          ; raise "unknown state: #{state}"
  end
end
__close__(locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 52
def __close__(locker = nil)
  @db.close
  CONNECTIONS[@db.path] = nil
  STDERR.puts "UNLOCK: #{@source} by [#{LOCKED_BY[locker || caller]}]" if @debug
end
close(locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 58
def close(locker = nil)
  C!(locker)
end
locker_info() click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 20
def locker_info
  if CONNECTIONS[@source]
    return LOCKED_BY[CONNECTIONS[@source]]
  end

  target = File.basename(@source)
  CONNECTIONS.each_pair do |file, reason|
    return LOCKED_BY[reason] if File.basename(file) == target
  end

  if CONNECTIONS.any?
    return CONNECTIONS.inspect
  else
    return 'no brockers. maybe locked by other systems?'
  end
end
open(mode, locker = nil) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 37
def open(mode, locker = nil)
  Pathname(@source.to_s).parent.mkpath

  # open and mark filename for threading error
  if @db.open(@source.to_s, mode)
    locker ||= (caller rescue "???")
    STDERR.puts "LOCK: #{@source} by [#{LOCKED_BY[locker]}]" if @debug
    CONNECTIONS[@db.path.to_s] = locker
  elsif threading_error?
    raise Tokyo::Locked, "%s is locked by [%s]" % [@source, locker_info]
  else
    tokyo_error!("%s#open(%s,%s): " % [self.class, @source, mode])
  end
end
state() click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 16
def state
  @state || CLOSED
end
touch() click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 108
def touch
  W() {}
end

Private Instance Methods

isReadable() click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 113
def isReadable
  case state
  when CLOSED   ; false
  when READABLE ; true
  when WRITABLE ; true
  else          ; raise "unknown state: #{state}"
  end
end
isWritable() click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 122
def isWritable
  case state
  when CLOSED   ; false
  when READABLE ; false
  when WRITABLE ; true
  else          ; raise "unknown state: #{state}"
  end
end
tryR(op) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 131
def tryR(op)
  isReadable or raise NotAllowed, "use R! or R{tch.%s} (%s)" % [op, source]
end
tryW(op) click to toggle source
# File lib/ccp/kvs/tokyo/state_machine.rb, line 135
def tryW(op)
  isWritable or raise NotAllowed, "use W! or W{tch.%s} (%s)" % [op, source]
end