mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-06-18 08:31:01 +00:00
Cache NodeId and Location (#35)
* Cache NodeId and Location * Fix frontend dependency vuln
This commit is contained in:
@@ -1,15 +1,14 @@
|
|||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
import * as EventEmitter from 'events';
|
import * as EventEmitter from 'events';
|
||||||
|
|
||||||
import { noop, timestamp, Maybe, Types, idGenerator, blockAverage } from '@dotstats/common';
|
import { noop, timestamp, Maybe, Types, blockAverage } from '@dotstats/common';
|
||||||
import { parseMessage, getBestBlock, Message, BestBlock, SystemInterval } from './message';
|
import { parseMessage, getBestBlock, Message, BestBlock, SystemInterval } from './message';
|
||||||
import { locate, Location } from './location';
|
import { locate, Location } from './location';
|
||||||
|
import { getId, refreshId } from './nodeId';
|
||||||
|
|
||||||
const BLOCK_TIME_HISTORY = 10;
|
const BLOCK_TIME_HISTORY = 10;
|
||||||
const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute
|
const TIMEOUT = (1000 * 60 * 1) as Types.Milliseconds; // 1 minute
|
||||||
|
|
||||||
const nextId = idGenerator<Types.NodeId>();
|
|
||||||
|
|
||||||
export interface NodeEvents {
|
export interface NodeEvents {
|
||||||
on(event: 'location', fn: (location: Location) => void): void;
|
on(event: 'location', fn: (location: Location) => void): void;
|
||||||
emit(event: 'location', location: Location): void;
|
emit(event: 'location', location: Location): void;
|
||||||
@@ -21,6 +20,7 @@ export default class Node {
|
|||||||
public readonly chain: Types.ChainLabel;
|
public readonly chain: Types.ChainLabel;
|
||||||
public readonly implementation: Types.NodeImplementation;
|
public readonly implementation: Types.NodeImplementation;
|
||||||
public readonly version: Types.NodeVersion;
|
public readonly version: Types.NodeVersion;
|
||||||
|
public readonly pubkey: Maybe<Types.NodePubKey>;
|
||||||
|
|
||||||
public readonly events = new EventEmitter() as EventEmitter & NodeEvents;
|
public readonly events = new EventEmitter() as EventEmitter & NodeEvents;
|
||||||
|
|
||||||
@@ -52,15 +52,17 @@ export default class Node {
|
|||||||
config: string,
|
config: string,
|
||||||
implentation: Types.NodeImplementation,
|
implentation: Types.NodeImplementation,
|
||||||
version: Types.NodeVersion,
|
version: Types.NodeVersion,
|
||||||
|
pubkey: Maybe<Types.NodePubKey>,
|
||||||
messages: Array<Message>,
|
messages: Array<Message>,
|
||||||
) {
|
) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.id = nextId();
|
this.id = getId(pubkey);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.chain = chain;
|
this.chain = chain;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.implementation = implentation;
|
this.implementation = implentation;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
this.pubkey = pubkey;
|
||||||
this.lastMessage = timestamp();
|
this.lastMessage = timestamp();
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
|
||||||
@@ -126,9 +128,9 @@ export default class Node {
|
|||||||
if (message.msg === "system.connected") {
|
if (message.msg === "system.connected") {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
const { name, chain, config, implementation, version } = message;
|
const { name, chain, config, implementation, version, pubkey } = message;
|
||||||
|
|
||||||
resolve(new Node(ip, socket, name, chain, config, implementation, version, messages));
|
resolve(new Node(ip, socket, name, chain, config, implementation, version, pubkey, messages));
|
||||||
} else {
|
} else {
|
||||||
if (messages.length === 10) {
|
if (messages.length === 10) {
|
||||||
messages.shift();
|
messages.shift();
|
||||||
@@ -194,6 +196,8 @@ export default class Node {
|
|||||||
this.socket.close();
|
this.socket.close();
|
||||||
this.socket.terminate();
|
this.socket.terminate();
|
||||||
|
|
||||||
|
refreshId(this.pubkey, this.id);
|
||||||
|
|
||||||
this.events.emit('disconnect');
|
this.events.emit('disconnect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export interface Location {
|
|||||||
city: Types.City;
|
city: Types.City;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cache = new Map<string, Location>();
|
const cache = new Map<string, Maybe<Location>>();
|
||||||
|
|
||||||
export async function locate(ip: string): Promise<Maybe<Location>> {
|
export async function locate(ip: string): Promise<Maybe<Location>> {
|
||||||
if (ip === '127.0.0.1') {
|
if (ip === '127.0.0.1') {
|
||||||
@@ -18,17 +18,19 @@ export async function locate(ip: string): Promise<Maybe<Location>> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const cached = cache.get(ip);
|
if (cache.has(ip)) {
|
||||||
|
return Promise.resolve(cache.get(ip));
|
||||||
if (cached) {
|
|
||||||
return Promise.resolve(cached);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cached = cache.get(ip);
|
||||||
|
|
||||||
return new Promise<Maybe<Location>>((resolve, _) => {
|
return new Promise<Maybe<Location>>((resolve, _) => {
|
||||||
iplocation(ip, (err, result) => {
|
iplocation(ip, (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(`Couldn't locate ${ip}`);
|
console.error(`Couldn't locate ${ip}`);
|
||||||
|
|
||||||
|
cache.set(ip, null);
|
||||||
|
|
||||||
return resolve(null);
|
return resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { timestamp, Maybe, Types, idGenerator } from '@dotstats/common';
|
||||||
|
|
||||||
|
const CACHE_LIFETIME = (24 * 3600 * 1000) as Types.Milliseconds; // 24h
|
||||||
|
const CACHE_INTERVAL = (3600 * 1000) as Types.Milliseconds; // 1h
|
||||||
|
|
||||||
|
interface NodeIdCache {
|
||||||
|
id: Types.NodeId;
|
||||||
|
ts: Types.Timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextId = idGenerator<Types.NodeId>();
|
||||||
|
const idCache = new Map<Types.NodePubKey, NodeIdCache>();
|
||||||
|
|
||||||
|
function clearCache() {
|
||||||
|
const now = timestamp();
|
||||||
|
|
||||||
|
for (const [pubkey, { ts }] of idCache.entries()) {
|
||||||
|
if ((now - ts) > CACHE_LIFETIME) {
|
||||||
|
idCache.delete(pubkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(clearCache, CACHE_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearCache();
|
||||||
|
|
||||||
|
export function getId(pubkey: Maybe<Types.NodePubKey>): Types.NodeId {
|
||||||
|
if (!pubkey) {
|
||||||
|
return nextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const cached = idCache.get(pubkey);
|
||||||
|
|
||||||
|
if (cached) {
|
||||||
|
return cached.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = nextId();
|
||||||
|
const ts = timestamp();
|
||||||
|
|
||||||
|
idCache.set(pubkey, { id, ts });
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function refreshId(pubkey: Maybe<Types.NodePubKey>, id: Types.NodeId) {
|
||||||
|
if (!pubkey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ts = timestamp();
|
||||||
|
|
||||||
|
idCache.set(pubkey, { id, ts });
|
||||||
|
}
|
||||||
@@ -8,4 +8,4 @@ import * as FeedMessage from './feed';
|
|||||||
export { Types, FeedMessage };
|
export { Types, FeedMessage };
|
||||||
|
|
||||||
// Increment this if breaking changes were made to types in `feed.ts`
|
// Increment this if breaking changes were made to types in `feed.ts`
|
||||||
export const VERSION: Types.FeedVersion = 8 as Types.FeedVersion;
|
export const VERSION: Types.FeedVersion = 9 as Types.FeedVersion;
|
||||||
|
|||||||
Generated
+2782
-2778
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "16.4.0",
|
"react": "16.4.0",
|
||||||
"react-dom": "16.4.0",
|
"react-dom": "16.4.0",
|
||||||
"react-scripts-ts": "2.16.0",
|
"react-scripts-ts": "2.17.0",
|
||||||
"react-svg": "^4.1.1"
|
"react-svg": "^4.1.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Types, Maybe } from '@dotstats/common';
|
|
||||||
import Row from './Row';
|
import Row from './Row';
|
||||||
import Location from './Location';
|
import Location from './Location';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user