-
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.
Prune, by default, caches that are older than 2 days after accumulating 50 megabytes of cache.
- Loading branch information
Showing
9 changed files
with
231 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
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 = +(await stat(join(dir, 'stamp'))).mtime; | ||
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; | ||
} | ||
} | ||
|
||
class PruneCachesSystem { | ||
constructor(cacheRoot, options = {}) { | ||
this.cacheRoot = cacheRoot; | ||
|
||
this.options = Object.assign( | ||
{ | ||
// Caches created or modified before `deleteAfter` are not considered for | ||
// deletion. They must be at least this (default: 2 days) old. | ||
deleteAfter: 2 * 24 * 60 * 60 * 1000, | ||
// All caches together must be larger than `allCacheLimit` before any | ||
// caches will be deleted. Together they must be at least this (default: | ||
// 50 MB) in size. | ||
allCacheLimit: 50 * 1024 * 1024, | ||
}, | ||
options, | ||
); | ||
} | ||
|
||
apply(compiler) { | ||
const compilerHooks = pluginCompat.hooks(compiler); | ||
|
||
const deleteOldCaches = async () => { | ||
let infos; | ||
try { | ||
infos = await CacheInfo.fromDirectoryChildren(this.cacheRoot); | ||
} catch (error) { | ||
if (error.code === 'ENOENT') { | ||
return; | ||
} | ||
throw error; | ||
} | ||
|
||
// 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.deleteAfter, | ||
); | ||
const oldTotalSize = oldInfos.reduce( | ||
(carry, info) => carry + info.size, | ||
0, | ||
); | ||
|
||
if (oldInfos.length > 0 && totalSize > this.options.allCacheLimit) { | ||
const newInfos = infos.filter( | ||
info => info.lastModified >= Date.now() - this.options.deleteAfter, | ||
); | ||
|
||
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, | ||
}); | ||
} | ||
}; | ||
|
||
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 + '/../../..', | ||
}, | ||
prune: { | ||
deleteAfter: -2000, | ||
allCacheLimit: 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