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.
-
.open(path, &block) ⇒ Object
Open storage file.
-
.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']
122 123 124 125 |
# File 'lib/triglav/agent/storage_file.rb', line 122 def self.get(path, key) keys = Array(key) open(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')
102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/triglav/agent/storage_file.rb', line 102 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)
26 27 28 |
# File 'lib/triglav/agent/storage_file.rb', line 26 def self.load(path) open(path) {|fp| fp.load } 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
40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/triglav/agent/storage_file.rb', line 40 def self.open(path, &block) fp = File.open(path, (File::RDONLY | File::CREAT)) until fp.flock(File::LOCK_EX | File::LOCK_NB) $logger.info { "Somebody else is locking the storage file #{path.inspect}" } sleep 0.5 end 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
150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/triglav/agent/storage_file.rb', line 150 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'
62 63 64 65 66 67 68 69 |
# File 'lib/triglav/agent/storage_file.rb', line 62 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'
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/triglav/agent/storage_file.rb', line 80 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
141 142 143 |
# File 'lib/triglav/agent/storage_file.rb', line 141 def dump(hash) File.write(@fp.path, YAML.dump(hash)) end |
#load ⇒ Hash
Load storage file
130 131 132 133 134 135 136 |
# File 'lib/triglav/agent/storage_file.rb', line 130 def load if !(content = @fp.read).empty? YAML.load(content) # all keys must be symbols else {} end end |