Skip to content

Instantly share code, notes, and snippets.

@jchip
Created December 22, 2017 07:49
Show Gist options
  • Save jchip/4a6a81a7afa5657424860d1bc1b54470 to your computer and use it in GitHub Desktop.
Save jchip/4a6a81a7afa5657424860d1bc1b54470 to your computer and use it in GitHub Desktop.
"use strict";
const Tar = require("tar");
const Path = require("path");
const Fs = require("fs");
const Promise = require("bluebird");
const logger = require("./logger");
const defer = require("./util/defer");
const { fork } = require("child_process");
class Tartar {
constructor() {
this._max = 3;
this._workers = {};
this._count = 0;
this._busy = 0;
this._workQ = [];
process.once("exit", () => {
this.shutdown();
});
}
shutdown() {
if (this._count === 0) return;
for (let id in this._workers) {
const worker = this._workers[id];
worker.child.send({ action: "kill" });
}
}
addWorker() {
if (this._count < this._max) {
this._count++;
const id = `${this._count}`;
const child = fork(Path.join(__dirname, "tarter.js"), [id], { silent: true });
this._workers[id] = { child, busy: false };
}
}
extract(data) {
const d = defer();
this._workQ.push({ defer: d, data });
process.nextTick(() => this.process());
return d.promise;
}
process() {
if (this._workQ.length < 1) return;
if (this._count === this._busy) return;
this._busy++;
const workload = this._workQ.shift();
for (let id in this._workers) {
const worker = this._workers[id];
if (!worker.busy) {
const handler = resp => {
if (resp.action !== "extract") {
return worker.child.once("message", handler);
}
worker.busy = false;
this._busy--;
if (resp.err) {
workload.defer.reject(new Error(resp.err.message));
} else {
workload.defer.resolve(workload.data);
}
process.nextTick(() => this.process());
};
worker.busy = true;
worker.child.once("message", handler);
worker.child.send(workload.data);
break;
}
}
}
}
module.exports = Tartar;
// const tt = new Tartar();
// tt.addWorker();
// tt
// .extract({
// action: "extract",
// file: Path.resolve("blah.tgz"),
// strip: 0,
// strict: true,
// outDir: Path.resolve("o")
// })
// .then(x => {
// console.log("done", x);
// process.exit();
// });
"use strict";
const Tar = require("tar");
const id = process.argv[2];
process.on("message", data => {
if (data.action === "extract") {
Tar.x({
file: data.file,
strip: data.strip,
strict: data.strict,
C: data.outDir
})
.catch(err => {
data.err = {
message: err.message
};
})
.then(() => {
data.$ = id;
process.send(data);
});
} else if (data.action === "kill") {
process.send({ id, action: "bye" });
process.nextTick(() => process.exit());
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment