From 1282ce359b9297633e8fc2feeccb5a51142da5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Salgado?= Date: Wed, 27 Jul 2022 01:09:47 +0100 Subject: [PATCH] fix: use node-cache --- lib/plugins/wallet/infura/infura.js | 45 +++++++++++++---------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/lib/plugins/wallet/infura/infura.js b/lib/plugins/wallet/infura/infura.js index 7cf9bb60..0b5d702b 100644 --- a/lib/plugins/wallet/infura/infura.js +++ b/lib/plugins/wallet/infura/infura.js @@ -1,4 +1,5 @@ const _ = require('lodash/fp') +const NodeCache = require('node-cache') const base = require('../geth/base') const T = require('../../../time') const { BALANCE_FETCH_SPEED_MULTIPLIER } = require('../../../constants') @@ -16,21 +17,15 @@ function run (account) { base.connect(endpoint) } -const txsCache = {} -setInterval(() => { - _.forEach(it => { - // A transaction not being updated for over an hour means that it stopped being fetched on poll, - // which means that it probably was cancelled by the operator or something else caused the - // transaction to stop being listened to. So, trim the cache to save memory - const lastReq = _.isNil(txsCache[it].lastReqTime) ? Date.now() : new Date(txsCache[it].lastReqTime) - const timePassedSinceReq = Date.now() - lastReq - if (timePassedSinceReq > T.hour) delete txsCache[it] - }, _.keys(txsCache)) -}, T.minute) +const txsCache = new NodeCache({ + stdTTL: T.hour / 1000, + checkperiod: T.minute / 1000, + deleteOnExpire: true +}) function shouldGetStatus (tx) { const timePassedSinceTx = Date.now() - new Date(tx.created) - const timePassedSinceReq = Date.now() - new Date(txsCache[tx.id].lastReqTime) + const timePassedSinceReq = Date.now() - new Date(txsCache.get(tx.id).lastReqTime) // Allow for infura to gradually lower the amount of requests based on the time passed since the transaction // Until first 5 minutes - 1/2 regular polling speed @@ -40,33 +35,33 @@ function shouldGetStatus (tx) { // Until first four hours - 1/16 polling speed // Until first day - 1/24 polling speed // After first day - 1/32 polling speed - if (timePassedSinceTx < 5 * T.minutes) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 2 * REGULAR_TX_POLLING - if (timePassedSinceTx < 10 * T.minutes) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 4 * REGULAR_TX_POLLING - if (timePassedSinceTx < 1 * T.hour) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 8 * REGULAR_TX_POLLING - if (timePassedSinceTx < 2 * T.hours) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 12 * REGULAR_TX_POLLING - if (timePassedSinceTx < 4 * T.hours) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 16 * REGULAR_TX_POLLING - if (timePassedSinceTx < 1 * T.day) return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 24 * REGULAR_TX_POLLING - return _.isNil(txsCache[tx.id].res) || timePassedSinceReq > 32 * REGULAR_TX_POLLING + if (timePassedSinceTx < 5 * T.minutes) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 2 * REGULAR_TX_POLLING + if (timePassedSinceTx < 10 * T.minutes) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 4 * REGULAR_TX_POLLING + if (timePassedSinceTx < 1 * T.hour) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 8 * REGULAR_TX_POLLING + if (timePassedSinceTx < 2 * T.hours) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 12 * REGULAR_TX_POLLING + if (timePassedSinceTx < 4 * T.hours) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 16 * REGULAR_TX_POLLING + if (timePassedSinceTx < 1 * T.day) return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 24 * REGULAR_TX_POLLING + return _.isNil(txsCache.get(tx.id).res) || timePassedSinceReq > 32 * REGULAR_TX_POLLING } // Override geth's getStatus function to allow for different polling timing function getStatus (account, tx, requested, settings, operatorId) { - if (_.isNil(txsCache[tx.id])) { - txsCache[tx.id] = { lastReqTime: Date.now() } + if (_.isNil(txsCache.get(tx.id))) { + txsCache.set(tx.id, { lastReqTime: Date.now() }) } // return last available response if (!shouldGetStatus(tx)) { - return Promise.resolve(txsCache[tx.id].res) + return Promise.resolve(txsCache.get(tx.id).res) } return base.getStatus(account, tx, requested, settings, operatorId) .then(res => { if (res.status === 'confirmed') { - delete txsCache[tx.id] // Transaction reached final status, can trim it from the caching obj + txsCache.del(tx.id) // Transaction reached final status, can trim it from the caching obj } else { - txsCache[tx.id].lastReqTime = Date.now() - txsCache[tx.id].res = res + txsCache.set(tx.id, { lastReqTime: Date.now(), res }) + txsCache.ttl(tx.id, T.hour / 1000) } return res })