use a single, shared timestamps array between all pings
This commit is contained in:
parent
3ddb2c9a08
commit
c2494af82d
@ -102,7 +102,7 @@ export class App {
|
|||||||
.reduce((sum, current) => sum + current, 0)
|
.reduce((sum, current) => sum + current, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
addServer = (pings) => {
|
addServer = (pings, timestampPoints) => {
|
||||||
// Even if the backend has never pinged the server, the frontend is promised a placeholder object.
|
// Even if the backend has never pinged the server, the frontend is promised a placeholder object.
|
||||||
// result = undefined
|
// result = undefined
|
||||||
// error = defined with "Waiting" description
|
// error = defined with "Waiting" description
|
||||||
@ -114,14 +114,14 @@ export class App {
|
|||||||
|
|
||||||
// Push the historical data into the graph
|
// Push the historical data into the graph
|
||||||
// This will trim and format the data so it is ready for the graph to render once init
|
// This will trim and format the data so it is ready for the graph to render once init
|
||||||
serverRegistration.addGraphPoints(pings)
|
serverRegistration.addGraphPoints(pings, timestampPoints)
|
||||||
|
|
||||||
// Create the plot instance internally with the restructured and cleaned data
|
// Create the plot instance internally with the restructured and cleaned data
|
||||||
serverRegistration.buildPlotInstance()
|
serverRegistration.buildPlotInstance()
|
||||||
|
|
||||||
// Handle the last known state (if any) as an incoming update
|
// Handle the last known state (if any) as an incoming update
|
||||||
// This triggers the main update pipeline and enables centralized update handling
|
// This triggers the main update pipeline and enables centralized update handling
|
||||||
serverRegistration.updateServerStatus(latestPing, latestPing.timestamp, true, this.publicConfig.minecraftVersions)
|
serverRegistration.updateServerStatus(latestPing, true, this.publicConfig.minecraftVersions)
|
||||||
|
|
||||||
// Allow the ServerRegistration to bind any DOM events with app instance context
|
// Allow the ServerRegistration to bind any DOM events with app instance context
|
||||||
serverRegistration.initEventListeners()
|
serverRegistration.initEventListeners()
|
||||||
|
@ -94,7 +94,7 @@ export class ServerRegistration {
|
|||||||
this._failedSequentialPings = 0
|
this._failedSequentialPings = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
addGraphPoints (points) {
|
addGraphPoints (points, timestampPoints) {
|
||||||
// Test if the first point contains error.placeholder === true
|
// Test if the first point contains error.placeholder === true
|
||||||
// This is sent by the backend when the server hasn't been pinged yet
|
// This is sent by the backend when the server hasn't been pinged yet
|
||||||
// These points will be disregarded to prevent the graph starting at 0 player count
|
// These points will be disregarded to prevent the graph starting at 0 player count
|
||||||
@ -106,30 +106,33 @@ export class ServerRegistration {
|
|||||||
points.slice(points.length - SERVER_GRAPH_DATA_MAX_LENGTH, points.length)
|
points.slice(points.length - SERVER_GRAPH_DATA_MAX_LENGTH, points.length)
|
||||||
}
|
}
|
||||||
|
|
||||||
this._graphData = points.map(point => point.result ? [point.timestamp, point.result.players.online] : [point.timestamp, 0])
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
const point = points[i]
|
||||||
|
const timestamp = timestampPoints[i]
|
||||||
|
|
||||||
|
this._graphData.push([timestamp, point.result ? point.result.players.online : 0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildPlotInstance () {
|
buildPlotInstance () {
|
||||||
this._plotInstance = $.plot('#chart_' + this.serverId, [this._graphData], SERVER_GRAPH_OPTIONS)
|
this._plotInstance = $.plot('#chart_' + this.serverId, [this._graphData], SERVER_GRAPH_OPTIONS)
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePing (payload, timestamp, pushToGraph) {
|
handlePing (payload, timestamp) {
|
||||||
if (payload.result) {
|
if (payload.result) {
|
||||||
this.playerCount = payload.result.players.online
|
this.playerCount = payload.result.players.online
|
||||||
|
|
||||||
if (pushToGraph) {
|
// Only update graph for successful pings
|
||||||
// Only update graph for successful pings
|
// This intentionally pauses the server graph when pings begin to fail
|
||||||
// This intentionally pauses the server graph when pings begin to fail
|
this._graphData.push([timestamp, this.playerCount])
|
||||||
this._graphData.push([timestamp, this.playerCount])
|
|
||||||
|
|
||||||
// Trim graphData to within the max length by shifting out the leading elements
|
// Trim graphData to within the max length by shifting out the leading elements
|
||||||
if (this._graphData.length > SERVER_GRAPH_DATA_MAX_LENGTH) {
|
if (this._graphData.length > SERVER_GRAPH_DATA_MAX_LENGTH) {
|
||||||
this._graphData.shift()
|
this._graphData.shift()
|
||||||
}
|
|
||||||
|
|
||||||
this.redraw()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.redraw()
|
||||||
|
|
||||||
// Reset failed ping counter to ensure the next connection error
|
// Reset failed ping counter to ensure the next connection error
|
||||||
// doesn't instantly retrigger a layout change
|
// doesn't instantly retrigger a layout change
|
||||||
this._failedSequentialPings = 0
|
this._failedSequentialPings = 0
|
||||||
@ -169,11 +172,7 @@ export class ServerRegistration {
|
|||||||
this.lastPeakData = data
|
this.lastPeakData = data
|
||||||
}
|
}
|
||||||
|
|
||||||
updateServerStatus (ping, timestamp, isInitialUpdate, minecraftVersions) {
|
updateServerStatus (ping, isInitialUpdate, minecraftVersions) {
|
||||||
// Only pushToGraph when initialUpdate === false
|
|
||||||
// Otherwise the ping value is pushed into the graphData when already present
|
|
||||||
this.handlePing(ping, timestamp, !isInitialUpdate)
|
|
||||||
|
|
||||||
if (ping.versions) {
|
if (ping.versions) {
|
||||||
const versionsElement = document.getElementById('version_' + this.serverId)
|
const versionsElement = document.getElementById('version_' + this.serverId)
|
||||||
|
|
||||||
|
@ -67,7 +67,9 @@ export class SocketManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payload.servers.forEach(this._app.addServer)
|
payload.servers.forEach(server => {
|
||||||
|
this._app.addServer(server, payload.timestampPoints)
|
||||||
|
})
|
||||||
|
|
||||||
if (payload.mojangServices) {
|
if (payload.mojangServices) {
|
||||||
this._app.mojangUpdater.updateStatus(payload.mojangServices)
|
this._app.mojangUpdater.updateStatus(payload.mojangServices)
|
||||||
@ -88,6 +90,8 @@ export class SocketManager {
|
|||||||
const serverUpdate = payload.updates[serverId]
|
const serverUpdate = payload.updates[serverId]
|
||||||
|
|
||||||
if (serverRegistration) {
|
if (serverRegistration) {
|
||||||
|
serverRegistration.handlePing(serverUpdate, payload.timestamp)
|
||||||
|
|
||||||
serverRegistration.updateServerStatus(serverUpdate, payload.timestamp, false, this._app.publicConfig.minecraftVersions)
|
serverRegistration.updateServerStatus(serverUpdate, payload.timestamp, false, this._app.publicConfig.minecraftVersions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ const Database = require('./database')
|
|||||||
const MojangUpdater = require('./mojang')
|
const MojangUpdater = require('./mojang')
|
||||||
const PingController = require('./ping')
|
const PingController = require('./ping')
|
||||||
const Server = require('./server')
|
const Server = require('./server')
|
||||||
|
const TimeTracker = require('./time')
|
||||||
const MessageOf = require('./message')
|
const MessageOf = require('./message')
|
||||||
|
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
@ -14,6 +15,7 @@ class App {
|
|||||||
this.mojangUpdater = new MojangUpdater(this)
|
this.mojangUpdater = new MojangUpdater(this)
|
||||||
this.pingController = new PingController(this)
|
this.pingController = new PingController(this)
|
||||||
this.server = new Server(this.handleClientConnection)
|
this.server = new Server(this.handleClientConnection)
|
||||||
|
this.timeTracker = new TimeTracker()
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDatabase (callback) {
|
loadDatabase (callback) {
|
||||||
@ -73,6 +75,7 @@ class App {
|
|||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
mojangServices: this.mojangUpdater.getLastUpdate(),
|
mojangServices: this.mojangUpdater.getLastUpdate(),
|
||||||
|
timestampPoints: this.timeTracker.getPoints(),
|
||||||
servers: this.serverRegistrations.map(serverRegistration => serverRegistration.getPingHistory())
|
servers: this.serverRegistrations.map(serverRegistration => serverRegistration.getPingHistory())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class PingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pingAll = () => {
|
pingAll = () => {
|
||||||
const timestamp = new Date().getTime()
|
const timestamp = this._app.timeTracker.newTimestamp()
|
||||||
|
|
||||||
this.startPingTasks(results => {
|
this.startPingTasks(results => {
|
||||||
const updates = []
|
const updates = []
|
||||||
|
@ -16,7 +16,7 @@ class ServerRegistration {
|
|||||||
|
|
||||||
handlePing (timestamp, resp, err, version) {
|
handlePing (timestamp, resp, err, version) {
|
||||||
// Store into in-memory ping data
|
// Store into in-memory ping data
|
||||||
this.addPing(timestamp, resp)
|
this.addPing(resp)
|
||||||
|
|
||||||
// Only notify the frontend to append to the historical graph
|
// Only notify the frontend to append to the historical graph
|
||||||
// if both the graphing behavior is enabled and the backend agrees
|
// if both the graphing behavior is enabled and the backend agrees
|
||||||
@ -89,10 +89,8 @@ class ServerRegistration {
|
|||||||
return update
|
return update
|
||||||
}
|
}
|
||||||
|
|
||||||
addPing (timestamp, resp) {
|
addPing (resp) {
|
||||||
const ping = {
|
const ping = {}
|
||||||
timestamp: timestamp
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resp) {
|
if (resp) {
|
||||||
// Append a result object
|
// Append a result object
|
||||||
@ -127,7 +125,6 @@ class ServerRegistration {
|
|||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
serverId: this.serverId,
|
serverId: this.serverId,
|
||||||
timestamp: lastPing.timestamp,
|
|
||||||
versions: this.versions,
|
versions: this.versions,
|
||||||
recordData: this.recordData,
|
recordData: this.recordData,
|
||||||
favicon: this.lastFavicon
|
favicon: this.lastFavicon
|
||||||
@ -157,7 +154,6 @@ class ServerRegistration {
|
|||||||
|
|
||||||
return [{
|
return [{
|
||||||
serverId: this.serverId,
|
serverId: this.serverId,
|
||||||
timestamp: new Date().getTime(),
|
|
||||||
error: {
|
error: {
|
||||||
message: 'Waiting...',
|
message: 'Waiting...',
|
||||||
placeholder: true
|
placeholder: true
|
||||||
|
23
lib/time.js
Normal file
23
lib/time.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
class TimeTracker {
|
||||||
|
constructor () {
|
||||||
|
this._points = []
|
||||||
|
}
|
||||||
|
|
||||||
|
newTimestamp () {
|
||||||
|
const timestamp = new Date().getTime()
|
||||||
|
|
||||||
|
this._points.push(timestamp)
|
||||||
|
|
||||||
|
if (this._points.length > 72) {
|
||||||
|
this._points.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
return timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
getPoints () {
|
||||||
|
return this._points
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = TimeTracker
|
Loading…
Reference in New Issue
Block a user