Browse Source

uid for task and better messages / tasks sending via analytics service

pull/1/head
Coin de Gamma 6 years ago
parent
commit
2fb4e5a289
  1. 3
      server/src/models/analytics_message_model.ts
  2. 11
      server/src/models/analytics_task_model.ts
  3. 28
      server/src/services/analytics_service.ts
  4. 19
      server/src/utils/uid.ts

3
server/src/models/analytics_message_model.ts

@ -1,13 +1,12 @@
export enum AnalyticsMessageMethod { export enum AnalyticsMessageMethod {
TASK = 'TASK', TASK = 'TASK',
PING = 'PING',
TASK_RESULT = 'TASK_RESULT' TASK_RESULT = 'TASK_RESULT'
} }
export class AnalyticsMessage { export class AnalyticsMessage {
public constructor( public constructor(
public method: AnalyticsMessageMethod, public method: AnalyticsMessageMethod,
public payload?: string, public payload?: any,
public requestId?: number public requestId?: number
) { ) {

11
server/src/models/analytics_task_model.ts

@ -1,5 +1,9 @@
import { AnalyticUnitId } from "./analytic_unit_model"; import { AnalyticUnitId } from "./analytic_unit_model";
import { uid } from "../utils/uid";
const UID_LENGTH = 16;
export type AnalyticsTaskId = string; export type AnalyticsTaskId = string;
export enum AnalyticsTaskType { export enum AnalyticsTaskType {
@ -20,13 +24,17 @@ export class AnalyticsTask {
if(type === undefined || type === null) { if(type === undefined || type === null) {
throw new Error('type is undefined or null'); throw new Error('type is undefined or null');
} }
if(id === undefined) {
this.id = uid(UID_LENGTH);
}
} }
public toObject() { public toObject() {
return { return {
_id: this.id, _id: this.id,
analyticUnitId: this.analyticUnitId, analyticUnitId: this.analyticUnitId,
type: this.type type: this.type,
payload: this.payload
}; };
} }
@ -37,6 +45,7 @@ export class AnalyticsTask {
return new AnalyticsTask( return new AnalyticsTask(
obj.analyticUnitId, obj.analyticUnitId,
obj.type as AnalyticsTaskType, obj.type as AnalyticsTaskType,
obj.payload,
obj._id, obj._id,
); );
} }

28
server/src/services/analytics_service.ts

@ -1,4 +1,5 @@
import { AnalyticsMessageMethod, AnalyticsMessage } from '../models/analytics_message_model' import { AnalyticsTask } from '../models/analytics_task_model';
import { AnalyticsMessageMethod, AnalyticsMessage } from '../models/analytics_message_model';
import * as config from '../config'; import * as config from '../config';
const zmq = require('zeromq'); const zmq = require('zeromq');
@ -22,24 +23,25 @@ export class AnalyticsService {
this._init(); this._init();
} }
public async sendTask(taskObj: any): Promise<void> { public async sendTask(task: AnalyticsTask): Promise<void> {
if(!this._ready) { if(!this._ready) {
return Promise.reject("Analytics is not ready"); return Promise.reject("Analytics is not ready");
} }
let message = { let message = new AnalyticsMessage(
method: AnalyticsMessageMethod.TASK, AnalyticsMessageMethod.TASK,
payload: taskObj task.toObject()
} );
return this.sendMessage(message); return this.sendMessage(message);
} }
public async sendMessage(message: AnalyticsMessage): Promise<void> { public async sendMessage(message: AnalyticsMessage): Promise<void> {
let strMessage = JSON.stringify(message); let strMessage = JSON.stringify(message);
if(message.method === AnalyticsMessageMethod.PING) { return this.sendText(strMessage);
strMessage = 'PING'; }
}
public async sendText(text: string): Promise<void> {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
this._requester.send(strMessage, undefined, (err: any) => { this._requester.send(text, undefined, (err: any) => {
if(err) { if(err) {
reject(err); reject(err);
} else { } else {
@ -169,7 +171,8 @@ export class AnalyticsService {
} }
private _onAnalyticsMessage(data: any) { private _onAnalyticsMessage(data: any) {
if(data.toString() === 'PONG') { let text = data.toString();
if(text === 'PONG') {
this._pingResponded = true; this._pingResponded = true;
if(!this._ready) { if(!this._ready) {
this._ready = true; this._ready = true;
@ -178,7 +181,6 @@ export class AnalyticsService {
return; return;
} }
let text = data.toString();
let response; let response;
try { try {
response = JSON.parse(text); response = JSON.parse(text);
@ -201,7 +203,7 @@ export class AnalyticsService {
} }
this._pingResponded = false; this._pingResponded = false;
// TODO: set life limit for this ping // TODO: set life limit for this ping
this.sendMessage({ method: AnalyticsMessageMethod.PING }); this.sendText('PING');
}, config.ANLYTICS_PING_INTERVAL); }, config.ANLYTICS_PING_INTERVAL);
} }

19
server/src/utils/uid.ts

@ -0,0 +1,19 @@
import { randomBytes } from 'crypto';
// Copied from https://github.com/louischatriot/nedb/blob/master/lib/customUtils.js
/**
* Return a random alphanumerical string of length len
* There is a very small probability (less than 1/1,000,000) for the length to be less than len
* (il the base64 conversion yields too many pluses and slashes) but
* that's not an issue here
* The probability of a collision is extremely small (need 3*10^12 documents to have one chance in a million of a collision)
* See http://en.wikipedia.org/wiki/Birthday_problem
*/
export function uid(len: number): string {
return randomBytes(Math.ceil(Math.max(8, len * 2)))
.toString('base64')
.replace(/[+\/]/g, '')
.slice(0, len);
}
Loading…
Cancel
Save