tinylink/core/app.js
mahdahar 10f8dbbb83 refactor: consolidate core runtime and docs
Move middleware sources into core/, refresh config paths, and update design/user docs to reflect the raw payload pipeline.
2026-04-07 11:30:11 +07:00

85 lines
2.8 KiB
JavaScript

const config = require('./config/config');
const logger = require('./logger');
const migrate = require('./maintenance/migrate');
const { createHttpJsonConnector } = require('./connectors/httpJson');
const { createHl7TcpConnector } = require('./connectors/tcp');
const { createAstmSerialConnector } = require('./connectors/serial');
const { processMessage } = require('./pipeline/pipeline');
const { startWorker, stopWorker } = require('./worker/worker');
const instrumentConfig = require('./config/instrumentConfig');
const { createHttpServer } = require('./http');
const connectorFactories = {
'http-json': createHttpJsonConnector,
'hl7-tcp': createHl7TcpConnector,
'astm-serial': createAstmSerialConnector
};
function buildConnectors() {
return instrumentConfig.list()
.filter((entry) => entry.enabled)
.map((entry) => {
const createConnector = connectorFactories[entry.connector];
if (!createConnector) {
logger.warn({ connector: entry.connector, instrument_id: entry.instrument_id }, 'unknown connector in instrument config, skipping startup');
return null;
}
return createConnector({
...(entry.connectorConfig || {}),
instrument_id: entry.instrument_id
});
})
.filter(Boolean);
}
function attachConnectorHandlers(connectors) {
connectors.forEach((connector) => {
connector.onMessage(async (incoming) => {
try {
const payload = incoming && Object.prototype.hasOwnProperty.call(incoming, 'payload')
? incoming.payload
: incoming;
const context = incoming && incoming.context ? incoming.context : {};
await processMessage(connector.name(), payload, context);
} catch (err) {
logger.error({ err: err.message, connector: connector.name() }, 'pipeline error');
}
});
connector.onError((err) => {
logger.error({ err: err.message }, `${connector.name()} emitted error`);
});
});
}
async function start() {
instrumentConfig.validateAndLoadInstrumentConfigs();
await migrate();
await instrumentConfig.init();
const connectors = buildConnectors();
if (!connectors.length) {
logger.warn('no enabled connectors configured, ingestion listeners are disabled');
}
attachConnectorHandlers(connectors);
await Promise.all(connectors.map((connector) => connector.start()));
await startWorker();
const app = createHttpServer(connectors);
const server = app.listen(config.healthPort, () => {
logger.info({ port: config.healthPort }, 'health server ready');
});
async function shutdown() {
await stopWorker();
await Promise.all(connectors.map((connector) => connector.stop()));
if (server) {
await new Promise((resolve) => server.close(resolve));
}
}
return { connectors, server, shutdown };
}
module.exports = { start };