diff --git a/package-lock.json b/package-lock.json index 6d7476d5..d6879c4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21164,6 +21164,7 @@ "xmlbuilder2": "^3.1.1" }, "devDependencies": { + "@types/node": "^20.11.16", "c8": "^9.1.0", "chai": "^5.0.3", "chai-subset": "^1.6.0", @@ -21176,6 +21177,15 @@ "xml2js-xpath": "^0.13.0" } }, + "packages/ckan/node_modules/@types/node": { + "version": "20.11.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", + "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "packages/ckan/node_modules/foreground-child": { "version": "3.1.1", "dev": true, diff --git a/packages/ckan/package.json b/packages/ckan/package.json index 55d2c0cc..f021eee0 100644 --- a/packages/ckan/package.json +++ b/packages/ckan/package.json @@ -37,6 +37,7 @@ "xmlbuilder2": "^3.1.1" }, "devDependencies": { + "@types/node": "^20.11.16", "c8": "^9.1.0", "chai": "^5.0.3", "chai-subset": "^1.6.0", diff --git a/packages/core/index.js b/packages/core/index.js index e47326b7..5d24632a 100644 --- a/packages/core/index.js +++ b/packages/core/index.js @@ -1,4 +1,5 @@ // @ts-check +import EventEmitter from 'node:events' import express from 'express' import { pino } from 'pino' import cors from 'cors' @@ -41,6 +42,7 @@ export { * }>} Trifid instance. */ const trifid = async (config, additionalMiddlewares = {}) => { + const trifidEvents = new EventEmitter() const fullConfig = await handler(config) const server = express() server.disable('x-powered-by') @@ -63,6 +65,15 @@ const trifid = async (config, additionalMiddlewares = {}) => { // Add support for absolute URLs, so that we can use `req.absoluteUrl()` in any middleware to get the absolute URL server.use(absoluteUrl()) + // Forward server events to the Trifid middlewares + server.on('ready', () => { + trifidEvents.emit('ready') + }) + + server.on('close', () => { + trifidEvents.emit('close') + }) + // Configure Express server if (fullConfig?.server?.express) { for (const expressSettingKey in fullConfig.server.express) { @@ -104,6 +115,7 @@ const trifid = async (config, additionalMiddlewares = {}) => { logger, templateEngineInstance, `http://${host}:${portNumber}/`, + trifidEvents, ) const start = async () => { diff --git a/packages/core/lib/middlewares/apply.js b/packages/core/lib/middlewares/apply.js index beeae8b5..2c29718c 100644 --- a/packages/core/lib/middlewares/apply.js +++ b/packages/core/lib/middlewares/apply.js @@ -2,7 +2,7 @@ import merge from 'lodash/merge.js' import vhost from 'vhost' import { initQuery } from '../sparql.js' -const apply = async (server, globals, middlewares, logger, templateEngine, instanceHostname) => { +const apply = async (server, globals, middlewares, logger, templateEngine, instanceHostname, trifidEvents) => { const { query: querySparql } = initQuery(logger, globals.endpoints, instanceHostname) for (const middleware of middlewares) { @@ -28,6 +28,7 @@ const apply = async (server, globals, middlewares, logger, templateEngine, insta render, query, registerTemplateHelper: registerHelper, + trifidEvents, }) // default path is '/' (see: https://github.com/expressjs/express/blob/d854c43ea177d1faeea56189249fff8c24a764bd/lib/router/index.js#L425) diff --git a/packages/core/types/index.js b/packages/core/types/index.js index 5f96083a..fee21eb4 100644 --- a/packages/core/types/index.js +++ b/packages/core/types/index.js @@ -74,6 +74,7 @@ * @property {Object.} config The Trifid configuration. * @property {(templatePath: string, context: Object., options: Object.) => Promise} render The render function. * @property {TrifidQuery} query The SPARQL query function. + * @property {import('node:events').EventEmitter} trifidEvents The Trifid events emitter. */ /** diff --git a/packages/handler-fetch/index.js b/packages/handler-fetch/index.js index 3419d2ab..e9361c0a 100644 --- a/packages/handler-fetch/index.js +++ b/packages/handler-fetch/index.js @@ -6,7 +6,7 @@ import { waitForVariableToBeTrue } from './lib/utils.js' /** @type {import('trifid-core/dist/types/index.d.ts').TrifidMiddleware} */ export const factory = async (trifid) => { - const { config, logger } = trifid + const { config, logger, trifidEvents } = trifid const { contentType, url, baseIri, graphName, unionDefaultGraph } = config const queryTimeout = 30000 @@ -17,6 +17,18 @@ export const factory = async (trifid) => { let ready = false + logger.warn('Listening to Trifid events…') + + trifidEvents.on('ready', async () => { + logger.warn('Got "ready" event from Trifid') + }) + + trifidEvents.on('close', async () => { + logger.warn('Got "close" event from Trifid ; closing worker…') + await worker.terminate() + logger.debug('Worker terminated') + }) + worker.on('message', async (message) => { const { type, data } = message if (type === 'log') {