diff --git a/CHANGELOG.md b/CHANGELOG.md index 6366a4d92..0cdc84c13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ **Master** +- Avoid recreating cache files removed during a read. [Oskar Eichler](https://github.com/OskarEichler) + Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprockets/blob/master/UPGRADING.md # 4.4.1 diff --git a/README.md b/README.md index 958b44cd4..060dd6f78 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,8 @@ Now in your `application.js` will correctly load the `foo.min.js` before `foo-ui ## Cache +A file cache read may finish after another process evicts that entry; updating its access time does not recreate an empty cache file. + Compiling assets is slow. It requires a lot of disk use to pull assets off of hard drives, a lot of RAM to manipulate those files in memory, and a lot of CPU for compilation operations. Because of this Sprockets has a cache to speed up asset compilation times. That's the good news. The bad news, is that sprockets has a cache and if you've found a bug it's likely going to involve the cache. By default Sprockets uses the file system to cache assets. It makes sense that Sprockets does not want to generate assets that already exist on disk in `public/assets`, what might not be as intuitive is that Sprockets needs to cache "partial" assets. diff --git a/lib/sprockets/cache/file_store.rb b/lib/sprockets/cache/file_store.rb index 85d7f7972..3f47c4275 100644 --- a/lib/sprockets/cache/file_store.rb +++ b/lib/sprockets/cache/file_store.rb @@ -69,7 +69,11 @@ def get(key) end if value - FileUtils.touch(path) + begin + File.utime(nil, nil, path) + rescue Errno::ENOENT + # Another cache user may have removed the file after it was read. + end value end end