work on bulking updateServer payloads and single timestamps
This commit is contained in:
parent
a3c88dc0c5
commit
3ddb2c9a08
@ -121,7 +121,7 @@ export class App {
|
|||||||
|
|
||||||
// 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, true, this.publicConfig.minecraftVersions)
|
serverRegistration.updateServerStatus(latestPing, latestPing.timestamp, 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()
|
||||||
|
@ -113,14 +113,14 @@ export class ServerRegistration {
|
|||||||
this._plotInstance = $.plot('#chart_' + this.serverId, [this._graphData], SERVER_GRAPH_OPTIONS)
|
this._plotInstance = $.plot('#chart_' + this.serverId, [this._graphData], SERVER_GRAPH_OPTIONS)
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePing (payload, pushToGraph) {
|
handlePing (payload, timestamp, pushToGraph) {
|
||||||
if (payload.result) {
|
if (payload.result) {
|
||||||
this.playerCount = payload.result.players.online
|
this.playerCount = payload.result.players.online
|
||||||
|
|
||||||
if (pushToGraph) {
|
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([payload.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) {
|
||||||
@ -169,10 +169,10 @@ export class ServerRegistration {
|
|||||||
this.lastPeakData = data
|
this.lastPeakData = data
|
||||||
}
|
}
|
||||||
|
|
||||||
updateServerStatus (ping, isInitialUpdate, minecraftVersions) {
|
updateServerStatus (ping, timestamp, isInitialUpdate, minecraftVersions) {
|
||||||
// Only pushToGraph when initialUpdate === false
|
// Only pushToGraph when initialUpdate === false
|
||||||
// Otherwise the ping value is pushed into the graphData when already present
|
// Otherwise the ping value is pushed into the graphData when already present
|
||||||
this.handlePing(ping, !isInitialUpdate)
|
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)
|
||||||
|
@ -79,27 +79,30 @@ export class SocketManager {
|
|||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'updateServer': {
|
case 'updateServers': {
|
||||||
// The backend may send "update" events prior to receiving all "add" events
|
for (let serverId = 0; serverId < payload.updates.length; serverId++) {
|
||||||
// A server has only been added once it's ServerRegistration is defined
|
// The backend may send "update" events prior to receiving all "add" events
|
||||||
// Checking undefined protects from this race condition
|
// A server has only been added once it's ServerRegistration is defined
|
||||||
const serverRegistration = this._app.serverRegistry.getServerRegistration(payload.serverId)
|
// Checking undefined protects from this race condition
|
||||||
|
const serverRegistration = this._app.serverRegistry.getServerRegistration(serverId)
|
||||||
|
const serverUpdate = payload.updates[serverId]
|
||||||
|
|
||||||
if (serverRegistration) {
|
if (serverRegistration) {
|
||||||
serverRegistration.updateServerStatus(payload, false, this._app.publicConfig.minecraftVersions)
|
serverRegistration.updateServerStatus(serverUpdate, payload.timestamp, false, this._app.publicConfig.minecraftVersions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use update payloads to conditionally append data to graph
|
// Use update payloads to conditionally append data to graph
|
||||||
// Skip any incoming updates if the graph is disabled
|
// Skip any incoming updates if the graph is disabled
|
||||||
if (payload.updateHistoryGraph && this._app.graphDisplayManager.isVisible) {
|
if (serverUpdate.updateHistoryGraph && this._app.graphDisplayManager.isVisible) {
|
||||||
// Update may not be successful, safely append 0 points
|
// Update may not be successful, safely append 0 points
|
||||||
const playerCount = payload.result ? payload.result.players.online : 0
|
const playerCount = serverUpdate.result ? serverUpdate.result.players.online : 0
|
||||||
|
|
||||||
this._app.graphDisplayManager.addGraphPoint(serverRegistration.serverId, payload.timestamp, playerCount)
|
this._app.graphDisplayManager.addGraphPoint(serverRegistration.serverId, payload.timestamp, playerCount)
|
||||||
|
|
||||||
// Only redraw the graph if not mutating hidden data
|
// Only redraw the graph if not mutating hidden data
|
||||||
if (serverRegistration.isVisible) {
|
if (serverRegistration.isVisible) {
|
||||||
this._app.graphDisplayManager.requestRedraw()
|
this._app.graphDisplayManager.requestRedraw()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
70
lib/ping.js
70
lib/ping.js
@ -97,6 +97,40 @@ class PingController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pingAll = () => {
|
pingAll = () => {
|
||||||
|
const timestamp = new Date().getTime()
|
||||||
|
|
||||||
|
this.startPingTasks(results => {
|
||||||
|
const updates = []
|
||||||
|
|
||||||
|
for (const serverRegistration of this._app.serverRegistrations) {
|
||||||
|
const result = results[serverRegistration.serverId]
|
||||||
|
|
||||||
|
// Log to database if enabled
|
||||||
|
if (config.logToDatabase) {
|
||||||
|
const playerCount = result.resp ? result.resp.players.online : 0
|
||||||
|
this._app.database.insertPing(serverRegistration.data.ip, timestamp, playerCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a combined update payload
|
||||||
|
// This includes any modified fields and flags used by the frontend
|
||||||
|
// This will not be cached and can contain live metadata
|
||||||
|
const update = serverRegistration.handlePing(timestamp, result.resp, result.err, result.version)
|
||||||
|
updates[serverRegistration.serverId] = update
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send object since updates uses serverIds as keys
|
||||||
|
// Send a single timestamp entry since it is shared
|
||||||
|
this._app.server.broadcast(MessageOf('updateServers', {
|
||||||
|
timestamp,
|
||||||
|
updates
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
startPingTasks = (callback) => {
|
||||||
|
const results = []
|
||||||
|
let remainingTasks = this._app.serverRegistrations.length
|
||||||
|
|
||||||
for (const serverRegistration of this._app.serverRegistrations) {
|
for (const serverRegistration of this._app.serverRegistrations) {
|
||||||
const version = serverRegistration.getNextProtocolVersion()
|
const version = serverRegistration.getNextProtocolVersion()
|
||||||
|
|
||||||
@ -105,36 +139,18 @@ class PingController {
|
|||||||
logger.log('error', 'Failed to ping %s: %s', serverRegistration.data.ip, err.message)
|
logger.log('error', 'Failed to ping %s: %s', serverRegistration.data.ip, err.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handlePing(serverRegistration, resp, err, version)
|
results[serverRegistration.serverId] = {
|
||||||
|
resp,
|
||||||
|
err,
|
||||||
|
version
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--remainingTasks === 0) {
|
||||||
|
callback(results)
|
||||||
|
}
|
||||||
}, version.protocolId)
|
}, version.protocolId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePing (serverRegistration, resp, err, version) {
|
|
||||||
const timestamp = new Date().getTime()
|
|
||||||
|
|
||||||
serverRegistration.addPing(timestamp, resp)
|
|
||||||
|
|
||||||
let updateHistoryGraph = false
|
|
||||||
|
|
||||||
if (config.logToDatabase) {
|
|
||||||
const playerCount = resp ? resp.players.online : 0
|
|
||||||
|
|
||||||
// Log to database
|
|
||||||
this._app.database.insertPing(serverRegistration.data.ip, timestamp, playerCount)
|
|
||||||
|
|
||||||
if (serverRegistration.addGraphPoint(resp !== undefined, playerCount, timestamp)) {
|
|
||||||
updateHistoryGraph = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a combined update payload
|
|
||||||
// This includes any modified fields and flags used by the frontend
|
|
||||||
// This will not be cached and can contain live metadata
|
|
||||||
const updateMessage = serverRegistration.getUpdate(timestamp, resp, err, version, updateHistoryGraph)
|
|
||||||
|
|
||||||
this._app.server.broadcast(MessageOf('updateServer', updateMessage))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = PingController
|
module.exports = PingController
|
||||||
|
@ -14,12 +14,30 @@ class ServerRegistration {
|
|||||||
this._pingHistory = []
|
this._pingHistory = []
|
||||||
}
|
}
|
||||||
|
|
||||||
getUpdate (timestamp, resp, err, version, updateHistoryGraph) {
|
handlePing (timestamp, resp, err, version) {
|
||||||
const update = {
|
// Store into in-memory ping data
|
||||||
serverId: this.serverId,
|
this.addPing(timestamp, resp)
|
||||||
timestamp: timestamp
|
|
||||||
|
// Only notify the frontend to append to the historical graph
|
||||||
|
// if both the graphing behavior is enabled and the backend agrees
|
||||||
|
// that the ping is eligible for addition
|
||||||
|
let updateHistoryGraph = false
|
||||||
|
|
||||||
|
if (config.logToDatabase) {
|
||||||
|
const playerCount = resp ? resp.players.online : 0
|
||||||
|
|
||||||
|
if (this.addGraphPoint(resp !== undefined, playerCount, timestamp)) {
|
||||||
|
updateHistoryGraph = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delegate out update payload generation
|
||||||
|
return this.getUpdate(timestamp, resp, err, version, updateHistoryGraph)
|
||||||
|
}
|
||||||
|
|
||||||
|
getUpdate (timestamp, resp, err, version, updateHistoryGraph) {
|
||||||
|
const update = {}
|
||||||
|
|
||||||
if (resp) {
|
if (resp) {
|
||||||
if (resp.version && this.updateProtocolVersionCompat(resp.version, version.protocolId, version.protocolIndex)) {
|
if (resp.version && this.updateProtocolVersionCompat(resp.version, version.protocolId, version.protocolIndex)) {
|
||||||
// Append an updated version listing
|
// Append an updated version listing
|
||||||
|
Loading…
Reference in New Issue
Block a user