2014-11-05 60 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