You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.6 KiB

import { AnalyticsTask, AnalyticsTaskType } from '../models/analytics_task_model';
import * as AnalyticUnit from '../models/analytic_unit_model';
import { AnalyticsService } from './analytics_service';
import { HASTIC_API_KEY } from '../config';
import { queryByMetric } from 'grafana-datasource-kit';
import * as _ from 'lodash';
declare type UnitTime = {
unit: AnalyticUnit.AnalyticUnit,
time: number
};
export class DataPuller {
private PULL_PERIOD_MS: number = 5000;
private _interval: number = 1000;
private _timer: any = null;
private _unitTimes: { [id: string]: UnitTime } = {};
constructor(private analyticsService: AnalyticsService){};
public addUnit(unit: AnalyticUnit.AnalyticUnit) {
let time = unit.lastDetectionTime || Date.now();
let unitTime: UnitTime = {unit, time };
this._unitTimes[unit.id] = unitTime;
}
public deleteUnit(id: AnalyticUnit.AnalyticUnitId) {
delete this._unitTimes[id];
}
private pullData(unit: AnalyticUnit.AnalyticUnit, from: number, to: number) {
if(!unit) {
throw Error(`puller: can't pull undefined unit`);
}
return queryByMetric(unit.metric, unit.panelUrl, from, to, HASTIC_API_KEY);
}
private pushData(unit: AnalyticUnit.AnalyticUnit, data: any) {
if(unit === undefined || data === undefined) {
throw Error(`can't push unit: ${unit} data: ${data}`);
}
let task = new AnalyticsTask(unit.id, AnalyticsTaskType.PUSH, data);
this.analyticsService.sendTask(task);
}
//TODO: group analyticUnits by panelID and send same dataset for group
public runPuller() {
this._timer = setTimeout(this.puller.bind(this), this._interval);
console.log('Data puller runned');
}
public stopPuller() {
if(this._timer) {
clearTimeout(this._timer);
this._timer = null;
this._interval = 0;
console.log('Data puller stopped');
}
console.log('Data puller already stopped');
}
private async puller() {
if(_.isEmpty(this._unitTimes)) {
this._interval = this.PULL_PERIOD_MS;
this._timer = setTimeout(this.puller.bind(this), this._interval);
return;
}
let now = Date.now();
_.forOwn(this._unitTimes, async value => {
if(!value.unit.alert) {
return;
}
let data = await this.pullData(value.unit, value.time, now);
if(data.values.length === 0) {
return;
}
let payload = { data, from: value.time, to: now};
value.time = now;
this.pushData(value.unit, payload);
});
this._timer = setTimeout(this.puller.bind(this), this._interval);
}
}