Class: Triglav::Agent::StorageFile
- Inherits:
-
Object
- Object
- Triglav::Agent::StorageFile
- Defined in:
- lib/triglav/agent/storage_file.rb
Overview
Thread and inter-process safe YAML file storage
StorageFile.open($setting.status_file) do |fp|
status = fp.load
status['foo'] = 'bar'
fp.dump(status)
end
Instance Attribute Summary collapse
-
#fp ⇒ Object
readonly
Returns the value of attribute fp.
Class Method Summary collapse
-
.get(path, key) ⇒ Object
Get value of the given key from storage file.
-
.getsetnx(path, key, val) ⇒ Object
Set key to hold val if key does not exist and returns the holded value.
-
.load(path) ⇒ Hash
Load storage file.
-
.merge!(path, key, val) ⇒ Object
Merge Hash value with existing Hash value.
-
.open(path, &block) ⇒ Object
Open storage file.
-
.readopen(path, &block) ⇒ Object
Open storage file to read.
-
.select!(path, parents = [], keys) ⇒ Object
Keep specified keys, and remove others.
-
.set(path, key, val) ⇒ Object
Set storage file with given key, value.
-
.setnx(path, key, val) ⇒ Boolean
Set key to hold val if key does not exist.
Instance Method Summary collapse
-
#dump(hash) ⇒ Object
Dump to storage file.
-
#load ⇒ Hash
Load storage file.
Instance Attribute Details
#fp ⇒ Object (readonly)
Returns the value of attribute fp
14 15 16 |
# File 'lib/triglav/agent/storage_file.rb', line 14 def fp @fp end |
Class Method Details
.get(path, key) ⇒ Object
Get value of the given key from storage file
StorageFile.get($setting.status_file, 'foo') # like h['foo'] = 'bar'
StorageFile.get($setting.status_file, ['a','b']) # like hash['a']['b']
175 176 177 178 |
# File 'lib/triglav/agent/storage_file.rb', line 175 def self.get(path, key) keys = Array(key) readopen(path) {|fp| fp.load.dig(*keys) } end |
.getsetnx(path, key, val) ⇒ Object
Set key to hold val if key does not exist and returns the holded value
This is a kind of atomic short hand of
StorageFile.setnx($setting.status_file, 'foo', 'bar')
StorageFile.get($setting.status_file, 'foo')
155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/triglav/agent/storage_file.rb', line 155 def self.getsetnx(path, key, val) keys = Array(key) open(path) do |fp| params = fp.load if curr = params.dig(*keys) return curr end HashUtil.setdig(params, keys, val) fp.dump(params) return val end end |
.load(path) ⇒ Hash
Load storage file
StorageFile.load($setting.status_file)
44 45 46 |
# File 'lib/triglav/agent/storage_file.rb', line 44 def self.load(path) open(path) {|fp| fp.load } end |
.merge!(path, key, val) ⇒ Object
Merge Hash value with existing Hash value.
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/triglav/agent/storage_file.rb', line 112 def self.merge!(path, key, val) keys = Array(key) open(path) do |fp| params = fp.load _val = params.dig(*keys) || {} _val.merge!(val) HashUtil.setdig(params, keys, _val) fp.dump(params) return true end end |
.open(path, &block) ⇒ Object
Open storage file
StorageFile.open($setting.status_file) do |fp|
status = fp.load
status['foo'] = 'bar'
fp.dump(status)
end
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/triglav/agent/storage_file.rb', line 58 def self.open(path, &block) # Use RDONLY instead of WRONLY not to TRUNCate contents fp = File.open(path, (File::RDONLY | File::CREAT)) fp.flock(File::LOCK_EX) begin return yield(StorageFile.new(fp)) ensure fp.flock(File::LOCK_UN) fp.close rescue nil end end |
.readopen(path, &block) ⇒ Object
Open storage file to read
StorageFile.readopen($setting.status_file) do |fp|
status = fp.load
end
78 79 80 81 82 83 84 85 86 87 |
# File 'lib/triglav/agent/storage_file.rb', line 78 def self.readopen(path, &block) fp = File.open(path, (File::RDONLY | File::CREAT)) fp.flock(File::LOCK_SH) begin return yield(StorageFile.new(fp)) ensure fp.flock(File::LOCK_UN) fp.close rescue nil end end |
.select!(path, parents = [], keys) ⇒ Object
Keep specified keys, and remove others
185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/triglav/agent/storage_file.rb', line 185 def self.select!(path, parents = [], keys) open(path) do |fp| params = fp.load if dig = (parents.empty? ? params : params.dig(*parents)) removes = dig.keys - keys unless removes.empty? $logger.info { "Remove from status: #{{parent_keys: parents, keys: removes}}" } removes.each {|k| dig.delete(k) } end end fp.dump(params) end end |
.set(path, key, val) ⇒ Object
Set storage file with given key, value
StorageFile.set($setting.status_file, 'foo', 'bar') # like h['foo'] = 'bar'
StorageFile.set($setting.status_file, ['a','b'], 'bar') # like h['a']['b'] = 'bar'
97 98 99 100 101 102 103 104 |
# File 'lib/triglav/agent/storage_file.rb', line 97 def self.set(path, key, val) keys = Array(key) open(path) do |fp| params = fp.load HashUtil.setdig(params, keys, val) fp.dump(params) end end |
.setnx(path, key, val) ⇒ Boolean
Set key to hold val if key does not exist
StorageFile.setnx($setting.status_file, 'foo', 'bar') # like h['foo'] = 'bar'
StorageFile.setnx($setting.status_file, ['a','b'], 'bar') # like h['a']['b'] = 'bar'
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/triglav/agent/storage_file.rb', line 133 def self.setnx(path, key, val) keys = Array(key) open(path) do |fp| params = fp.load return false if params.dig(*keys) HashUtil.setdig(params, keys, val) fp.dump(params) return true end end |
Instance Method Details
#dump(hash) ⇒ Object
Dump to storage file
34 35 36 |
# File 'lib/triglav/agent/storage_file.rb', line 34 def dump(hash) File.write(@fp.path, YAML.dump(hash)) end |
#load ⇒ Hash
Load storage file
23 24 25 26 27 28 29 |
# File 'lib/triglav/agent/storage_file.rb', line 23 def load if !(content = @fp.read).empty? YAML.load(content) # all keys must be symbols else {} end end |