mirror of
https://github.com/lovasoa/whitebophir
synced 2024-11-10 14:34:20 +00:00
add statsd monitoring
wbo is now more observable
This commit is contained in:
parent
55acf500d0
commit
fcc97f58b5
8 changed files with 3370 additions and 3276 deletions
13
README.md
13
README.md
|
@ -90,3 +90,16 @@ Some important environment variables are :
|
|||
## Troubleshooting
|
||||
|
||||
If you experience an issue or want to propose a new feature in WBO, please [open a github issue](https://github.com/lovasoa/whitebophir/issues/new).
|
||||
|
||||
## Monitoring
|
||||
|
||||
If you are self-hosting a WBO instance, you may want to monitor its load,
|
||||
the number of connected users, and different metrics.
|
||||
|
||||
You can start WBO with the `STATSD_URL` to send it to a statsd-compatible
|
||||
metrics collection agent.
|
||||
|
||||
Example: `docker run -e STATSD_URL=udp://127.0.0.1:8125 lovasoa/wbo`.
|
||||
|
||||
- If you use **prometheus**, you can collect the metrics with [statsd-exporter](https://hub.docker.com/r/prom/statsd-exporter).
|
||||
- If you use **datadog**, you can collect the metrics with [dogstatsd](https://docs.datadoghq.com/developers/dogstatsd).
|
87
package-lock.json
generated
87
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "whitebophir",
|
||||
"version": "1.11.0",
|
||||
"version": "1.14.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -797,9 +797,9 @@
|
|||
}
|
||||
},
|
||||
"es-abstract": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz",
|
||||
"integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==",
|
||||
"version": "1.18.3",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
|
||||
"integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
|
@ -810,14 +810,14 @@
|
|||
"has-symbols": "^1.0.2",
|
||||
"is-callable": "^1.2.3",
|
||||
"is-negative-zero": "^2.0.1",
|
||||
"is-regex": "^1.1.2",
|
||||
"is-string": "^1.0.5",
|
||||
"object-inspect": "^1.9.0",
|
||||
"is-regex": "^1.1.3",
|
||||
"is-string": "^1.0.6",
|
||||
"object-inspect": "^1.10.3",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.2",
|
||||
"string.prototype.trimend": "^1.0.4",
|
||||
"string.prototype.trimstart": "^1.0.4",
|
||||
"unbox-primitive": "^1.0.0"
|
||||
"unbox-primitive": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"object.assign": {
|
||||
|
@ -1334,12 +1334,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-boolean-object": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz",
|
||||
"integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
|
||||
"integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.0"
|
||||
"call-bind": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-buffer": {
|
||||
|
@ -1355,9 +1355,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-date-object": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.3.tgz",
|
||||
"integrity": "sha512-tDpEUInNcy2Yw3lNSepK3Wdw1RnXLcIVienz6Ou631Acl15cJyRWK4dgA1vCmOEgIbtOV0W7MHg+AR2Gdg1NXQ==",
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz",
|
||||
"integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
|
@ -1379,9 +1379,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-number-object": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz",
|
||||
"integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
|
||||
"integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
|
||||
"dev": true
|
||||
},
|
||||
"is-plain-obj": {
|
||||
|
@ -1397,13 +1397,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
|
||||
"integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
|
||||
"integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-symbols": "^1.0.1"
|
||||
"has-symbols": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-retry-allowed": {
|
||||
|
@ -1419,18 +1419,18 @@
|
|||
"dev": true
|
||||
},
|
||||
"is-string": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
|
||||
"integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
|
||||
"integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
|
||||
"dev": true
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
|
||||
"integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
|
||||
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.1"
|
||||
"has-symbols": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
|
@ -1922,9 +1922,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"nightwatch": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.6.3.tgz",
|
||||
"integrity": "sha512-otVr+YUmtXcj7aG14GfkuCMUOpuJfSOVvsTxQiSRmO3rSfclOWglE6jaCmyMiHMYNwy/LPp86PXJFD5pzMo/wA==",
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.6.4.tgz",
|
||||
"integrity": "sha512-3Ivb8TVjM9GHYwN0Ixi0CK+5hznRLsY7iiY1CBmdRi01ofx3a6glVvbrhsfOshwN3ai/tTaJ2D9taQGZ05wy3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assertion-error": "^1.1.0",
|
||||
|
@ -1984,9 +1984,9 @@
|
|||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz",
|
||||
"integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==",
|
||||
"version": "1.10.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
|
||||
"integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
|
||||
"dev": true
|
||||
},
|
||||
"object-keys": {
|
||||
|
@ -2294,9 +2294,9 @@
|
|||
}
|
||||
},
|
||||
"polyfill-library": {
|
||||
"version": "3.104.0",
|
||||
"resolved": "https://registry.npmjs.org/polyfill-library/-/polyfill-library-3.104.0.tgz",
|
||||
"integrity": "sha512-sYbO07WkGKSub4HxUKK/8eYSxV/HS4xOUcexmV/zBl6Ma2JJypKWk1xgbcZi2Gs4CmPrZIpfGhdPK1aFXjJKtQ==",
|
||||
"version": "3.105.0",
|
||||
"resolved": "https://registry.npmjs.org/polyfill-library/-/polyfill-library-3.105.0.tgz",
|
||||
"integrity": "sha512-Bt10kl+5I/k+F8U0/HYEw2RiHUyUYGz7KtzwhPVltngxcJjzm0pWTQi2Z8pYMI5ahE5B5WZv8CXgCVDxz/H4UA==",
|
||||
"requires": {
|
||||
"@financial-times/polyfill-useragent-normaliser": "^1.7.0",
|
||||
"@formatjs/intl-datetimeformat": "3.2.9",
|
||||
|
@ -2788,6 +2788,11 @@
|
|||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"statsd-client": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/statsd-client/-/statsd-client-0.4.7.tgz",
|
||||
"integrity": "sha512-+sGCE6FednJ/vI7vywErOg/mhVqmf6Zlktz7cdGRnF/cQWXD9ifMgtqU1CIIXmhSwm11SCk4zDN+bwNCvIR/Kg=="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
|
@ -3192,9 +3197,9 @@
|
|||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
|
||||
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
|
||||
"version": "7.4.5",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz",
|
||||
"integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g=="
|
||||
},
|
||||
"xregexp": {
|
||||
"version": "2.0.0",
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
"accept-language-parser": "^1.5.0",
|
||||
"async-mutex": "^0.3.1",
|
||||
"handlebars": "^4.7.7",
|
||||
"polyfill-library": "^3.104.0",
|
||||
"polyfill-library": "^3.105.0",
|
||||
"serve-static": "^1.14.1",
|
||||
"socket.io": "^3.1.2"
|
||||
"socket.io": "^3.1.2",
|
||||
"statsd-client": "^0.4.7"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node ./server/server.js",
|
||||
|
@ -26,6 +27,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"geckodriver": "^1.22.3",
|
||||
"nightwatch": "^1.6.3"
|
||||
"nightwatch": "^1.6.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ class BoardData {
|
|||
// empty board
|
||||
try {
|
||||
await fs.promises.unlink(file);
|
||||
log("removed empty board", { name: this.name });
|
||||
log("removed empty board", { board: this.name });
|
||||
} catch (err) {
|
||||
if (err.code !== "ENOENT") {
|
||||
// If the file already wasn't saved, this is not an error
|
||||
|
@ -227,12 +227,13 @@ class BoardData {
|
|||
await fs.promises.writeFile(tmp_file, board_txt, { flag: "wx" });
|
||||
await fs.promises.rename(tmp_file, file);
|
||||
log("saved board", {
|
||||
name: this.name,
|
||||
board: this.name,
|
||||
size: board_txt.length,
|
||||
delay_ms: Date.now() - this.lastSaveDate,
|
||||
});
|
||||
} catch (err) {
|
||||
log("board saving error", {
|
||||
board: this.name,
|
||||
err: err.toString(),
|
||||
tmp_file: tmp_file,
|
||||
});
|
||||
|
|
|
@ -47,5 +47,11 @@ module.exports = {
|
|||
|
||||
/** Automatically switch to White-out on finger touch after drawing
|
||||
with Pencil using a stylus. Only supported on iPad with Apple Pencil. */
|
||||
AUTO_FINGER_WHITEOUT: process.env['AUTO_FINGER_WHITEOUT'] !== "disabled",
|
||||
AUTO_FINGER_WHITEOUT: process.env["AUTO_FINGER_WHITEOUT"] !== "disabled",
|
||||
|
||||
/** If this variable is set, it should point to a statsd listener that will
|
||||
* receive WBO's monitoring information.
|
||||
* example: udp://127.0.0.1
|
||||
*/
|
||||
STATSD_URL: process.env["STATSD_URL"],
|
||||
};
|
||||
|
|
|
@ -1,3 +1,40 @@
|
|||
const config = require("./configuration.js"),
|
||||
SDC = require("statsd-client");
|
||||
|
||||
/**
|
||||
* Parse a statsd connection string
|
||||
* @param {string} url
|
||||
* @returns {SDC.TcpOptions|SDC.UdpOptions}
|
||||
*/
|
||||
function parse_statsd_url(url) {
|
||||
const regex = /^(tcp|udp|statsd):\/\/(.*):(\d+)$/;
|
||||
const match = url.match(regex);
|
||||
if (!match)
|
||||
throw new Error("Invalid statsd connection string, doesn't match " + regex);
|
||||
const [_, protocol, host, port_str] = match;
|
||||
const tcp = protocol !== "udp";
|
||||
const port = parseInt(port_str);
|
||||
return { tcp, host, port, prefix: "wbo" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Statsd client to which metrics will be reported
|
||||
* @type {SDC | null}
|
||||
* */
|
||||
let statsd = null;
|
||||
|
||||
if (config.STATSD_URL) {
|
||||
const options = parse_statsd_url(config.STATSD_URL);
|
||||
console.log("Exposing metrics on statsd server: " + JSON.stringify(options));
|
||||
statsd = new SDC(options);
|
||||
}
|
||||
|
||||
if (statsd) {
|
||||
setInterval(function reportHealth(){
|
||||
statsd.gauge('memory', process.memoryUsage().heapUsed);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message to the logs
|
||||
* @param {string} type
|
||||
|
@ -6,7 +43,33 @@
|
|||
function log(type, infos) {
|
||||
var msg = type;
|
||||
if (infos) msg += "\t" + JSON.stringify(infos);
|
||||
if (statsd) {
|
||||
const tags = {};
|
||||
if (infos.board) tags.board = infos.board;
|
||||
if (infos.original_ip) tags.original_ip = infos.original_ip;
|
||||
statsd.increment(type, 1, tags);
|
||||
}
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
module.exports.log = log;
|
||||
/**
|
||||
* @template {(...args) => any} F
|
||||
* @param {F} f
|
||||
* @returns {F}
|
||||
*/
|
||||
function monitorFunction(f) {
|
||||
if (statsd) return statsd.helpers.wrapCallback(f.name, f);
|
||||
else return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a number
|
||||
* @param {string} name
|
||||
* @param {number} value
|
||||
* @param {{[name:string]: string}=} tags
|
||||
*/
|
||||
function gauge(name, value, tags){
|
||||
if (statsd) statsd.gauge(name, value, tags);
|
||||
}
|
||||
|
||||
module.exports = { log, gauge, monitorFunction };
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
var app = require("http").createServer(handler),
|
||||
sockets = require("./sockets.js"),
|
||||
log = require("./log.js").log,
|
||||
{log, monitorFunction} = require("./log.js"),
|
||||
path = require("path"),
|
||||
url = require("url"),
|
||||
fs = require("fs"),
|
||||
crypto = require("crypto"),
|
||||
serveStatic = require("serve-static"),
|
||||
|
@ -57,7 +56,7 @@ function serveError(request, response) {
|
|||
*/
|
||||
function logRequest(request) {
|
||||
log("connection", {
|
||||
ip: request.connection.remoteAddress,
|
||||
ip: request.socket.remoteAddress,
|
||||
original_ip:
|
||||
request.headers["x-forwarded-for"] || request.headers["forwarded"],
|
||||
user_agent: request.headers["user-agent"],
|
||||
|
@ -72,7 +71,7 @@ function logRequest(request) {
|
|||
*/
|
||||
function handler(request, response) {
|
||||
try {
|
||||
handleRequest(request, response);
|
||||
handleRequestAndLog(request, response);
|
||||
} catch (err) {
|
||||
console.trace(err);
|
||||
response.writeHead(500, { "Content-Type": "text/plain" });
|
||||
|
@ -101,7 +100,7 @@ function validateBoardName(boardName) {
|
|||
* @type {import('http').RequestListener}
|
||||
*/
|
||||
function handleRequest(request, response) {
|
||||
var parsedUrl = url.parse(request.url, true);
|
||||
var parsedUrl = new URL(request.url, 'http://wbo/');
|
||||
var parts = parsedUrl.pathname.split("/");
|
||||
if (parts[0] === "") parts.shift();
|
||||
|
||||
|
@ -110,7 +109,7 @@ function handleRequest(request, response) {
|
|||
// "boards" refers to the root directory
|
||||
if (parts.length === 1) {
|
||||
// '/boards?board=...' This allows html forms to point to boards
|
||||
var boardName = parsedUrl.query.board || "anonymous";
|
||||
var boardName = parsedUrl.searchParams.get("board") || "anonymous";
|
||||
var headers = { Location: "boards/" + encodeURIComponent(boardName) };
|
||||
response.writeHead(301, headers);
|
||||
response.end();
|
||||
|
@ -218,4 +217,5 @@ function handleRequest(request, response) {
|
|||
}
|
||||
}
|
||||
|
||||
const handleRequestAndLog = monitorFunction(handleRequest);
|
||||
module.exports = app;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var iolib = require("socket.io"),
|
||||
log = require("./log.js").log,
|
||||
{ log, gauge, monitorFunction } = require("./log.js"),
|
||||
BoardData = require("./boardData.js").BoardData,
|
||||
config = require("./configuration");
|
||||
|
||||
|
@ -17,9 +17,10 @@ var boards = {};
|
|||
* @returns {A}
|
||||
*/
|
||||
function noFail(fn) {
|
||||
const monitored = monitorFunction(fn);
|
||||
return function noFailWrapped(arg) {
|
||||
try {
|
||||
return fn(arg);
|
||||
return monitored(arg);
|
||||
} catch (e) {
|
||||
console.trace(e);
|
||||
}
|
||||
|
@ -28,7 +29,7 @@ function noFail(fn) {
|
|||
|
||||
function startIO(app) {
|
||||
io = iolib(app);
|
||||
io.on("connection", noFail(socketConnection));
|
||||
io.on("connection", noFail(handleSocketConnection));
|
||||
return io;
|
||||
}
|
||||
|
||||
|
@ -41,6 +42,7 @@ function getBoard(name) {
|
|||
} else {
|
||||
var board = BoardData.load(name);
|
||||
boards[name] = board;
|
||||
gauge("boards in memory", Object.keys(boards).length);
|
||||
return board;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +51,7 @@ function getBoard(name) {
|
|||
* Executes on every new connection
|
||||
* @param {iolib.Socket} socket
|
||||
*/
|
||||
function socketConnection(socket) {
|
||||
function handleSocketConnection(socket) {
|
||||
/**
|
||||
* Function to call when an user joins a board
|
||||
* @param {string} name
|
||||
|
@ -64,6 +66,7 @@ function socketConnection(socket) {
|
|||
var board = await getBoard(name);
|
||||
board.users.add(socket.id);
|
||||
log("board joined", { board: board.name, users: board.users.size });
|
||||
gauge("connected", board.users.size, {board: name});
|
||||
return board;
|
||||
}
|
||||
|
||||
|
@ -141,9 +144,11 @@ function socketConnection(socket) {
|
|||
board.users.delete(socket.id);
|
||||
var userCount = board.users.size;
|
||||
log("disconnection", { board: board.name, users: board.users.size });
|
||||
gauge("connected", userCount, { board: board.name });
|
||||
if (userCount === 0) {
|
||||
board.save();
|
||||
delete boards[room];
|
||||
gauge("boards in memory", Object.keys(boards).length);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue