-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow Filter To Persist For Warm Boot #28
base: master
Are you sure you want to change the base?
Changes from 2 commits
95f7086
d98f019
ea86689
2ab3356
6fec4a4
41b6751
4df5053
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,9 @@ var copyDereferenceSync = require('copy-dereference').sync; | |
var Cache = require('./lib/cache'); | ||
var debugGenerator = require('debug'); | ||
var keyForFile = require('./lib/key-for-file'); | ||
var PersistentCache = require('async-disk-cache'); | ||
var hashForDep = require('hash-for-dep'); | ||
var md5Hex = require('md5-hex'); | ||
|
||
module.exports = Filter; | ||
|
||
|
@@ -43,6 +46,16 @@ function Filter(inputTree, options) { | |
this.inputEncoding = options.inputEncoding; | ||
if (options.outputEncoding != null) | ||
this.outputEncoding = options.outputEncoding; | ||
if (options.persist) { | ||
if (/^win/.test(process.platform)) { | ||
console.log('Unfortunately persistent cache is currently not available on windows based systems.'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should link to a tracking issue from this warning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} else { | ||
this.persistent = options.persist; | ||
this._peristentCache = new PersistentCache(this.cacheKey(), { | ||
compression: 'deflate' | ||
}); | ||
} | ||
} | ||
} | ||
|
||
this._cache = new Cache(); | ||
|
@@ -75,6 +88,36 @@ Filter.prototype.build = function build() { | |
}); | ||
}; | ||
|
||
/* | ||
* @private | ||
* | ||
* | ||
* @method cachKey | ||
* @return {String} this filters top-level cache key | ||
*/ | ||
Filter.prototype.cacheKey = function() { | ||
return hashForDep(this.baseDir()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As this is fairly costly, and we easily have N independent broccoli transforms. I believe this only needs to run once per subclass, not once per instance. As such I believe caching the result on the constructor should be sufficient. |
||
}; | ||
|
||
/* @public | ||
* | ||
* @method baseDir | ||
* @returns {String} absolute path to the root of the filter... | ||
*/ | ||
Filter.prototype.baseDir = function() { | ||
throw Error('Filter must implement prototype.baseDir'); | ||
}; | ||
|
||
/* | ||
* @public | ||
* | ||
* @method cacheKeyProcessString | ||
* @return {String} this filters top-level cache key | ||
*/ | ||
Filter.prototype.cacheKeyProcessString = function(string) { | ||
return md5Hex(string); | ||
}; | ||
|
||
Filter.prototype.canProcessFile = | ||
function canProcessFile(relativePath) { | ||
return !!this.getDestFilePath(relativePath); | ||
|
@@ -160,19 +203,32 @@ Filter.prototype.processFile = | |
if (outputEncoding === void 0) outputEncoding = 'utf8'; | ||
var contents = fs.readFileSync( | ||
srcDir + '/' + relativePath, { encoding: inputEncoding }); | ||
var promise; | ||
|
||
return Promise.resolve(this.processString(contents, relativePath)). | ||
then(function asyncOutputFilteredFile(outputString) { | ||
var outputPath = self.getDestFilePath(relativePath); | ||
if (outputPath == null) { | ||
throw new Error('canProcessFile("' + relativePath + '") is true, but getDestFilePath("' + relativePath + '") is null'); | ||
} | ||
outputPath = destDir + '/' + outputPath; | ||
mkdirp.sync(path.dirname(outputPath)); | ||
fs.writeFileSync(outputPath, outputString, { | ||
encoding: outputEncoding | ||
}); | ||
}); | ||
if (this.persistent) { | ||
var key = this.cacheKeyProcessString(contents, relativePath); | ||
promise = this._peristentCache.get(key).then(function(entry) { | ||
return entry.isCached ? entry.value : self.processString(contents, relativePath); | ||
}); | ||
} else { | ||
promise = Promise.resolve(this.processString(contents, relativePath)); | ||
} | ||
|
||
return promise.then(function asyncOutputFilteredFile(outputString) { | ||
var outputPath = self.getDestFilePath(relativePath); | ||
if (outputPath == null) { | ||
throw new Error('canProcessFile("' + relativePath + '") is true, but getDestFilePath("' + relativePath + '") is null'); | ||
} | ||
outputPath = destDir + '/' + outputPath; | ||
mkdirp.sync(path.dirname(outputPath)); | ||
fs.writeFileSync(outputPath, outputString, { | ||
encoding: outputEncoding | ||
}); | ||
|
||
if (self.persistent) { | ||
return self._peristentCache.set(key, outputString); | ||
} | ||
}); | ||
}; | ||
|
||
Filter.prototype.processString = | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.