sstephenson/sprockets — pull request #441 by kenmazaika (2013-05-13 19:01:50+00:00)
Title: For Konacha: skip if we're already in the process of marshaling the file to the cache

Otherwise it can cause issues when done in concurrent threads in race conditions.

Without this when running javascript tests with konacha, on the first running of them I sporadically get the following error when running the tests for the first time with an empty cache:

```
ActionView::Template::Error: end of file reached
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0.rc1/lib/active_support/core_ext/marshal.rb:4:in `load'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0.rc1/lib/active_support/core_ext/marshal.rb:4:in `load_with_autoloading'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/cache/file_store.rb:19:in `block in []'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/cache/file_store.rb:19:in `open'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/cache/file_store.rb:19:in `open'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/cache/file_store.rb:19:in `[]'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/caching.rb:14:in `cache_get'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/caching.rb:84:in `cache_get_hash'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/caching.rb:54:in `cache_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/index.rb:93:in `build_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/base.rb:287:in `find_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/index.rb:61:in `find_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/bundled_asset.rb:16:in `initialize'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/base.rb:377:in `new'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/base.rb:377:in `build_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/index.rb:94:in `block in build_asset'
/Users/webdev/campaign_manager/vendor/bundle/ruby/2.0.0/gems/sprockets-2.9.3/lib/sprockets/caching.rb:58:in `cache_asset'
```

There may be a better way to do this; but this is the cleanest way I could fix the problem in my environment. I'm not sure if it would be cleaner to use a mutex rather than a lockfile, but if we used a mutex we'd have to either deal with multiple mutexes (one for each file) and deal with the management of them, or slow the compilation by using a single mutex for the caching of each.

While this solution technically isn't threadsafe (time between checking for the existence of a lockfile and making one could potentially have another one made), this resolves the problem for me consistently. Marshal.dump for large assets that are in my vendor directory continually presents problems here.