我们总是习惯将应用程序配置放入环境文件中。这对生产管理没有好处,所以现在我们通过初始化程序加载它:
# myinitializer.rb
ApplicationConfig = YAML.load_file("#{Rails.root}/config/application/default.yml").symbolize_keys()
一旦我们开始通过ApplicationConfig
访问配置,应用程序测试性能就会变得更糟。一个rspec套件从4秒下降到30。
在我们的应用程序控制器中,我们需要使用before_filter
执行某些操作,其工作方式如下:
before_filter :extra_control
def extra_control
if ApplicationConfig.some_flag
...
end
end
声明指向ApplicationConfig
的变量可以完全恢复性能:
config = ApplicationConfig
def extra_control
if config.some_flag
...
end
end
为什么呢?为什么通过全局变量访问它会破坏性能?我们在视图和其他控制器的整个代码库中执行此操作。我们需要以不同的方式做到这一点,例如通过将实例变量注入所有控制器?
编辑我们确实验证了从YAML加载配置的代码在任何一种情况下都会被调用一次,因此重复加载似乎不是根本原因。
编辑:事实证明这是一个由设置变量引起的错误,该变量被加载为字符串而不是布尔值,导致应用程序进入测试睡眠模式:(抱歉,谢谢你的尝试。我生命中的3天我永远不会回来!
答案 0 :(得分:0)
我无法说明为什么你的方法很慢,但是处理设置的不同方式可能值得研究。我更喜欢使用包含配置信息的单例类:
class SiteSettings
def initialize
@settings = {}
end
@@instance = SiteSettings.new
def set_setting(key, value)
@settings ||= {}
@settings[key] = value
end
def self.setting(key, value)
@@instance.set_setting(key, value)
end
def settings
@settings
end
def self.method_missing(meth, *args, &block)
if @@instance.settings.has_key?(meth)
@@instance.settings[meth]
else
super
end
end
setting :test_setting, 'test'
setting :another_test_setting '.....'
end
puts SiteSettings.test_setting
puts SiteSettings.another_test_setting
Discourse app采用了类似的方法。
答案 1 :(得分:0)
尝试使用const:
APPLICATIONCONFIG = YAML.load(File.read(File.expand_path("#{RAILS_ROOT}/config/application/default.yml", __FILE__)))
或
APPLICATIONCONFIG = YAML::load(File.open("#{RAILS_ROOT}/config/application/default.yml"))
我认为它会使你的文件变慢因为加载文件而不是打开/读取。
答案 2 :(得分:0)
我认为这将有助于弄清楚YAML文件load \ read是否很慢,或者YAML解析是否很慢。我的猜测是,每次调用ApplicationConfig
变量时,ruby都会解析YAML文件。您可以尝试将其重命名为APPLICATION_CONFIG
,如下所示:
APPLICATION_CONFIG = YAML.load(File.read(Rails.root.join('config', 'application', 'my_config.yml')))
请不要在所有控制器中注入实例变量:)
答案 3 :(得分:0)
这里的其他答案没有什么区别 - 这是由一个无关的问题引起的。记录