-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Add `prune` configuration information to README Prune, by default, caches that are older than 2 days after accumulating 50 megabytes of cache.
- Loading branch information
Showing
11 changed files
with
279 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
const { readdir: _readdir, stat: _stat } = require('fs'); | ||
const { basename, join } = require('path'); | ||
|
||
const _rimraf = require('rimraf'); | ||
|
||
const logMessages = require('./util/log-messages'); | ||
const pluginCompat = require('./util/plugin-compat'); | ||
const promisify = require('./util/promisify'); | ||
|
||
const readdir = promisify(_readdir); | ||
const rimraf = promisify(_rimraf); | ||
const stat = promisify(_stat); | ||
|
||
const directorySize = async dir => { | ||
const _stat = await stat(dir); | ||
if (_stat.isFile()) { | ||
return _stat.size; | ||
} | ||
|
||
if (_stat.isDirectory()) { | ||
const names = await readdir(dir); | ||
let size = 0; | ||
for (const name of names) { | ||
size += await directorySize(join(dir, name)); | ||
} | ||
return size; | ||
} | ||
|
||
return 0; | ||
}; | ||
|
||
class CacheInfo { | ||
constructor(id = '') { | ||
this.id = id; | ||
this.lastModified = 0; | ||
this.size = 0; | ||
} | ||
|
||
static async fromDirectory(dir) { | ||
const info = new CacheInfo(basename(dir)); | ||
info.lastModified = new Date( | ||
(await stat(join(dir, 'stamp'))).mtime, | ||
).getTime(); | ||
info.size = await directorySize(dir); | ||
return info; | ||
} | ||
|
||
static async fromDirectoryChildren(dir) { | ||
const children = []; | ||
const names = await readdir(dir); | ||
for (const name of names) { | ||
children.push(await CacheInfo.fromDirectory(join(dir, name))); | ||
} | ||
return children; | ||
} | ||
} | ||
|
||
// Compilers for webpack with multiple parallel configurations might try to | ||
// delete caches at the same time. Mutex lock the process of pruning to keep | ||
// from multiple pruning runs from colliding with each other. | ||
let deleteLock = null; | ||
|
||
class PruneCachesSystem { | ||
constructor(cacheRoot, options = {}) { | ||
this.cacheRoot = cacheRoot; | ||
|
||
this.options = Object.assign( | ||
{ | ||
// Caches younger than `maxAge` are not considered for deletion. They | ||
// must be at least this (default: 2 days) old in milliseconds. | ||
maxAge: 2 * 24 * 60 * 60 * 1000, | ||
// All caches together must be larger than `sizeThreshold` before any | ||
// caches will be deleted. Together they must be at least this | ||
// (default: 50 MB) big in bytes. | ||
sizeThreshold: 50 * 1024 * 1024, | ||
}, | ||
options, | ||
); | ||
} | ||
|
||
apply(compiler) { | ||
const compilerHooks = pluginCompat.hooks(compiler); | ||
|
||
const deleteOldCaches = async () => { | ||
while (deleteLock !== null) { | ||
await deleteLock; | ||
} | ||
|
||
let resolveLock; | ||
|
||
let infos; | ||
try { | ||
deleteLock = new Promise(resolve => { | ||
resolveLock = resolve; | ||
}); | ||
|
||
infos = await CacheInfo.fromDirectoryChildren(this.cacheRoot); | ||
|
||
// Sort lastModified in descending order. More recently modified at the | ||
// beginning of the array. | ||
infos.sort((a, b) => b.lastModified - a.lastModified); | ||
|
||
const totalSize = infos.reduce((carry, info) => carry + info.size, 0); | ||
const oldInfos = infos.filter( | ||
info => info.lastModified < Date.now() - this.options.maxAge, | ||
); | ||
const oldTotalSize = oldInfos.reduce( | ||
(carry, info) => carry + info.size, | ||
0, | ||
); | ||
|
||
if (oldInfos.length > 0 && totalSize > this.options.sizeThreshold) { | ||
const newInfos = infos.filter( | ||
info => info.lastModified >= Date.now() - this.options.maxAge, | ||
); | ||
|
||
for (const info of oldInfos) { | ||
rimraf(join(this.cacheRoot, info.id)); | ||
} | ||
|
||
const newTotalSize = newInfos.reduce( | ||
(carry, info) => carry + info.size, | ||
0, | ||
); | ||
|
||
logMessages.deleteOldCaches(compiler, { | ||
infos, | ||
totalSize, | ||
newInfos, | ||
newTotalSize, | ||
oldInfos, | ||
oldTotalSize, | ||
}); | ||
} else { | ||
logMessages.keepCaches(compiler, { | ||
infos, | ||
totalSize, | ||
}); | ||
} | ||
} catch (error) { | ||
if (error.code !== 'ENOENT') { | ||
throw error; | ||
} | ||
} finally { | ||
if (typeof resolveLock === 'function') { | ||
deleteLock = null; | ||
resolveLock(); | ||
} | ||
} | ||
}; | ||
|
||
compilerHooks.watchRun.tapPromise( | ||
'HardSource - PruneCachesSystem', | ||
deleteOldCaches, | ||
); | ||
compilerHooks.run.tapPromise( | ||
'HardSource - PruneCachesSystem', | ||
deleteOldCaches, | ||
); | ||
} | ||
} | ||
|
||
module.exports = PruneCachesSystem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
b |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = function(n) { | ||
return n + (n > 0 ? n - 2 : 0); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
var fib = require('./fib'); | ||
|
||
console.log(fib(3)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
var fs = require('fs'); | ||
|
||
var HardSourceWebpackPlugin = require('../../..'); | ||
|
||
module.exports = { | ||
context: __dirname, | ||
entry: './index.js', | ||
output: { | ||
path: __dirname + '/tmp', | ||
filename: 'main.js', | ||
}, | ||
plugins: [ | ||
new HardSourceWebpackPlugin({ | ||
cacheDirectory: 'cache/[confighash]', | ||
configHash: function(config) { | ||
return fs.readFileSync(__dirname + '/config-hash', 'utf8'); | ||
}, | ||
environmentHash: { | ||
root: __dirname + '/../../..', | ||
}, | ||
cachePrune: { | ||
maxAge: -2000, | ||
sizeThreshold: 0, | ||
}, | ||
}), | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters