Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 92 additions & 33 deletions platforms/minigame/common/engine/cache-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ const {
let checkNextPeriod = false;
let writeCacheFileList = null;
let startWrite = false;
let nextCallbacks = [];
let callbacks = [];
const nextCallbacks = [];
const callbacks = [];
let cleaning = false;
let suffix = 0;
const REGEX = /^https?:\/\/.*/;
const LOG_PREFIX = '[CacheManager]';

const cacheManager = {

Expand All @@ -54,6 +55,9 @@ const cacheManager = {

deleteInterval: 500,

// delete multiple files per cycle when clearing LRU caches
deleteBatchCount: 30,

writeFileInterval: 2000,

// whether or not storage space has run out
Expand All @@ -78,6 +82,10 @@ const cacheManager = {
init () {
this.cacheDir = `${getUserDataPath()}/${this.cacheDir}`;
const cacheFilePath = `${this.cacheDir}/${this.cachedFileName}`;
console.warn(`${LOG_PREFIX} init storage`, {
cacheDir: this.cacheDir,
cacheFilePath,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we change warn to debug?

const result = readJsonSync(cacheFilePath);
if (result instanceof Error || !result.version) {
if (!(result instanceof Error)) rmdirSync(this.cacheDir, true);
Expand All @@ -100,7 +108,7 @@ const cacheManager = {
_write () {
writeCacheFileList = null;
startWrite = true;
writeFile(this.cacheDir + '/' + this.cachedFileName, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8', function () {
writeFile(`${this.cacheDir}/${this.cachedFileName}`, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8', () => {
startWrite = false;
for (let i = 0, j = callbacks.length; i < j; i++) {
callbacks[i]();
Expand All @@ -116,8 +124,7 @@ const cacheManager = {
writeCacheFileList = setTimeout(this._write.bind(this), this.writeFileInterval);
if (startWrite === true) {
cb && nextCallbacks.push(cb);
}
else {
} else {
cb && callbacks.push(cb);
}
} else {
Expand All @@ -135,11 +142,10 @@ const cacheManager = {

if (cacheBundleRoot) {
localPath = `${this.cacheDir}/${cacheBundleRoot}/${time}${suffix++}${cc.path.extname(id)}`;
}
else {
} else {
localPath = `${this.cacheDir}/${time}${suffix++}${cc.path.extname(id)}`;
}

function callback (err) {
checkNextPeriod = false;
if (err) {
Expand All @@ -160,8 +166,7 @@ const cacheManager = {
}
if (!isCopy) {
downloadFile(srcUrl, localPath, null, callback);
}
else {
} else {
copyFile(srcUrl, localPath, callback);
}
return;
Expand All @@ -178,8 +183,7 @@ const cacheManager = {
checkNextPeriod = true;
if (!this.outOfStorage) {
setTimeout(this._cache.bind(this), this.cacheInterval);
}
else {
} else {
checkNextPeriod = false;
}
}
Expand All @@ -189,12 +193,12 @@ const cacheManager = {
rmdirSync(this.cacheDir, true);
this.cachedFiles = new cc.AssetManager.Cache();
makeDirSync(this.cacheDir, true);
const cacheFilePath = this.cacheDir + '/' + this.cachedFileName;
const cacheFilePath = `${this.cacheDir}/${this.cachedFileName}`;
this.outOfStorage = false;
clearTimeout(writeCacheFileList);
writeCacheFileList = null;
writeFileSync(cacheFilePath, JSON.stringify({ files: this.cachedFiles._map, version: this.version }), 'utf8');
cc.assetManager.bundles.forEach(bundle => {
cc.assetManager.bundles.forEach((bundle) => {
if (REGEX.test(bundle.base)) this.makeBundleFolder(bundle.name);
});
},
Expand All @@ -220,46 +224,101 @@ const cacheManager = {
cc.assetManager.files.remove(cacheKey);
this.cachedFiles.remove(caches[i].originUrl);
}

clearTimeout(writeCacheFileList);
writeCacheFileList = null;
this.writeCacheFile(function () {
function deferredDelete () {
const item = caches.pop();
self._removePathOrFile(item.originUrl, item.url);
if (caches.length > 0) {
setTimeout(deferredDelete, self.deleteInterval);
}
else {
cleaning = false;
}
}
setTimeout(deferredDelete, self.deleteInterval);
this.writeCacheFile(() => {
self._deleteLRUCaches(caches);
});
},

_deleteLRUCaches (caches) {
const self = this;
const deleteBatchCount = Math.max(1, this.deleteBatchCount || 1);
let index = 0;
let pending = 0;
let removed = false;
const startTime = Date.now();
console.warn(`${LOG_PREFIX} delete LRU caches start`, {
count: caches.length,
startTime,
});

function finish () {
const endTime = Date.now();
console.warn(`${LOG_PREFIX} delete LRU caches finished`, {
count: caches.length,
removed,
startTime,
endTime,
durationMs: endTime - startTime,
});
if (removed) self.outOfStorage = false;
cleaning = false;
}

function onDeleted (err) {
if (!err) removed = true;
pending--;
if (index >= caches.length && pending === 0) {
finish();
}
}

function deleteBatch () {
const end = Math.min(index + deleteBatchCount, caches.length);
for (; index < end; index++) {
pending++;
self._removePathOrFile(caches[index].originUrl, caches[index].url, onDeleted);
}
const endTime = Date.now();
console.warn(`${LOG_PREFIX} delete batch:`, {
count: end,
removed,
startTime,
endTime,
durationMs: endTime - startTime,
});
if (index < caches.length) {
setTimeout(deleteBatch, self.deleteInterval);
} else if (pending === 0) {
finish();
}
}

deleteBatch();
},

removeCache (url) {
if (this.cachedFiles.has(url)) {
const self = this;
const path = this.cachedFiles.remove(url).url;
clearTimeout(writeCacheFileList);
writeCacheFileList = null;
this.writeCacheFile(function () {
this.writeCacheFile(() => {
self._removePathOrFile(url, path);
});
}
},

_removePathOrFile (url, path) {
_removePathOrFile (url, path, onComplete) {
const cb = (err) => {
this._deleteFileCB(err);
onComplete && onComplete(err);
};
if (this._isZipFile(url)) {
if (this._isZipFile(path)) {
deleteFile(path, this._deleteFileCB.bind(this));
deleteFile(path, cb);
} else {
rmdirSync(path, true);
this._deleteFileCB();
try {
rmdirSync(path, true);
cb();
} catch (err) {
cb(err);
}
}
} else {
deleteFile(path, this._deleteFileCB.bind(this));
deleteFile(path, cb);
}
},

Expand Down
Loading