Class: Triglav::Agent::StorageFile

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fpObject (readonly)

Returns the value of attribute fp



13
14
15
# File 'lib/triglav/agent/storage_file.rb', line 13

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']

Parameters:

  • path (String)
  • key (Object)


121
122
123
124
# File 'lib/triglav/agent/storage_file.rb', line 121

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')

Parameters:

  • path (String)
  • key (Object)
  • val (Object)

Returns:

  • (Object)

    holded value



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/triglav/agent/storage_file.rb', line 101

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)

Parameters:

  • path (String)

Returns:

  • (Hash)


25
26
27
# File 'lib/triglav/agent/storage_file.rb', line 25

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

Parameters:

  • path (String)
  • block (Block)


39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/triglav/agent/storage_file.rb', line 39

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

.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'

Parameters:

  • path (String)
  • key (Object)
  • val (Object)


61
62
63
64
65
66
67
68
# File 'lib/triglav/agent/storage_file.rb', line 61

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'

Parameters:

  • path (String)
  • key (Object)
  • val (Object)

Returns:

  • (Boolean)

    true if set (not exist), false if not set (exists)



79
80
81
82
83
84
85
86
87
88
# File 'lib/triglav/agent/storage_file.rb', line 79

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

Parameters:

  • hash (Hash)


140
141
142
# File 'lib/triglav/agent/storage_file.rb', line 140

def dump(hash)
  File.write(@fp.path, YAML.dump(hash))
end

#loadHash

Load storage file

Returns:

  • (Hash)


129
130
131
132
133
134
135
# File 'lib/triglav/agent/storage_file.rb', line 129

def load
  if !(content = @fp.read).empty?
    YAML.load(content) # all keys must be symbols
  else
    {}
  end
end