We have a use case where we need to run assets:precompile outside of the deploy/restart process, and therefore preferably without having to restart the Rails server processes. Is this possible in a Passenger environment?
I've been banging my head trying a bunch of stuff within Rake tasks and fiddling with Rails.application.config.assets stuff, but nothing makes the application pickup the changes to the digests except restarting Passenger with /usr/bin/env touch ~/project/current/tmp/restart.txt
We ended up going with a 2 part solution:
Part 1 is to setup the app to hit redis to store an 'assets:version' (we just went with a timestamp). Then, whenever our process was done precompiling, we update this assets version with the latest timestamp.
Part 2 was that we added a before_filter :check_assets_version
in our main application_controller that all our other controllers inherit from. This method looks something like this:
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
And those two reset methods look like this:
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
The nondev reset "stuffs" each of the values into memory from the new generated manifest file
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
The dev reset just kicks sprockets "version" value so that it thinks (correctly so) it needs to reparse and live recompile the latest assets.