ror 应该是把配置读到某个对象里(ruby 几乎啥都是对象),更新配置,在 reload 这个对象应该就可以了。
如果有很多服务,有需要有统一的配置,比如 reids、mysql,就用配置中心。觉得配置中心麻烦,可以放到 reids 里。
关键是内存里的要 refresh,还不如重新部署一次…
# frozen_string_literal: true
# Redis > .env > default
# FeatureToggle.fetch('ROLE_MAPPING') { { "read" => ["list", "read"], "list" => ["list", "read", "write"] } }
# FeatureToggle.fetch('WHITELIST') { ["23","33","43","53"] }
# FeatureToggle.fetch('HACK_ENABLE') { false }
module FeatureToggle
class << self
def fetch(key)
return read(key) if exists?(key)
load ENV.fetch(key.upcase) { block_given? ? yield : nil }
end
def read(key)
data = client.get(key.upcase)
data = ENV.fetch(key.upcase) { block_given? ? yield : nil } if data.nil?
load data
end
def write(key)
return nil unless block_given?
data = yield
body = data.is_a?(String) ? data : Oj.dump(data)
client.set(key.upcase, body)
data
end
def delete(key)
if exists?(key)
data = read(key)
client.del(key.upcase)
data
end
end
def keys
client.keys
end
private
def load(data)
return Oj.load(data) if json?(data)
return data.to_b if bool?(data)
data
end
def exists?(key)
client.exists(key.upcase)
end
def json?(data)
data =~ %r(^(\{|\[)(.*)(\]|\})$)
end
def bool?(data)
data =~ %r((true|false|yes|no|on|off))i
end
def client
@client ||= Redis::Namespace.new(NAMESPACE, redis: Redis.current)
end
# redis key
NAMESPACE = [Rails.application.class.parent_name.underscore, Rails.env, "FeatureToggle"].join(":").freeze
end
end