119 lines
2.3 KiB
JavaScript
119 lines
2.3 KiB
JavaScript
'use strict';
|
|
|
|
const db = require('../db/knex');
|
|
const {
|
|
broadcastPhotoEvent,
|
|
broadcastActivityEvent,
|
|
} = require('../ws-server');
|
|
|
|
const {
|
|
ensureServerEventOutbox,
|
|
getNextPendingServerEvent,
|
|
completeServerEvent,
|
|
failServerEvent,
|
|
} = require('../db/serverEventOutbox');
|
|
|
|
function sleep(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async function dispatchEvent(event) {
|
|
let payload;
|
|
|
|
try {
|
|
payload = JSON.parse(event.payload);
|
|
} catch (err) {
|
|
throw new Error(
|
|
`Payload JSON non valido per evento ${event.id}: ${err.message}`
|
|
);
|
|
}
|
|
|
|
switch (event.channel) {
|
|
case 'photo':
|
|
await broadcastPhotoEvent(event.user, payload);
|
|
return;
|
|
|
|
case 'activity':
|
|
await broadcastActivityEvent(event.user, payload);
|
|
return;
|
|
|
|
default:
|
|
throw new Error(
|
|
`Canale outbox sconosciuto: ${event.channel}`
|
|
);
|
|
}
|
|
}
|
|
|
|
function startWsOutboxConsumer(options = {}) {
|
|
const pollMs = Math.max(
|
|
100,
|
|
Number(options.pollMs) || 250
|
|
);
|
|
|
|
let stopping = false;
|
|
|
|
async function loop() {
|
|
await ensureServerEventOutbox(db);
|
|
|
|
console.log(
|
|
`[WsOutboxConsumer] avviato; polling ${pollMs} ms`
|
|
);
|
|
|
|
while (!stopping) {
|
|
try {
|
|
const event = await getNextPendingServerEvent(db);
|
|
|
|
if (!event) {
|
|
await sleep(pollMs);
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
await dispatchEvent(event);
|
|
await completeServerEvent(db, event.id);
|
|
|
|
console.log(
|
|
`[WsOutboxConsumer] evento ${event.id} inviato ` +
|
|
`channel=${event.channel} user=${event.user}`
|
|
);
|
|
} catch (err) {
|
|
await failServerEvent(
|
|
db,
|
|
event.id,
|
|
err.message
|
|
);
|
|
|
|
console.error(
|
|
`[WsOutboxConsumer] evento ${event.id} fallito:`,
|
|
err.message
|
|
);
|
|
|
|
// Evita un busy-loop continuo su un evento non valido.
|
|
await sleep(pollMs);
|
|
}
|
|
} catch (err) {
|
|
console.error(
|
|
'[WsOutboxConsumer] errore ciclo:',
|
|
err
|
|
);
|
|
|
|
await sleep(pollMs);
|
|
}
|
|
}
|
|
}
|
|
|
|
loop().catch((err) => {
|
|
console.error(
|
|
'[WsOutboxConsumer] errore fatale:',
|
|
err
|
|
);
|
|
});
|
|
|
|
return () => {
|
|
stopping = true;
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
startWsOutboxConsumer,
|
|
};
|