From 6ae07bb480d287cf9f0590c1f028c2e15d2ff1df Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 5 Jul 2022 11:48:40 +0200 Subject: [PATCH] Allow accounts server to trigger quota updates --- lib/commands/quota.js | 87 +++++++++++++++++++++++++++++++++++-------- lib/env.js | 1 + lib/rpc.js | 19 ++++++++-- server.js | 8 ++++ 4 files changed, 96 insertions(+), 19 deletions(-) diff --git a/lib/commands/quota.js b/lib/commands/quota.js index 1bf9203f6..9be965407 100644 --- a/lib/commands/quota.js +++ b/lib/commands/quota.js @@ -5,6 +5,7 @@ const Quota = module.exports; //const Util = require("../common-util"); const Keys = require("../keys"); const Https = require("https"); +const Http = require("http"); const Util = require("../common-util"); const Stats = require("../stats"); @@ -135,8 +136,6 @@ var queryAccountServer = function (Env, cb) { try { var json = JSON.parse(str); checkUpdateAvailability(Env, json); - // don't overwrite the limits with junk data - if (json && json.message === 'EINVAL') { return void cb(); } done(void 0, json); } catch (e) { done(e); @@ -144,22 +143,12 @@ var queryAccountServer = function (Env, cb) { }); }); - req.on('error', function (e) { - Quota.applyCustomLimits(Env); - if (!Env.myDomain) { return done(); } - // only return an error if your server allows subscriptions - done(e); + req.on('error', function () { + done(); }); req.end(body); }; - -Quota.queryAccountServer = function (Env, cb) { - Env.batchAccountQuery('', cb, function (done) { - queryAccountServer(Env, done); - }); -}; - Quota.shouldContactServer = function (Env) { return !(Env.blockDailyCheck === true || ( @@ -169,14 +158,80 @@ Quota.shouldContactServer = function (Env) { ) ); }; +Quota.pingAccountsDaily = function (Env, _cb) { + var cb = Util.mkAsync(_cb); + if (!Quota.shouldContactServer(Env)) { return void cb(); } + queryAccountServer(Env, function (err) { + cb(err); + }); +}; +var queryQuotaServer = function (Env, cb) { + var done = Util.once(Util.mkAsync(cb)); + + var rawBody = Stats.instanceData(Env); + Env.Log.info("QUOTA_UPDATE", rawBody); + var body = JSON.stringify(rawBody); + + var options = { + host: Env.quota_api, + path: '/api/getquota', + method: 'POST', + headers: { + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(body) + } + }; + + var H = Https; + + if (Env.quota_api === 'localhost:3002') { + H = Http; + options.host = 'localhost'; + options.port = 3002; + } + + var req = H.request(options, function (response) { + if (!('' + response.statusCode).match(/^2\d\d$/)) { + return void cb('SERVER ERROR ' + response.statusCode); + } + var str = ''; + + response.on('data', function (chunk) { + str += chunk; + }); + + response.on('end', function () { + try { + var json = JSON.parse(str); + // don't overwrite the limits with junk data + if (json && json.message === 'EINVAL') { return void done(); } + done(void 0, json); + } catch (e) { + done(e); + } + }); + }); + + req.on('error', function (e) { + Quota.applyCustomLimits(Env); + done(e); + }); + + req.end(body); +}; +Quota.queryQuotaServer = function (Env, cb) { + Env.batchAccountQuery('', cb, function (done) { + queryQuotaServer(Env, done); + }); +}; Quota.updateCachedLimits = function (Env, _cb) { var cb = Util.mkAsync(_cb); Quota.applyCustomLimits(Env); - if (!Quota.shouldContactServer(Env)) { return void cb(); } - Quota.queryAccountServer(Env, function (err, json) { + if (!Env.allowSubscriptions && !Env.quota_api) { return void cb(); } + Quota.queryQuotaServer(Env, function (err, json) { if (err) { return void cb(err); } if (!json) { return void cb(); } diff --git a/lib/env.js b/lib/env.js index bb32f88c0..b226ba893 100644 --- a/lib/env.js +++ b/lib/env.js @@ -74,6 +74,7 @@ module.exports.create = function (config) { NO_SANDBOX: NO_SANDBOX, httpSafePort: httpSafePort, accounts_api: config.accounts_api || undefined, // this simplifies integration with an accounts page + quota_api: config.quota_api || undefined, // hourly check quota shouldUpdateNode: !isRecentVersion(), diff --git a/lib/rpc.js b/lib/rpc.js index 52f5c315a..14f89615f 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -189,7 +189,18 @@ var rpc = function (Env, Server, userId, data, respond) { RPC.create = function (Env, cb) { var Sessions = Env.Sessions; - var updateLimitDaily = function () { + + var pingAccountsDaily = function () { + Quota.pingAccountsDaily(Env, function (e) { + if (e) { + Env.WARN('dailyPing', e); + } + }); + }; + pingAccountsDaily(); + Env.intervals.dailyPing = setInterval(pingAccountsDaily, 24*3600*1000); + + var updateLimitInterval = function () { Quota.updateCachedLimits(Env, function (e) { if (e) { Env.WARN('limitUpdate', e); @@ -197,8 +208,10 @@ RPC.create = function (Env, cb) { }); }; Quota.applyCustomLimits(Env); - updateLimitDaily(); - Env.intervals.dailyLimitUpdate = setInterval(updateLimitDaily, 24*3600*1000); + updateLimitInterval(); + if (Env.quota_api) { + Env.intervals.quotaUpdate = setInterval(updateLimitInterval, 3600*1000); + } // expire old sessions once per minute Env.intervals.sessionExpirationInterval = setInterval(function () { diff --git a/server.js b/server.js index 3830a1fbc..2b9f7b92b 100644 --- a/server.js +++ b/server.js @@ -262,6 +262,14 @@ var serveBroadcast = makeRouteCache(function (host) { app.get('/api/config', serveConfig); app.get('/api/broadcast', serveBroadcast); +app.get('/api/updatequota', function (req, res) { + var Quota = require("./lib/commands/quota"); + Quota.updateCachedLimits(Env, (e) => { + if (e) { return res.status(500).send({error: 'Internal server error'}); } + res.send(); + }); +}); + var define = function (obj) { return `define(function (){ return ${JSON.stringify(obj, null, '\t')};