Module: Ccp::Kvs::Tokyo::StateMachine

Includes:
TokyoCabinet
Included in:
Cabinet
Defined in:
lib/ccp/kvs/tokyo/state_machine.rb

Constant Summary collapse

CLOSED =

state machine

1
READABLE =
2
WRITABLE =
3

Instance Method Summary collapse

Instance Method Details

#__close__Object



50
51
52
53
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 50

def __close__
  @db.close
  CONNECTIONS[@db.path] = nil
end

#C!Object



59
60
61
62
63
64
65
66
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 59

def C!
  case state
  when CLOSED   ; # NOP
  when READABLE,
       WRITABLE ; __close__; @state = CLOSED
  else          ; raise "unknown state: #{state}"
  end
end

#closeObject



55
56
57
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 55

def close
  C!
end

#locker_infoObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 18

def locker_info
  pretty = proc{|c| Array(c).find{|i| i !~ %r{/ruby/[^/]+/gems/}} || c}

  if CONNECTIONS[@source]
    return pretty[CONNECTIONS[@source]]
  end

  target = File.basename(@source)
  CONNECTIONS.each_pair do |file, reason|
    return pretty[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) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 37

def open(mode)
  Pathname(@source.to_s).parent.mkpath

  # open and mark filename for threading error
  if @db.open(@source.to_s, mode)
    CONNECTIONS[@db.path.to_s] = (caller rescue "???")
  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

#R(&block) ⇒ Object



86
87
88
89
90
91
92
93
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 86

def R(&block)
  case state
  when CLOSED   ; begin; R!(); yield; ensure; close; end
  when READABLE ; yield
  when WRITABLE ; yield
  else          ; raise "unknown state: #{state}"
  end
end

#R!Object



68
69
70
71
72
73
74
75
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 68

def R!
  case state
  when CLOSED   ; open(HDB::OREADER); @state = READABLE
  when READABLE ; # NOP
  when WRITABLE ; # NOP
  else          ; raise "unknown state: #{state}"
  end
end

#stateObject



14
15
16
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 14

def state
  @state || CLOSED
end

#touchObject



105
106
107
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 105

def touch
  W() {}
end

#W(&block) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 95

def W(&block)
  case state
  when CLOSED   ; begin; W!(); yield; ensure; close; 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!Object



77
78
79
80
81
82
83
84
# File 'lib/ccp/kvs/tokyo/state_machine.rb', line 77

def W!
  case state
  when CLOSED   ; open(HDB::OCREAT | HDB::OWRITER); @state = WRITABLE
  when READABLE ; C!; W!()
  when WRITABLE ; # NOP
  else          ; raise "unknown state: #{state}"
  end
end