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
JavaScript
"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