mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-06-15 15:21:03 +00:00
Deploy script (#52)
* No-downtime deploy script * Easier to use helper for average numbers
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
htdocs
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"deploy": "scripts/deploy.sh",
|
||||||
"start:frontend": "scripts/start-frontend.sh",
|
"start:frontend": "scripts/start-frontend.sh",
|
||||||
|
"build:frontend": "scripts/build-frontend.sh",
|
||||||
"start:backend": "scripts/start-backend.sh",
|
"start:backend": "scripts/start-backend.sh",
|
||||||
"build:backend": "scripts/build-backend.sh",
|
"build:backend": "scripts/build-backend.sh",
|
||||||
"check:backend": "tsc -p packages/backend --noEmit",
|
"check:backend": "tsc -p packages/backend --noEmit",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import * as EventEmitter from 'events';
|
|||||||
import Node from './Node';
|
import Node from './Node';
|
||||||
import Feed from './Feed';
|
import Feed from './Feed';
|
||||||
import FeedSet from './FeedSet';
|
import FeedSet from './FeedSet';
|
||||||
import { Maybe, Types, FeedMessage, blockAverage } from '@dotstats/common';
|
import { Maybe, Types, FeedMessage, NumStats } from '@dotstats/common';
|
||||||
|
|
||||||
const BLOCK_TIME_HISTORY = 10;
|
const BLOCK_TIME_HISTORY = 10;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ export default class Chain {
|
|||||||
public height = 0 as Types.BlockNumber;
|
public height = 0 as Types.BlockNumber;
|
||||||
public blockTimestamp = 0 as Types.Timestamp;
|
public blockTimestamp = 0 as Types.Timestamp;
|
||||||
|
|
||||||
private blockTimes: Array<number> = new Array(BLOCK_TIME_HISTORY).fill(0);
|
private blockTimes = new NumStats<Types.Milliseconds>(BLOCK_TIME_HISTORY);
|
||||||
private averageBlockTime: Maybe<Types.Milliseconds> = null;
|
private averageBlockTime: Maybe<Types.Milliseconds> = null;
|
||||||
|
|
||||||
constructor(label: Types.ChainLabel) {
|
constructor(label: Types.ChainLabel) {
|
||||||
@@ -110,9 +110,9 @@ export default class Chain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateAverageBlockTime(height: Types.BlockNumber, now: Types.Timestamp) {
|
private updateAverageBlockTime(height: Types.BlockNumber, now: Types.Timestamp) {
|
||||||
this.blockTimes[height % BLOCK_TIME_HISTORY] = now - this.blockTimestamp;
|
this.blockTimes.push((now - this.blockTimestamp) as Types.Milliseconds);
|
||||||
|
|
||||||
// We are guaranteed that count > 0
|
// We are guaranteed that count > 0
|
||||||
this.averageBlockTime = blockAverage(this.blockTimes);
|
this.averageBlockTime = this.blockTimes.average();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
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, blockAverage } from '@dotstats/common';
|
import { noop, timestamp, Maybe, Types, NumStats } 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';
|
import { getId, refreshId } from './nodeId';
|
||||||
@@ -42,7 +42,7 @@ export default class Node {
|
|||||||
|
|
||||||
private readonly ip: string;
|
private readonly ip: string;
|
||||||
private readonly socket: WebSocket;
|
private readonly socket: WebSocket;
|
||||||
private blockTimes: Array<number> = new Array(BLOCK_TIME_HISTORY);
|
private blockTimes = new NumStats<Types.Milliseconds>(BLOCK_TIME_HISTORY);
|
||||||
private lastBlockAt: Maybe<Date> = null;
|
private lastBlockAt: Maybe<Date> = null;
|
||||||
private pingStart = 0 as Types.Timestamp;
|
private pingStart = 0 as Types.Timestamp;
|
||||||
private throttle = false;
|
private throttle = false;
|
||||||
@@ -189,7 +189,7 @@ export default class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public get average(): Types.Milliseconds {
|
public get average(): Types.Milliseconds {
|
||||||
return blockAverage(this.blockTimes);
|
return this.blockTimes.average();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get localBlockAt(): Types.Milliseconds {
|
public get localBlockAt(): Types.Milliseconds {
|
||||||
@@ -265,7 +265,7 @@ export default class Node {
|
|||||||
this.height = height;
|
this.height = height;
|
||||||
this.blockTimestamp = timestamp();
|
this.blockTimestamp = timestamp();
|
||||||
this.lastBlockAt = time;
|
this.lastBlockAt = time;
|
||||||
this.blockTimes[height % BLOCK_TIME_HISTORY] = blockTime;
|
this.blockTimes.push(blockTime);
|
||||||
this.blockTime = blockTime;
|
this.blockTime = blockTime;
|
||||||
|
|
||||||
if (blockTime > 100) {
|
if (blockTime > 100) {
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import { Milliseconds } from './types';
|
|
||||||
|
|
||||||
export function blockAverage(blockTimes: Array<number>): Milliseconds {
|
|
||||||
let count = 0;
|
|
||||||
let sum = 0;
|
|
||||||
|
|
||||||
for (const time of blockTimes) {
|
|
||||||
if (time) {
|
|
||||||
count += 1;
|
|
||||||
sum += time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 0) {
|
|
||||||
return 0 as Milliseconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (sum / count) as Milliseconds;
|
|
||||||
}
|
|
||||||
@@ -35,3 +35,80 @@ export function sleep(time: Milliseconds): Promise<void> {
|
|||||||
export const timestamp = Date.now as () => Timestamp;
|
export const timestamp = Date.now as () => Timestamp;
|
||||||
|
|
||||||
export function noop() {}
|
export function noop() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of last N numbers pushed onto internal stack.
|
||||||
|
* Provides means to get an average of said numbers.
|
||||||
|
*/
|
||||||
|
export class NumStats<T extends number> {
|
||||||
|
private readonly stack: Array<T>;
|
||||||
|
private readonly history: number;
|
||||||
|
private index: 0;
|
||||||
|
|
||||||
|
constructor(history: number) {
|
||||||
|
if (history < 1) {
|
||||||
|
throw new Error('Must track at least one number');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.history = history;
|
||||||
|
this.stack = new Array(history);
|
||||||
|
}
|
||||||
|
|
||||||
|
public push(val: T) {
|
||||||
|
this.stack[this.index++ % this.history] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get average value of all values on the stack.
|
||||||
|
*
|
||||||
|
* @return {T} average value
|
||||||
|
*/
|
||||||
|
public average(): T {
|
||||||
|
if (this.index === 0) {
|
||||||
|
return 0 as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = this.nonEmpty();
|
||||||
|
let sum = 0;
|
||||||
|
|
||||||
|
for (const n of list as Array<number>) {
|
||||||
|
sum += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum / list.length) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get average value of all values of the stack after filtering
|
||||||
|
* out a number of highest and lowest values
|
||||||
|
*
|
||||||
|
* @param {number} extremes number of high/low values to ignore
|
||||||
|
* @return {T} average value
|
||||||
|
*/
|
||||||
|
public averageWithoutExtremes(extremes: number): T {
|
||||||
|
if (this.index === 0) {
|
||||||
|
return 0 as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = this.nonEmpty();
|
||||||
|
const count = list.length - extremes * 2;
|
||||||
|
|
||||||
|
if (count < 1) {
|
||||||
|
// Not enough entries to remove desired number of extremes,
|
||||||
|
// fall back to regular average
|
||||||
|
return this.average();
|
||||||
|
}
|
||||||
|
|
||||||
|
let sum = 0;
|
||||||
|
|
||||||
|
for (const n of list.sort((a, b) => a - b).slice(extremes, -extremes)) {
|
||||||
|
sum += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum / count) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
private nonEmpty(): Readonly<Array<number>> {
|
||||||
|
return this.index < this.history ? this.stack.slice(0, this.index) : this.stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
export * from './helpers';
|
export * from './helpers';
|
||||||
export * from './id';
|
export * from './id';
|
||||||
export * from './block';
|
|
||||||
export * from './stringify';
|
export * from './stringify';
|
||||||
|
|
||||||
import * as Types from './types';
|
import * as Types from './types';
|
||||||
@@ -9,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 = 13 as Types.FeedVersion;
|
export const VERSION: Types.FeedVersion = 14 as Types.FeedVersion;
|
||||||
|
|||||||
Executable
+1
@@ -0,0 +1 @@
|
|||||||
|
cd ./packages/frontend && yarn run build && cp -r ./build ../../htdocs && cd ../../
|
||||||
Executable
+1
@@ -0,0 +1 @@
|
|||||||
|
yarn run build:common && yarn run build:backend && yarn run build:frontend && pm2 restart all
|
||||||
Reference in New Issue
Block a user