Files
factorio-clusterio/sharedPlugins/clusterioMod/routes.js
T
Hornwitser f700e98e8e Remove old statistics code
Remove left over code from the old statistics gathering and display
which was replaced with Prometheus+Grafana.
2019-12-22 00:54:45 +01:00

209 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const express = require("express");
const path = require("path");
const authenticate = require("lib/authenticate");
const dole = require("./dole");
function addWebRoutes(app) {
app.use('/clusterioMod', express.static(path.join(__dirname, 'static')));
app.get('/clusterioMod/storage', (req, res) => { res.render('clusterioMod/views/storage'); });
}
function addApiRoutes(
app, config, db, items, Prometheus, prometheusPrefix, endpointHitCounter,
) {
const prometheusExportGauge = new Prometheus.Gauge({
name: prometheusPrefix+'export_gauge',
help: 'Items exported by instance',
labelNames: ["instanceID", "itemName"],
});
const prometheusImportGauge = new Prometheus.Gauge({
name: prometheusPrefix+'import_gauge',
help: 'Items imported by instance',
labelNames: ["instanceID", "itemName"],
});
const prometheusDoleFactorGauge = new Prometheus.Gauge({
name: prometheusPrefix+'dole_factor_gauge',
help: 'The current dole division factor for this item',
labelNames: ["itemName"],
});
// Only initialize neural network when it's enabled, otherwise it might override gauge
let neuralDole;
if(config.useNeuralNetDoleDivider) {
neuralDole=new dole.neuralDole({
db, gaugePrefix: prometheusPrefix
});
}
/**
* POST endpoint for storing items in master's inventory.
* @memberof clusterioMaster
* @instance
* @alias api/place
* @param {itemStack} itemStack the number and type of items to store (see typedef)
* @param {string} [itemStack.instanceID="unknown"]
* the unique/instanceID which is a numerical value for an instance
* @param {string} [itemStack.instanceName="unknown"]
* the name of an instance for identification in statistics, as
* provided when launching it. ex node client start [name]
* @returns {string} status either "success" or "failure"
*/
app.post("/api/place", authenticate.middleware, function(req, res) {
endpointHitCounter.labels(req.route.path).inc();
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
let x;
try {
x = JSON.parse(req.body);
} catch (e) {
x = req.body;
}
if(!x.instanceName) {
x.instanceName = "unknown";
}
if(!x.instanceID) {
x.instanceID = "unknown";
for (let [instanceID, slave] of db.slaves) {
if(slave.instanceName == req.body.instanceName) {
x.instanceID = instanceID;
break;
}
}
}
if(x.instanceID
&& x.instanceName
&& !isNaN(Number(x.count))
&& x.name
&& typeof x.name == "string"){
if(config.logItemTransfers){
console.log("added: " + req.body.name + " " + req.body.count+" from "+x.instanceName+" ("+x.instanceID+")");
}
// gather statistics
prometheusExportGauge.labels(x.instanceID, req.body.name).inc(Number(req.body.count) || 0);
// save items we get
var count = Number(req.body.count);
items.addItem(req.body.name, count);
// Attempt confirming
res.send("success");
} else {
res.send("failure");
}
});
/**
* POST endpoint to remove items from DB when client orders items.
*
* @memberof clusterioMaster
* @instance
* @alias api/remove
* @param {itemStack} itemStack the name of and the number of items to remove (see typedef)
* @param {string} [itemStack.instanceID="unknown"]
* the unique/instanceID which is a numerical value for an instance
* @param {string} [itemStack.instanceName="unknown"]
* the name of an instance for identification in statistics, as
* provided when launching it. ex node client start [name]
* @returns {itemStack}
* the number of items actually removed, may be lower than what was
* asked for due to shortages.
*/
app.post("/api/remove", authenticate.middleware, function(req, res) {
endpointHitCounter.labels(req.route.path).inc();
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// save items we get
var object = req.body;
if(!object.instanceID) {
object.instanceID = "unknown"
}
if(!object.instanceName) {
object.instanceName = "unknown";
}
if (db.slaves.has(String(object.instanceID))) {
object.instanceName = db.slaves.get(String(object.instanceID)).instanceName;
}
let itemCount = items.getItemCount(object.name);
if (
(config.disableImportsOfEverythingExceptElectricity === true || config.disableImportsOfEverythingExceptElectricity === "true" )
&& object.name != "electricity"
) {
if(config.logItemTransfers){
console.log('failure could not find ' + object.name);
}
res.send({name:object.name, count:0});
} else if(config.disableFairItemDistribution){
// Give out as much items as possible until there are 0 left. This might lead to one slave getting all the items and the rest nothing.
let numberToRemove = Math.min(Math.abs(Number(object.count)),itemCount);
items.removeItem(object.name, numberToRemove);
res.send({count: numberToRemove, name: object.name});
// track statistics and do graphing things
prometheusImportGauge.labels(object.instanceID, object.name).inc(Number(numberToRemove) || 0);
} else if(config.useNeuralNetDoleDivider){
// use fancy neural net to calculate a "fair" dole division rate.
neuralDole.divider({
res,
object,
config,
prometheusImportGauge
})
} else {
// Use dole division. Makes it really slow to drain out the last little bit.
dole.doleDivider({
itemCount,
object,
db,
config,
prometheusDoleFactorGauge,
prometheusImportGauge,
req,res,
})
}
});
/**
* GET endpoint to read the masters current inventory of items.
*
* @memberof clusterioMaster
* @instance
* @alias api/inventory
* @returns {object[]} JSON [{name:"iron-plate", count:100},{name:"copper-plate",count:5}]
*/
app.get("/api/inventory", function(req, res) {
endpointHitCounter.labels(req.route.path).inc();
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// Check it and send it
var inventory = [];
for (let [name, count] of items._items) {
inventory.push({ name, count });
}
res.send(JSON.stringify(inventory));
});
/**
* GET endpoint to read the masters inventory as an object with key:value pairs
*
* @memberof clusterioMaster
* @instance
* @alias api/inventoryAsObject
* @returns {object} JSON {"iron-plate":100, "copper-plate":5}
*/
app.get("/api/inventoryAsObject", function(req, res) {
endpointHitCounter.labels(req.route.path).inc();
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// Check it and send it
res.send(JSON.stringify(items.serialise()));
});
}
module.exports = {
addWebRoutes,
addApiRoutes,
}