ruby-on-rails – Rails应用程序配置访问速度慢 – 为什么?

我们总是习惯将应用程序配置放入环境文件中.这对生产管理没有好处,所以现在我们通过初始化程序加载它:
# 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天我永远不会回来!

解决方法

我不能说你为什么你的方法很慢,但可能有一种不同的处理设置方式值得研究.我更喜欢有一个包含配置信息的单例类的想法:
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采用了类似的方法.

> site_setting.rb
> site_setting_extension.rb

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...