UNPKG

test-bed-time-service

Version:

A time service for the test-bed, producing messages with real time, fictive time and scenario duration.

137 lines 5.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = require("events"); const node_test_bed_adapter_1 = require("node-test-bed-adapter"); const time_service_idle_state_1 = require("./states/time-service-idle-state"); class TimeService extends events_1.EventEmitter { constructor(options) { super(); this.log = node_test_bed_adapter_1.Logger.instance; this.interval = options.interval; this._trialTimeSpeed = 0; this._state = new time_service_idle_state_1.Idle(this); this.adapter = new node_test_bed_adapter_1.TestBedAdapter({ kafkaHost: options.kafkaHost, schemaRegistry: options.schemaRegistryUrl, fetchAllSchemas: false, clientId: 'TB-TimeService', autoRegisterSchemas: options.autoRegisterSchemas, schemaFolder: 'schemas', autoRegisterDefaultSchemas: false, consume: [{ topic: node_test_bed_adapter_1.TimeControlTopic }], produce: [node_test_bed_adapter_1.HeartbeatTopic, node_test_bed_adapter_1.LogTopic, node_test_bed_adapter_1.TimeControlTopic, node_test_bed_adapter_1.TimeTopic], fromOffset: false, // consume: [{ topic: TimeControlTopic }], // produce: [TimeTopic, TimeControlTopic], logging: { logToConsole: node_test_bed_adapter_1.LogLevel.Info, logToKafka: node_test_bed_adapter_1.LogLevel.Warn, }, }); this.adapter.on('ready', () => { this.subscribe(); this.log.info('Consumer is connected'); }); } connect() { return this.adapter.connect(); } /** Allow external services to control transitions. */ transition(msg) { this._state = this._state.transition(msg); this.sendTimeUpdate(); // force update with new state info ASAP this.emit('stateUpdated', this._state.name); } subscribe() { this.adapter.on('message', message => this.handleMessage(message)); this.adapter.on('error', err => this.log.error(`Consumer received an error: ${err}`)); this.adapter.on('offsetOutOfRange', err => { this.log.error(`Consumer received an offsetOutOfRange error on topic ${err.topic}.`); }); } handleMessage(message) { switch (message.topic) { case node_test_bed_adapter_1.TimeControlTopic: this.log.info(`${node_test_bed_adapter_1.TimeControlTopic} message:\n` + JSON.stringify(message, null, 2)); const controlMsg = message.value; this.transition(controlMsg); break; default: this.log.warn('Unhandled message: ' + JSON.stringify(message)); break; } } get state() { return this._state; } get trialTime() { return this._trialTime; } set trialTime(val) { // keep track of last time trial time was updated to allow correct computation of trial time based on speed this._lastTrialTimeUpdate = Date.now(); this._trialTime = val; } get trialTimeSpeed() { return this._trialTimeSpeed; } set trialTimeSpeed(val) { this._trialTimeSpeed = val; } get lastUpdateTime() { return this._lastTrialTimeUpdate; } get realStartTime() { return this._realStartTime; } /** * Computes the new Trial Time using the amount of time that has passed since the previous computation of TrialTime * and the TrialTimeSpeed. Updates the Trial Time accordingly. */ progressTrialTime() { const now = Date.now(); const passed = now - this.lastUpdateTime; const newTrialTime = Math.round(this.trialTime + passed * this.trialTimeSpeed); this.trialTime = newTrialTime; this._lastTrialTimeUpdate = now; return newTrialTime; } startScenario() { this._realStartTime = Date.now(); if (this.trialTime === null) { this.log.warn('No trial time provided upon scenario start. Defaulting Trial Time to current Real-time'); this.trialTime = this.realStartTime; } this._lastTrialTimeUpdate = this.realStartTime; this.startProducingTimeMessages(); } stopScenario() { this.stopProducingTimeMessages(); } sendTimeUpdate() { this.sendTimeMessage(this.state.createTimeMessage()); } sendTimeMessage(timeMsg) { this.emit('time', timeMsg); const payload = { topic: node_test_bed_adapter_1.TimeTopic, messages: timeMsg, attributes: 1, }; this.adapter.send(payload, err => { if (err) { this.log.error(err); } }); } startProducingTimeMessages() { this._timeHandler = setInterval(() => this.sendTimeUpdate(), this.interval); } stopProducingTimeMessages() { if (this._timeHandler) { clearInterval(this._timeHandler); } } } exports.TimeService = TimeService; //# sourceMappingURL=time-service.js.map