From 5618aed14b2d4cab1232565d4476b70b0549bd2e Mon Sep 17 00:00:00 2001 From: 1computer1 Date: Mon, 20 May 2019 16:19:41 -0400 Subject: [PATCH] Add parallel build option and build logging --- README.md | 2 ++ config.example.json | 1 + src/struct/LanguageHandler.js | 35 ++++++++++++++++++++++++----------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4dc4b88..15fd464 100644 --- a/README.md +++ b/README.md @@ -121,5 +121,7 @@ The container is locked down, so there is no networking, limited memory and CPU - `timeout` Time limit for code in milliseconds. - `prepare` Whether to start containers on setup. Setting to true will speed up the first eval, but that language might not be used. + - `parallel` Whether to build images and container in parallel. + Faster, but will take more resources. - `concurrent` Number of code evaluations per language than can run at a time. 0. Run `node .` diff --git a/config.example.json b/config.example.json index 925eb55..2f78c3d 100644 --- a/config.example.json +++ b/config.example.json @@ -12,5 +12,6 @@ "cpus": "0.25", "timeout": 10000, "prepare": false, + "parallel": true, "concurrent": 10 } diff --git a/src/struct/LanguageHandler.js b/src/struct/LanguageHandler.js index 5d41899..4b1d38e 100644 --- a/src/struct/LanguageHandler.js +++ b/src/struct/LanguageHandler.js @@ -53,17 +53,29 @@ class LanguageHandler extends AkairoHandler { return this.modules.get(this.aliases.get(alias.toLowerCase())); } - buildDocker() { - return Promise.all(this.modules.map(({ loads }) => { - return Promise.all(loads.map(async dockerID => { - const folder = path.join(__dirname, '../../docker', dockerID); - await util.promisify(childProcess.exec)(`docker build -t "1computer1/comp_iler:${dockerID}" ${folder}`); - this.queues.set(dockerID, new Queue(10)); - if (this.client.config.prepare) { - await this.setupContainer(dockerID); - } - })); - })); + async buildDocker() { + if (this.client.config.parallel) { + await Promise.all(this.modules.map(({ loads }) => Promise.all(loads.map(dockerID => this.buildImage(dockerID))))); + return; + } + + for (const { loads } of this.modules.values()) { + for (const dockerID of loads) { + // eslint-disable-next-line no-await-in-loop + await this.buildImage(dockerID); + } + } + } + + async buildImage(dockerID) { + const folder = path.join(__dirname, '../../docker', dockerID); + await util.promisify(childProcess.exec)(`docker build -t "1computer1/comp_iler:${dockerID}" ${folder}`); + // eslint-disable-next-line no-console + console.log(`Built image 1computer1/comp_iler:${dockerID}.`); + this.queues.set(dockerID, new Queue(10)); + if (this.client.config.prepare) { + await this.setupContainer(dockerID); + } } async setupContainer(dockerID) { @@ -82,6 +94,7 @@ class LanguageHandler extends AkairoHandler { try { await this.handleSpawn(proc); this.containers.set(dockerID, { name, count: 0 }); + console.log(`Started container ${name} for 1computer1/comp_iler:${dockerID}.`); return this.containers.get(dockerID); } catch (err) { throw err;