Class: NFSStore

Inherits:
Object show all
Defined in:
lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

HOSTNAME =
Socket::gethostname

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ NFSStore

Returns a new instance of NFSStore.



26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 26

def initialize(file)
  dir = File::dirname(file)
  unless File::directory? dir
    raise NFSStore::Error, format("directory %s does not exist", dir)
  end
  if File::exist? file and not File::readable? file
    raise NFSStore::Error, format("file %s not readable", file)
  end
  @transaction = false
  @filename = file
  @lockfile = Lockfile.new "#{ @filename }.lock",:max_age=>64,:refresh=>8
  @abort = false
end

Instance Method Details

#[](name) ⇒ Object



45
46
47
48
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 45

def [](name)
  in_transaction
  @table[name]
end

#[]=(name, value) ⇒ Object



59
60
61
62
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 59

def []=(name, value)
  in_transaction
  @table[name] = value
end

#abortObject



83
84
85
86
87
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 83

def abort
  in_transaction
  @abort = true
  throw :pstore_abort_transaction
end

#commitObject



78
79
80
81
82
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 78

def commit
  in_transaction
  @abort = false
  throw :pstore_abort_transaction
end

#delete(name) ⇒ Object



63
64
65
66
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 63

def delete(name)
  in_transaction
  @table.delete name
end

#fetch(name, default = NFSStore::Error) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 49

def fetch(name, default=NFSStore::Error)
  unless @table.key? name
    if default==NFSStore::Error
	raise NFSStore::Error, format("undefined root name `%s'", name)
    else
	default
    end
  end
  self[name]
end

#pathObject



75
76
77
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 75

def path
  @filename
end

#root?(name) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
74
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 71

def root?(name)
  in_transaction
  @table.key? name
end

#rootsObject



67
68
69
70
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 67

def roots
  in_transaction
  @table.keys
end

#transaction(read_only = false) ⇒ Object

Raises:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 110

def transaction(read_only=false)
  raise NFSStore::Error, "nested transaction" if @transaction
  file = nil
  value = nil

@lockfile.lock do
    begin
      @transaction = true
      backup = @filename+"~"
      begin
        file = File::open(@filename, read_only ? "rb" : "rb+")
        orig = true
      rescue Errno::ENOENT
        raise if read_only
        file = File::open(@filename, "wb+")
      end
      #file.flock(read_only ? File::LOCK_SH : File::LOCK_EX)
      uncache file
      file.rewind
      if read_only
        @table = Marshal::load(file)
      elsif orig and (content = file.read) != ""
        @table = Marshal::load(content)
        size = content.size
        md5 = Digest::MD5.digest(content)
        content = nil		# unreference huge data
      else
        @table = {}
      end
      begin
        catch(:pstore_abort_transaction) do
          value = yield(self)
        end
      rescue Exception
        @abort = true
        raise
      ensure
        if !read_only and !@abort
          file.rewind
          content = Marshal::dump(@table)
          if !md5 || size != content.size || md5 != Digest::MD5.digest(content)
            File::copy @filename, backup
            begin
              file.write(content)
              file.truncate(file.pos)
              content = nil		# unreference huge data
            rescue
              File::rename backup, @filename if File::exist?(backup)
              raise
            end
          end
        end
        if @abort and !orig
          File.unlink(@filename)
        end
        @abort = false
      end
    ensure
      @table = nil
      @transaction = false
      file.close if file
    end
end
    value
end

#uncache(file) ⇒ Object

do what we can to invalidate any nfs caching



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/crazy_ivan/vendor/lockfile-1.4.3/samples/nfsstore.rb', line 90

def uncache file 
  begin
    stat = file.stat
    path = file.path
    refresh = "%s.%s.%s.%s" % [path, HOSTNAME, $$, Time.now.to_i % 1024] 
    File.link path, refresh
    file.chmod stat.mode
    File.utime stat.atime, stat.mtime, path
  rescue Exception => e 
    warn e
  ensure
    begin
      File.unlink refresh if File.exist? refresh
    rescue Exception => e
      warn e
    end
  end
end