Module: Ccp::Kvs::Kyoto::StateMachine
Constant Summary collapse
- CLOSED =
state machine
1
- READABLE =
2
- WRITABLE =
3
- LOCKED_BY =
proc{|c| Array(c).select{|i| i !~ %r{/ruby/[^/]+/gems/}}[0,5].join("\n") || c rescue c}
Instance Method Summary collapse
- #__close__(locker = nil) ⇒ Object
- #C!(locker = nil) ⇒ Object
- #close(locker = nil) ⇒ Object
- #locker_info ⇒ Object
- #open(mode, locker = nil) ⇒ Object
- #R(locker = nil, &block) ⇒ Object
- #R!(locker = nil) ⇒ Object
- #state ⇒ Object
- #touch ⇒ Object
- #W(locker = nil, &block) ⇒ Object
- #W!(locker = nil) ⇒ Object
Instance Method Details
#__close__(locker = nil) ⇒ Object
52 53 54 55 56 |
# File 'lib/ccp/kvs/kyoto/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 |
#C!(locker = nil) ⇒ Object
62 63 64 65 66 67 68 69 |
# File 'lib/ccp/kvs/kyoto/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 |
#close(locker = nil) ⇒ Object
58 59 60 |
# File 'lib/ccp/kvs/kyoto/state_machine.rb', line 58 def close(locker = nil) C!(locker) end |
#locker_info ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/ccp/kvs/kyoto/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) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/ccp/kvs/kyoto/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 Kyoto::Locked, "%s is locked by [%s]" % [@source, locker_info] else kyoto_error!("%s#open(%s,%s): " % [self.class, @source, mode]) end end |
#R(locker = nil, &block) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/ccp/kvs/kyoto/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) ⇒ Object
71 72 73 74 75 76 77 78 |
# File 'lib/ccp/kvs/kyoto/state_machine.rb', line 71 def R!(locker = nil) case state when CLOSED ; open(DB::OREADER, locker); @state = READABLE when READABLE ; # NOP when WRITABLE ; # NOP else ; raise "unknown state: #{state}" end end |
#state ⇒ Object
16 17 18 |
# File 'lib/ccp/kvs/kyoto/state_machine.rb', line 16 def state @state || CLOSED end |
#touch ⇒ Object
108 109 110 |
# File 'lib/ccp/kvs/kyoto/state_machine.rb', line 108 def touch W() {} end |
#W(locker = nil, &block) ⇒ Object
98 99 100 101 102 103 104 105 106 |
# File 'lib/ccp/kvs/kyoto/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) ⇒ Object
80 81 82 83 84 85 86 87 |
# File 'lib/ccp/kvs/kyoto/state_machine.rb', line 80 def W!(locker = nil) case state when CLOSED ; open(DB::OCREATE | DB::OWRITER, locker); @state = WRITABLE when READABLE ; C!(locker); W!(locker) when WRITABLE ; # NOP else ; raise "unknown state: #{state}" end end |