Merge pull request 'refs #4550 Fix: Cannot read property 'method' of undefined' (!6) from 4550-transactionSlaveFixes into master
gitea/printnatura/pipeline/head This commit looks good Details

Reviewed-on: #6
This commit is contained in:
Juan Ferrer 2022-12-23 13:05:07 +00:00
commit 34413c7c57
3 changed files with 70 additions and 77 deletions

View File

@ -27,9 +27,7 @@ class PrintServer {
await this.init(); await this.init();
} }
async init() { async init() {
this.conn = await mysql.createConnection(this.conf.db); this.pool = await mysql.createPool(this.conf.db);
this.dbErrorHandler = err => this.onDbError(err);
this.conn.on('error', this.dbErrorHandler);
console.log('Connected to DB successfully.'.green); console.log('Connected to DB successfully.'.green);
await this.poll(); await this.poll();
} }
@ -42,14 +40,7 @@ class PrintServer {
clearTimeout(this.pollTimeout); clearTimeout(this.pollTimeout);
this.pollTimeout = null; this.pollTimeout = null;
} }
if (this.reconnectTimeout) { await this.pool.end();
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();
} }
async getToken() { async getToken() {
const salix = this.conf.salix; const salix = this.conf.salix;
@ -59,47 +50,49 @@ class PrintServer {
}); });
this.token = response.data.token; 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() { async poll() {
let delay = this.conf.refreshRate;
this.pollTimeout = null; this.pollTimeout = null;
try { 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) { } 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);
} }
this.pollTimeout = setTimeout(() => this.poll(), this.conf.refreshRate); } else
console.error(err);
} }
async printJob() {
const conn = this.conn; this.pollTimeout = setTimeout(() => this.poll(), delay);
}
async printJob(conn) {
const conf = this.conf; const conf = this.conf;
let printJob;
let jobId; let jobId;
try {
let jobData;
const args = {};
try { try {
await conn.beginTransaction(); await conn.beginTransaction();
[[printJob]] = await conn.query(selectQuery); const [[printJob]] = await conn.query(selectQuery);
if (!printJob) { if (!printJob) {
await conn.rollback(); await conn.rollback();
return; return;
@ -107,6 +100,15 @@ class PrintServer {
jobId = printJob.id; 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.query(updateQuery, ['printing', null, jobId]);
await conn.commit(); await conn.commit();
} catch (err) { } catch (err) {
@ -114,15 +116,6 @@ class PrintServer {
throw err; throw err;
} }
try {
// Job data
// FIXME: Cannot read property 'method' of undefined
const [[jobData]] = await conn.query(jobDataQuery, jobId);
const args = {};
const [res] = await conn.query(jobArgsQuery, jobId);
for (const row of res)
args[row.name] = row.value;
// Path params // Path params
const usedParams = new Set(); const usedParams = new Set();
const methodPath = jobData.method.replace(/{\w+}/g, function(match) { const methodPath = jobData.method.replace(/{\w+}/g, function(match) {
@ -135,10 +128,7 @@ class PrintServer {
let pdfData; let pdfData;
for (let attempts = 0; !pdfData && attempts < 2; attempts++) { for (let attempts = 0; !pdfData && attempts < 2; attempts++) {
// URL params // URL params
const params = { const params = {userFk: jobData.userFk};
access_token: this.token,
userFk: printJob.userFk
};
for (const key in args) { for (const key in args) {
if (!usedParams.has(key)) if (!usedParams.has(key))
params[key] = args[key]; params[key] = args[key];
@ -152,7 +142,8 @@ class PrintServer {
url: `${conf.salix.url}/api/${methodPath}?${urlParams.toString()}`, url: `${conf.salix.url}/api/${methodPath}?${urlParams.toString()}`,
responseType: 'arraybuffer', responseType: 'arraybuffer',
headers: { headers: {
'Accept': 'application/pdf' 'Accept': 'application/pdf',
'Authorization': this.token
} }
}); });
pdfData = response.data; pdfData = response.data;
@ -175,7 +166,7 @@ class PrintServer {
// Print PDF // Print PDF
try { try {
await pExec(`lp -d "${printer}" "${tmpFilePath}"`); //await pExec(`lp -d "${printer}" "${tmpFilePath}"`);
} catch(err) { } catch(err) {
await fs.unlink(tmpFilePath); await fs.unlink(tmpFilePath);
throw new Error(`Print error: ${err.message}`); throw new Error(`Print error: ${err.message}`);
@ -197,6 +188,8 @@ class PrintServer {
await conn.query(updateQuery, ['error', message, jobId]); await conn.query(updateQuery, ['error', message, jobId]);
throw new Error(`(${jobId}) ${message}`); throw new Error(`(${jobId}) ${message}`);
} }
return jobId;
} }
} }

View File

@ -1,4 +1,5 @@
SELECT r.name report, SELECT pq.workerFk userFk,
r.name report,
p.name printer, p.name printer,
r.method r.method
FROM printQueue pq FROM printQueue pq

View File

@ -1,5 +1,4 @@
SELECT pq.id, SELECT pq.id
pq.workerFk userFk
FROM printQueue pq FROM printQueue pq
JOIN report r ON r.id = pq.reportFk JOIN report r ON r.id = pq.reportFk
WHERE pq.statusCode = 'queued' WHERE pq.statusCode = 'queued'