2014-11-05 53 views
2

我们有一个需要运行资产的用例:在部署/重新启动过程之外进行预编译,因此最好不必重新启动Rails服务器进程。在乘客环境中这可能吗?如何刷新Rails/Sprockets以在资产之后注意生产服务器上的新清单:预编译

我一直在敲打我的脑袋试图Rake任务内的一堆东西,并与Rails.application.config.assets摆弄的东西,但没有使应用程序皮卡更改摘要除非/usr/bin/env touch ~/project/current/tmp/restart.txt

+0

如果你使用的乘客,可你只是'touch/tmp/restart.txt'? – jeremywoertink 2014-11-05 23:52:46

+0

我应该澄清这是我试图避免的情况,当我说“重新启动服务器”。为了清晰起见,我将编辑帖子。我宁愿能够将新的资产摘要填充到每个正在运行的实例中,但我想不出一种可靠的方法来实现这一点。 – streetlogics 2014-11-06 15:18:08

+0

嗯...只是弹跳的想法,但我不知道你是否可以更新manifest.yml文件,然后告诉链轮刷新它。这个清单将告诉像'stylesheet_link_tag'这样的'main'所在的位置。 – jeremywoertink 2014-11-06 18:31:42

回答

1
重启客运

我们结束了与2部分解决方案:

第1部分是设置应用程序命中redis存储'资产:版本'(我们只是与时间戳)。然后,只要我们的流程完成了预编译,我们就会用最新的时间戳更新这个资产版本。

第2部分是我们在我们的主要application_controller中添加了一个before_filter :check_assets_version,这是我们所有其他控制器继承自的。这种方法看起来是这样的:

def check_assets_version 
    @@version ||= 1 
    latest_version = get_assets_version # wrapped call to redis to get latest version 
    # clear assets cache if current version isn't the same as the latest version from redis 
    unless latest_version.blank? || latest_version.to_s == @@version 
     @@version = latest_version 
     if Rails.env.production? || Rails.env.sandbox? || Rails.env.experimental? 
     nondev_reset_sprockets 
     else 
     dev_reset_sprockets @@version 
     end 
    end 
    end 

那两个复位方法是这样的:

def nondev_reset_sprockets 
    manifest = YAML.load(File.read(Rails.root.join("public","assets","manifest.yml"))) 
    manifest.each do |key, value| 
     Rails.application.config.assets.digests[key] = value 
    end 
    end 

的nondev重置从所生成的新清单文件“东西”每个值到内存

def dev_reset_sprockets(version) 
    environment = Rails.application.assets 
    environment = environment.instance_variable_get('@environment') if environment.is_a?(Sprockets::Index) 
    environment.version = version 
    end 

开发人员重置只是启动链轮“版本”值,以便它认为(正确如此)它需要重新分析和生活重新编译最新的资产。

0

生产更新资产的另一种方式如下:

Rails.application.assets_manifest.instance_eval do 
    new_manifest = Sprockets::Manifest.new(manifest.dir, manifest.filename) 
    @data = new_manifest.instance_variable_get(:@data) 
end 
+0

有趣的做法,但我质疑它的线程安全 – 2017-02-23 06:41:47

0

对于轨道4(链轮2.11),你可以这样做:

Rails.application.assets_manifest = Sprockets::Manifest.new(Rails.env, Rails.application.assets_manifest.path) 
    # see sprockets-rails/lib/railtie.rb 
    ActionView::Base.assets_manifest = Rails.application.assets_manifest 
相关问题