From 862327c2a047d202caeaf67a2a542495ba597f80 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Fri, 23 Dec 2022 14:04:24 +0100 Subject: [PATCH] refs #4550 Db connection pool, error fixes --- print-server.js | 124 ++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 66 deletions(-) diff --git a/print-server.js b/print-server.js index 3689e44..0a7874f 100644 --- a/print-server.js +++ b/print-server.js @@ -27,9 +27,7 @@ class PrintServer { await this.init(); } async init() { - this.conn = await mysql.createConnection(this.conf.db); - this.dbErrorHandler = err => this.onDbError(err); - this.conn.on('error', this.dbErrorHandler); + this.pool = await mysql.createPool(this.conf.db); console.log('Connected to DB successfully.'.green); await this.poll(); } @@ -42,14 +40,7 @@ class PrintServer { clearTimeout(this.pollTimeout); this.pollTimeout = null; } - if (this.reconnectTimeout) { - clearTimeout(this.reconnectTimeout); - this.reconnectTimeout = null; - } - this.conn.off('error', this.dbErrorHandler); - // FIXME: mysql2/promise bug, conn.end() ends process - this.conn.on('error', () => {}); - await this.conn.end(); + await this.pool.end(); } async getToken() { const salix = this.conf.salix; @@ -59,73 +50,72 @@ class PrintServer { }); this.token = response.data.token; } - async onDbError(err) { - switch(err.code) { - case 'PROTOCOL_CONNECTION_LOST': - case 'ECONNRESET': - case 1927: // ER_CONNECTION_KILLED - console.error(`DB: ${err.message}`.red); - try { - await this.end(); - } catch(e) {} - console.log('Waiting until DB is available again...'.yellow); - await this.reconnect(); - break; - } - } - async reconnect() { - this.reconnectTimeout = null; - try { - await this.init(); - } catch (err) { - this.reconnectTimeout = setTimeout( - () => this.reconnect(), this.conf.reconnectTimeout * 1000); - } - } async poll() { + let delay = this.conf.refreshRate; this.pollTimeout = null; + try { - await this.printJob(); + const conn = await this.pool.getConnection(); + + try { + if (this.dbDisconnected) { + await conn.ping(); + this.dbDisconnected = false; + console.log('DB connection recovered.'.green); + } + + if (await this.printJob(conn)) + delay = 0; + } finally { + await conn.release(); + } } catch (err) { - console.error(err) + if (err.code === 'ETIMEDOUT') { + delay = this.conf.reconnectTimeout; + if (!this.dbDisconnected) { + this.dbDisconnected = true; + console.log(`DB connection lost: ${err.message}`.red); + } + } else + console.error(err); } - this.pollTimeout = setTimeout(() => this.poll(), this.conf.refreshRate); + + this.pollTimeout = setTimeout(() => this.poll(), delay); } - async printJob() { - const conn = this.conn; + async printJob(conn) { const conf = this.conf; let jobId; - let jobData; - const args = {}; try { - await conn.beginTransaction(); - const [[printJob]] = await conn.query(selectQuery); - if (!printJob) { + let jobData; + const args = {}; + + try { + await conn.beginTransaction(); + const [[printJob]] = await conn.query(selectQuery); + if (!printJob) { + await conn.rollback(); + return; + } + + jobId = printJob.id; + + // Job data + const [[data]] = await conn.query(jobDataQuery, jobId); + jobData = data; + + // Job arguments + const [res] = await conn.query(jobArgsQuery, jobId); + for (const row of res) + args[row.name] = row.value; + + await conn.query(updateQuery, ['printing', null, jobId]); + await conn.commit(); + } catch (err) { await conn.rollback(); - return; + throw err; } - jobId = printJob.id; - - // Job data - const [[data]] = await conn.query(jobDataQuery, jobId); - jobData = data; - - // Job arguments - const args = {}; - const [res] = await conn.query(jobArgsQuery, jobId); - for (const row of res) - args[row.name] = row.value; - - await conn.query(updateQuery, ['printing', null, jobId]); - await conn.commit(); - } catch (err) { - await conn.rollback(); - throw err; - } - - try { // Path params const usedParams = new Set(); const methodPath = jobData.method.replace(/{\w+}/g, function(match) { @@ -176,7 +166,7 @@ class PrintServer { // Print PDF try { - await pExec(`lp -d "${printer}" "${tmpFilePath}"`); + //await pExec(`lp -d "${printer}" "${tmpFilePath}"`); } catch(err) { await fs.unlink(tmpFilePath); throw new Error(`Print error: ${err.message}`); @@ -198,6 +188,8 @@ class PrintServer { await conn.query(updateQuery, ['error', message, jobId]); throw new Error(`(${jobId}) ${message}`); } + + return jobId; } }