UNPKG

@tvkitchen/countertop

Version:

The entry point for developers who want to set up a TV Kitchen.

147 lines (129 loc) 4.26 kB
import { v4 as uuid } from 'uuid' import { countertopStates } from '../constants' import { consoleLogger } from '../tools/loggers' import CountertopWorker from './CountertopWorker' class CountertopStation { logger = null kafka = null id = null Appliance = null applianceSettings = null workers = [] state = '' /** * Create a CountertopStation * * @param {Class} Appliance The IAppliance class that this station will manage. * @param {Object} applianceSettings Settings for the appliance. * @param {Logger} options.logger A logger with methods for all TV Kitchen logLevels. */ constructor( Appliance, applianceSettings = {}, { logger = consoleLogger, kafka, } = {}, ) { if (Appliance === undefined) { throw new Error('CountertopStation requires an Appliance.') } this.Appliance = Appliance this.applianceSettings = applianceSettings this.logger = logger this.kafka = kafka this.id = `${Appliance.name}::${uuid()}` this.setState(countertopStates.STOPPED) } /** * Replace the station's workers in order to fit a specified topology. * * @param {CountertopToplogy} topology The topology to use. * @return {CountertopWorker[]} The new set of workers. */ invokeTopology = (topology) => { this.logger.trace(`CountertopStation<${this.id}>: invokeTopology()`) if (this.getState() !== countertopStates.STOPPED) { throw new Error('CountertopStations must be stopped before invoking a topology.') } const stationStreams = topology.streams.filter((stream) => stream.getMouth() === this) this.workers = stationStreams.map((stream) => new CountertopWorker( this.Appliance, this.applianceSettings, { stream, logger: this.logger, kafka: this.kafka, }, )) return this.workers } /** * Start the station and begin data processing. * * @return {Boolean} Whether the station successfully started. */ start = async () => { this.logger.trace(`CountertopStation<${this.id}>: start()`) this.state = countertopStates.STARTING const promises = this.workers.map(async (worker) => worker.start()) const started = (await Promise.all(promises)).every((result) => result) this.setState(started ? countertopStates.STARTED : countertopStates.ERRORED) return this.getState() === countertopStates.STARTED } /** * Stop the countertop and halt all data processing. * * @return {Boolean} Whether the station successfully stopped. */ stop = async () => { this.logger.trace(`CountertopStation<${this.id}>: stop()`) this.setState(countertopStates.STOPPING) const promises = this.workers.map(async (worker) => worker.stop()) const stopped = (await Promise.all(promises)).every((result) => result) this.setState(stopped ? countertopStates.STOPPED : countertopStates.ERRORED) return this.getState() === countertopStates.STOPPED } /** * Get the data types that this station processes. * * This is determined by the Appliance that the station hosts. * * @return {String[]} The data types that this station processes. */ getInputTypes = () => this.Appliance.getInputTypes(this.applianceSettings) /** * Get the data types that this station produces. * * This is determined by the Appliance that the station hosts. * * @return {String[]} The data types that this station produces. */ getOutputTypes = () => this.Appliance.getOutputTypes(this.applianceSettings) /** * Get the current state of the CountertopStation. * * @return {String} The state of the CountertopStation. */ getState = () => this.state /** * Set the current state of the CountertopStation. * * This is an internal method. */ setState = (state) => { this.state = state } /** * Registers a listener to the CountertopStation for a given event type. * * Event types are defined in @tvkitchen/base-constants * * @param {String} eventType The type of event being listened to. * @param {Function} listener The listener to be registered for that event. * @return {CountertopStation} The CountertopStation instance (to enable chaining). */ on = (eventType, listener) => { this.workers.forEach((worker) => worker.on(eventType, listener)) return this } } export default CountertopStation