You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a new version of an "engine" registered with Sprockets generates different content from the same source file compared to a previous version, the cached asset remains stale and is not regenerated correctly by Sprockets.
I came across this issue when updating an existing Rails project containing sass-rails, and updating sass from 3.2.19 to 3.4.22, which generated slightly different CSS output from the same source file. On the next run of rake assets:precompile, a new asset was not generated and the existing (stale) cached asset continued to be used.
This caused issues in a load-balanced multi-server environment containing a mix of old and new servers, since the old servers continued to reference asset-[old-hash].ext in their manifest while the new ones contained asset-[new-hash].ext. When a page was requested from a new server and the referenced asset-[new-hash].ext asset was requested from an old server which not containing the new asset, a 404 error was returned.
Here is a minimal Bash script demonstrating the issue (or you can manually step through the commands listed):
#!/bin/bash
# Run in a temp dir and clean up after
TEST_DIR=$(mktemp -d)
pushd ${TEST_DIR} > /dev/null
trap "rm -rf ${TEST_DIR}; popd > /dev/null" EXIT
# Generate new Rails project
rails new ${TEST_DIR} -q
# Use old version of Sass
OLD_SASS=3.2.19
cat <<GEMFILE >> Gemfile
gem 'sass', '${OLD_SASS}'
GEMFILE
bundle update --quiet sass
# Write a .scss file
rm app/assets/stylesheets/application.css
cat <<'SCSS' > app/assets/stylesheets/application.scss
/*= require_self */
$red: #c00;
.selector {
color: $red;
}
SCSS
# Compile asset
bundle exec rake assets:precompile >/dev/null 2>&1
# Update sass version
NEW_SASS=3.4.22
sed -i -e "s/${OLD_SASS}/${NEW_SASS}/g" Gemfile
bundle update --quiet sass
# WORKAROUND: Clear Sprockets cache
# bundle exec rake tmp:cache:clear >/dev/null 2>&1
# Remove old asset
bundle exec rake assets:clobber >/dev/null 2>&1
# Compile asset again
bundle exec rake assets:precompile >/dev/null 2>&1
# Test output of compiled asset
cat public/assets/application*.css | grep color
Expected output (compiled with the new version of sass):
color: #c00;
Actual output (cached output of the old version of sass):
color: #cc0000;
A workaround (see commented line in the test script above) is to manually clear out the Sprockets cache by running rake tmp:cache:clear whenever Sprockets-engine dependencies are updated in a way that potentially changes the compiled asset output for given input contents. (Changing config.assets.version did not have any effect.) However, this workaround is extremely prone to human error and would require extremely clear documentation to rely upon.
I think it would more robust if an engine version was included in the code Sprockets uses to generate its cache key, so that cached assets would automatically expire whenever a dependent engine version is updated.
The text was updated successfully, but these errors were encountered:
that is exactly how it works. Then engine should bump the cache key based in they version. If an engine is not doing this it is an engine bug. Could you report this issue to the engine?
When a new version of an "engine" registered with Sprockets generates different content from the same source file compared to a previous version, the cached asset remains stale and is not regenerated correctly by Sprockets.
I came across this issue when updating an existing Rails project containing
sass-rails
, and updatingsass
from3.2.19
to3.4.22
, which generated slightly different CSS output from the same source file. On the next run ofrake assets:precompile
, a new asset was not generated and the existing (stale) cached asset continued to be used.This caused issues in a load-balanced multi-server environment containing a mix of old and new servers, since the old servers continued to reference
asset-[old-hash].ext
in their manifest while the new ones containedasset-[new-hash].ext
. When a page was requested from a new server and the referencedasset-[new-hash].ext
asset was requested from an old server which not containing the new asset, a 404 error was returned.Here is a minimal Bash script demonstrating the issue (or you can manually step through the commands listed):
Expected output (compiled with the new version of
sass
):Actual output (cached output of the old version of
sass
):A workaround (see commented line in the test script above) is to manually clear out the Sprockets cache by running
rake tmp:cache:clear
whenever Sprockets-engine dependencies are updated in a way that potentially changes the compiled asset output for given input contents. (Changingconfig.assets.version
did not have any effect.) However, this workaround is extremely prone to human error and would require extremely clear documentation to rely upon.I think it would more robust if an engine version was included in the code Sprockets uses to generate its cache key, so that cached assets would automatically expire whenever a dependent engine version is updated.
The text was updated successfully, but these errors were encountered: