File size: 4,777 Bytes
b4143a2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | "use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.measureFolderAsync = measureFolderAsync;
exports.findLargeFilesAsync = findLargeFilesAsync;
exports.terminateMeasureWorkers = terminateMeasureWorkers;
/**
* Offloads filesystem walks to worker threads so the Electron main process stays responsive.
* Pool of 2 workers balances throughput vs disk contention.
*/
const node_worker_threads_1 = require("node:worker_threads");
const path = __importStar(require("node:path"));
const POOL_SIZE = 2;
let pool = null;
let seq = 0;
const pendingMeasure = new Map();
const pendingLarge = new Map();
function workerScriptPath() {
return path.join(__dirname, 'fsWorker.js');
}
function rejectAllPending(err) {
for (const [, p] of pendingMeasure)
p.reject(err);
for (const [, p] of pendingLarge)
p.reject(err);
pendingMeasure.clear();
pendingLarge.clear();
}
function ensurePool() {
if (pool)
return pool;
pool = [];
for (let i = 0; i < POOL_SIZE; i++) {
const w = new node_worker_threads_1.Worker(workerScriptPath());
w.on('message', (msg) => {
if (pendingMeasure.has(msg.id)) {
const p = pendingMeasure.get(msg.id);
pendingMeasure.delete(msg.id);
if (!msg.ok) {
p.reject(new Error(msg.error ?? 'measure failed'));
return;
}
if (msg.bytes !== undefined && msg.files !== undefined && msg.truncated !== undefined) {
p.resolve({ bytes: msg.bytes, files: msg.files, truncated: msg.truncated });
}
else {
p.reject(new Error('invalid measure response'));
}
return;
}
if (pendingLarge.has(msg.id)) {
const p = pendingLarge.get(msg.id);
pendingLarge.delete(msg.id);
if (!msg.ok) {
p.reject(new Error(msg.error ?? 'large file scan failed'));
return;
}
if (msg.largeResults !== undefined) {
p.resolve(msg.largeResults);
}
else {
p.reject(new Error('invalid large-file response'));
}
}
});
w.on('error', (err) => {
rejectAllPending(err);
});
pool.push(w);
}
return pool;
}
function measureFolderAsync(absPath) {
const workers = ensurePool();
const id = ++seq;
return new Promise((resolve, reject) => {
pendingMeasure.set(id, { resolve, reject });
const w = workers[id % POOL_SIZE];
w.postMessage({ id, kind: 'measure', root: absPath });
});
}
function findLargeFilesAsync(root, minBytes, maxResults) {
const workers = ensurePool();
const id = ++seq;
return new Promise((resolve, reject) => {
pendingLarge.set(id, { resolve, reject });
const w = workers[id % POOL_SIZE];
w.postMessage({ id, kind: 'large', root, minBytes, maxResults });
});
}
function terminateMeasureWorkers() {
if (!pool)
return;
for (const w of pool) {
try {
w.terminate();
}
catch {
/* ignore */
}
}
pool = null;
pendingMeasure.clear();
pendingLarge.clear();
}
|