Class: Gin::Config
- Inherits:
-
Object
- Object
- Gin::Config
- Defined in:
- lib/gin/config.rb
Overview
Environment-specific config files loading mechanism.
# config_dir/memcache.yml
default: &default
host: http://memcache.example.com
connections: 5
development: &dev
host: localhost:123321
connections: 1
test: *dev
staging:
host: http://stage-memcache.example.com
production: *default
# config.rb
config = Gin::Config.new 'staging', :dir => 'config/dir'
config['memcache.host']
#=> "http://stage-memcache.example.com"
config['memcache.connections']
#=> 5
Config files get loaded on demand. They may also be reloaded on demand by setting the :ttl option to expire values. Values are only expired for configs with a source file whose mtime value differs from the one it had at its previous load time.
# 5 minute expiration
config = Gin::Config.new 'staging', :ttl => 300
Constant Summary collapse
- SYNTAX_ERROR =
defined?(Psych) ? Psych::SyntaxError : ArgumentError
Instance Attribute Summary collapse
-
#dir ⇒ Object
Returns the value of attribute dir.
-
#environment ⇒ Object
Returns the value of attribute environment.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#ttl ⇒ Object
Returns the value of attribute ttl.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Non-raising config lookup.
-
#current?(name) ⇒ Boolean
Checks if the given config is outdated.
-
#get(name, safe = false) ⇒ Object
Get a config value from its name.
-
#has?(name) ⇒ Boolean
Checks if a config exists in memory or on disk, by its name.
-
#initialize(environment, opts = {}) ⇒ Config
constructor
Create a new config instance for the given environment name.
-
#load! ⇒ Object
Force-load all the config files in the config directory.
-
#load_config(name) ⇒ Object
Load the given config name, or filename.
-
#set(name, data) ⇒ Object
Sets a new config name and value.
-
#write_timeout(sec = nil) ⇒ Object
Get or set the write timeout when waiting for reader thread locks.
Constructor Details
#initialize(environment, opts = {}) ⇒ Config
Create a new config instance for the given environment name. The environment dictates which part of the config files gets exposed.
50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/gin/config.rb', line 50 def initialize environment, opts={} @environment = environment @logger = opts[:logger] || Logger.new($stdout) @ttl = opts[:ttl] || false @dir = opts[:dir] || "./config" @data = {} @load_times = {} @mtimes = {} @lock = Gin::RWLock.new(opts[:write_timeout]) end |
Instance Attribute Details
#dir ⇒ Object
Returns the value of attribute dir.
42 43 44 |
# File 'lib/gin/config.rb', line 42 def dir @dir end |
#environment ⇒ Object
Returns the value of attribute environment.
42 43 44 |
# File 'lib/gin/config.rb', line 42 def environment @environment end |
#logger ⇒ Object
Returns the value of attribute logger.
42 43 44 |
# File 'lib/gin/config.rb', line 42 def logger @logger end |
#ttl ⇒ Object
Returns the value of attribute ttl.
42 43 44 |
# File 'lib/gin/config.rb', line 42 def ttl @ttl end |
Instance Method Details
#[](key) ⇒ Object
Non-raising config lookup. The following query the same value:
# Raises an error if the 'user' key is missing.
config.get('remote_shell')['user']['name']
# Doesn't raise an error if a key is missing.
# Doesn't support configs with '.' in the key names.
config['remote_shell.user.name']
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/gin/config.rb', line 185 def [] key chain = key.to_s.split(".") name = chain.shift curr = get(name, true) return unless curr chain.each do |k| return unless Array === curr || Hash === curr val = curr[k] val = curr[k.to_i] if val.nil? && k.to_i.to_s == k curr = val end curr end |
#current?(name) ⇒ Boolean
Checks if the given config is outdated.
156 157 158 159 160 161 162 |
# File 'lib/gin/config.rb', line 156 def current? name @lock.read_sync do @ttl == false && @data.has_key?(name) || !@load_times[name] && @data.has_key?(name) || @load_times[name] && Time.now - @load_times[name] <= @ttl end end |
#get(name, safe = false) ⇒ Object
Get a config value from its name. Setting safe to true will return nil instead of raising errors. Reloads the config if reloading is enabled and value expired.
145 146 147 148 149 150 |
# File 'lib/gin/config.rb', line 145 def get name, safe=false return @lock.read_sync{ @data[name] } if current?(name) || safe && !File.file?(filepath_for(name)) load_config(name) || @lock.read_sync{ @data[name] } end |
#has?(name) ⇒ Boolean
Checks if a config exists in memory or on disk, by its name.
# If foo config isn't loaded, looks for file under @dir/foo.yml
config.has? 'foo'
#=> true
171 172 173 |
# File 'lib/gin/config.rb', line 171 def has? name @lock.read_sync{ @data.has_key?(name) } || File.file?(filepath_for(name)) end |
#load! ⇒ Object
Force-load all the config files in the config directory.
77 78 79 80 81 82 83 |
# File 'lib/gin/config.rb', line 77 def load! return unless @dir Dir[File.join(@dir, "*.yml")].each do |filepath| load_config filepath end self end |
#load_config(name) ⇒ Object
Load the given config name, or filename.
# Loads @dir/my_config.yml
config.load_config 'my_config'
config['my_config']
#=> data from file
# Loads the given file if it exists.
config.load_config 'path/to/my_config.yml'
config['my_config']
#=> data from file
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/gin/config.rb', line 98 def load_config name name = name.to_s if File.file?(name) filepath = name name = File.basename(filepath, ".yml") else filepath = filepath_for(name) end raise Gin::MissingConfig, "No config file at #{filepath}" unless File.file?(filepath) @lock.write_sync do @load_times[name] = Time.now mtime = File.mtime(filepath) return if mtime == @mtimes[name] @mtimes[name] = mtime c = YAML.load_file(filepath) c = (c['default'] || {}).merge(c[@environment] || {}) @data[name] = c end rescue SYNTAX_ERROR @logger.write "[ERROR] Could not parse config `#{filepath}' as YAML" return nil end |
#set(name, data) ⇒ Object
Sets a new config name and value. Configs set in this manner do not qualify for reloading as they don’t have a source file.
135 136 137 |
# File 'lib/gin/config.rb', line 135 def set name, data @lock.write_sync{ @data[name] = data } end |
#write_timeout(sec = nil) ⇒ Object
Get or set the write timeout when waiting for reader thread locks. Defaults to 0.05 sec. See Gin::RWLock for more details.
68 69 70 71 |
# File 'lib/gin/config.rb', line 68 def write_timeout sec=nil @lock.write_timeout = sec if sec @lock.write_timeout end |