// site-worker.js // Copyright (C) 2022 DTP Technologies, LLC // License: Apache-2.0 'use strict'; const path = require('path'); const SitePlatform = require(path.join(__dirname, 'site-platform')); const { SiteAsync } = require(path.join(__dirname, 'site-async')); const { SiteCommon } = require(path.join(__dirname, 'site-common')); class SiteWorker extends SiteCommon { constructor (dtp, component) { super(dtp, component); this.processors = { }; } async start ( ) { try { process.on('unhandledRejection', async (error, p) => { this.log.error('Unhandled rejection', { promise: p, message: error.message, stack: error.stack }); process.exit(-2); }); process.on('warning', (error) => { this.log.alert('warning', { error }); }); process.once('SIGINT', async ( ) => { this.log.info('SIGINT received'); this.log.info('requesting shutdown...'); await this.stop(); const exitCode = await SitePlatform.shutdown(); process.nextTick(( ) => { process.exit(exitCode); }); }); /* * Site Platform startup */ await SitePlatform.startPlatform(this.dtp); } catch (error) { this.log.error('failed to start worker', { component: this.dtp.config.component, error, }); process.exit(-1); } } /** * Load a script as a Worker processor. It must be derived from * SiteWorkerProcess and implement the expected interface. * @param {String} scriptFile the filename of the script to load as a Worker * processor. * @returns the new processor instance */ async loadProcessor (scriptFile) { const ProcessorClass = require(scriptFile); const processor = new ProcessorClass(this); const { COMPONENT } = ProcessorClass; this.log.info('loading worker processor', { component: COMPONENT.name }); this.processors[COMPONENT.name] = processor; return processor; } /** * Start all loaded processors. The assumption here is if you load any * additional processors *after* calling this method, you will start them * yourself in some way. */ async startProcessors ( ) { const slugs = Object.keys(this.processors); await SiteAsync.each(slugs, async (slug) => { const processor = this.processors[slug]; try { this.log.info('starting worker processor', { component: processor.component.name, }); await processor.start(); } catch (error) { this.log.error('failed to start processor', { component: processor.component.name, error, }); } }, 1); } /** * Stops any running child processors and terminates the worker. */ async stop ( ) { const slugs = Object.keys(this.processors); await SiteAsync.each(slugs, async (slug) => { const processor = this.processors[slug]; try { this.log.info('stopping worker processor', { component: processor.component.name, }); await processor.stop(); } catch (error) { this.log.error('failed to stop processor', { component: processor.component.name, error, }); } }, 1); } } module.exports.SiteWorker = SiteWorker;