feat: machine performance indicators

This commit is contained in:
José Oliveira 2021-07-16 03:22:47 +01:00 committed by Josh Harvey
parent 9896b44178
commit 1a166bc279
9 changed files with 189 additions and 23 deletions

View file

@ -1,5 +1,7 @@
const _ = require('lodash/fp')
const pgp = require('pg-promise')()
const axios = require('axios')
const uuid = require('uuid')
const db = require('./db')
const pairing = require('./pairing')
@ -39,11 +41,14 @@ function getMachineNames (config) {
const unresponsiveStatus = { label: 'Unresponsive', type: 'error' }
const stuckStatus = { label: 'Stuck', type: 'error' }
return Promise.all([getMachines(), getConfig(config)])
.then(([machines, config]) => Promise.all(
[machines, checkPings(machines), dbm.machineEvents(), config]
return Promise.all([getMachines(), getConfig(config), getNetworkHeartbeat(), getNetworkPerformance()])
.then(([rawMachines, config, heartbeat, performance]) => Promise.all(
[rawMachines, checkPings(rawMachines), dbm.machineEvents(), config, heartbeat, performance]
))
.then(([machines, pings, events, config]) => {
.then(([rawMachines, pings, events, config, heartbeat, performance]) => {
const mergeByDeviceId = (x, y) => _.values(_.merge(_.keyBy('deviceId', x), _.keyBy('deviceId', y)))
const machines = mergeByDeviceId(mergeByDeviceId(rawMachines, heartbeat), performance)
const getStatus = (ping, stuck) => {
if (ping && ping.age) return unresponsiveStatus
@ -66,7 +71,6 @@ function getMachineNames (config) {
return _.assign(r, { cashOut, statuses })
}
return _.map(addName, machines)
})
}
@ -143,4 +147,56 @@ function setMachine (rec) {
}
}
module.exports = { getMachineName, getMachines, getMachine, getMachineNames, setMachine }
function updateNetworkPerformance (deviceId, data) {
const downloadSpeed = _.head(data)
const dbData = {
device_id: deviceId,
download_speed: downloadSpeed.speed,
created: new Date()
}
const cs = new pgp.helpers.ColumnSet(['device_id', 'download_speed', 'created'],
{ table: 'machine_network_performance' })
const onConflict = ' ON CONFLICT (device_id) DO UPDATE SET ' +
cs.assignColumns({ from: 'EXCLUDED', skip: ['device_id'] })
const upsert = pgp.helpers.insert(dbData, cs) + onConflict
return db.none(upsert)
}
function updateNetworkHeartbeat (deviceId, data) {
const avgResponseTime = _.meanBy(e => _.toNumber(e.averageResponseTime), data)
const avgPacketLoss = _.meanBy(e => _.toNumber(e.packetLoss), data)
const dbData = {
id: uuid.v4(),
device_id: deviceId,
average_response_time: avgResponseTime,
average_packet_loss: avgPacketLoss
}
const sql = pgp.helpers.insert(dbData, null, 'machine_network_heartbeat')
return db.none(sql)
}
function getNetworkPerformance () {
const sql = `SELECT device_id, download_speed FROM machine_network_performance`
return db.manyOrNone(sql)
.then(res => _.map(_.mapKeys(_.camelCase))(res))
}
function getNetworkHeartbeat () {
const sql = `SELECT AVG(average_response_time) AS response_time, AVG(average_packet_loss) AS packet_loss, device_id
FROM machine_network_heartbeat
GROUP BY device_id`
return db.manyOrNone(sql)
.then(res => _.map(_.mapKeys(_.camelCase))(res))
}
module.exports = {
getMachineName,
getMachines,
getMachine,
getMachineNames,
setMachine,
updateNetworkPerformance,
updateNetworkHeartbeat,
getNetworkPerformance,
getNetworkHeartbeat
}

View file

@ -19,6 +19,9 @@ const typeDef = gql`
cassette2: Int
statuses: [MachineStatus]
latestEvent: MachineEvent
downloadSpeed: String
responseTime: String
packetLoss: String
}
type MachineEvent {

View file

@ -289,6 +289,23 @@ function plugins (settings, deviceId) {
])
}
function pruneMachinesHeartbeat () {
const sql = `DELETE
FROM
machine_network_heartbeat h
USING (SELECT
device_id,
max(created) as lastEntry
FROM
machine_network_heartbeat
GROUP BY
device_id) d
WHERE
d.device_id = h.device_id
AND h.created < d.lastEntry`
db.none(sql)
}
function isHd (tx) {
return wallet.isHd(settings, tx)
}
@ -795,7 +812,8 @@ function plugins (settings, deviceId) {
sell,
getNotificationConfig,
notifyOperator,
fetchCurrentConfigVersion
fetchCurrentConfigVersion,
pruneMachinesHeartbeat
}
}

View file

@ -24,6 +24,7 @@ const LOGS_CLEAR_INTERVAL = 1 * T.day
const SANCTIONS_INITIAL_DOWNLOAD_INTERVAL = 5 * T.minutes
const SANCTIONS_UPDATE_INTERVAL = 1 * T.week
const RADAR_UPDATE_INTERVAL = 5 * T.minutes
const PRUNE_MACHINES_HEARBEAT = 1 * T.day
const CHECK_NOTIFICATION_INTERVAL = 20 * T.seconds
@ -102,6 +103,7 @@ function start (__settings) {
setInterval(initialSanctionsDownload, SANCTIONS_INITIAL_DOWNLOAD_INTERVAL)
setInterval(updateAndLoadSanctions, SANCTIONS_UPDATE_INTERVAL)
setInterval(updateCoinAtmRadar, RADAR_UPDATE_INTERVAL)
setInterval(() => pi().pruneMachinesHeartbeat(), PRUNE_MACHINES_HEARBEAT)
}
module.exports = { start, reload }

View file

@ -1,25 +1,17 @@
const express = require('express')
const router = express.Router()
const { getMachine } = require('../machine-loader')
const { updateNetworkHeartbeat, updateNetworkPerformance } = require('../machine-loader')
function networkHeartbeat (req, res, next) {
return getMachine(req.deviceId)
.then(machine => {
console.log(`${machine.name} network heartbeat:`)
console.log(req.body)
return res.status(200).send({ status: 'OK' })
})
return updateNetworkHeartbeat(req.deviceId, req.body)
.then(() => res.status(200).send({ status: 'OK' }))
.catch(next)
}
function networkPerformance (req, res, next) {
return getMachine(req.deviceId)
.then(machine => {
console.log(`${machine.name} network performance:`)
console.log(req.body)
return res.status(200).send({ status: 'OK' })
})
return updateNetworkPerformance(req.deviceId, req.body)
.then(() => res.status(200).send({ status: 'OK' }))
.catch(next)
}