Created
March 8, 2017 22:37
-
-
Save qix/7df30e967cc4235bcff357f95a1c05aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const WebSocket = require('ws'); | |
const express = require('express'); | |
const http = require('http'); | |
let debug = false; | |
function arrayShiftRight(array) { | |
for (let idx = array.length - 1; idx > 0; idx--) { | |
array[idx] = array[idx - 1]; | |
} | |
array[0] = 0; | |
} | |
const RealtimeBackend = { | |
init(startup_time, statsdConfig, events) { | |
const config = statsdConfig.realtime || {}; | |
const { | |
backendPort, | |
historyLength, | |
allowOrigin, | |
} = config; | |
if (!backendPort || !historyLength) { | |
console.error('Realtime configuration missing backendPort or historyLength'); | |
return false; | |
} | |
const app = express(); | |
const server = http.createServer(app); | |
const wss = new WebSocket.Server({ | |
server, | |
}); | |
server.listen(backendPort, function listening() { | |
console.log('Listening on %d', server.address().port); | |
}); | |
let history = { | |
lastTimestamp: null, | |
counters: {}, | |
gauges: {}, | |
}; | |
app.get('/history', function (req, res) { | |
if (allowOrigin) { | |
res.header('Access-Control-Allow-Origin', allowOrigin); | |
} | |
res.send(history) | |
}) | |
wss.on('connection', function connection(ws) { | |
ws.send(JSON.stringify(Object.assign({ | |
event: 'history', | |
}, history))); | |
}); | |
events.on('flush', (timestamp, stats) => { | |
const counters = Object.assign({}, stats.counters, { | |
random: Math.floor(Math.random() * 10), | |
}); | |
const gauges = {}; | |
for (let key of Object.keys(stats.gauges)) { | |
if (stats.gauges[key] !== history.gauges[key]) { | |
gauges[key] = stats.gauges[key]; | |
history.gauges[key] = stats.gauges[key]; | |
} | |
} | |
// @WARN: Shift counters right once | |
// We don't deal with the problems of time here. Just assume this is | |
// called accurately every `flushInterval` [even though it's not true.] | |
for (let key of Object.keys(history.counters)) { | |
arrayShiftRight(history.counters[key]); | |
} | |
// Add new value to the history | |
for (let key of Object.keys(counters)) { | |
if (!history.counters.hasOwnProperty(key)) { | |
history.counters[key] = new Array(historyLength).fill(0); | |
} | |
history.counters[key][0] = counters[key]; | |
} | |
const data = JSON.stringify({ | |
event: 'update', | |
timestamp, | |
counters, | |
gauges, | |
}); | |
wss.clients.forEach(function each(client) { | |
if (client.readyState === WebSocket.OPEN) { | |
client.send(data); | |
} | |
}); | |
history.lastTimestamp = timestamp; | |
}); | |
return true; | |
}, | |
}; | |
module.exports = RealtimeBackend; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment