diff --git a/backend/controllers/cln/channels.js b/backend/controllers/cln/channels.js index 15d7ae70..67bd9c9a 100644 --- a/backend/controllers/cln/channels.js +++ b/backend/controllers/cln/channels.js @@ -14,11 +14,12 @@ export const listPeerChannels = (req, res, next) => { options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels'; request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); - return Promise.all(body.channels?.map((channel) => { + const getPeerAliasesTasks = body.channels.map((channel) => () => { channel.to_them_msat = channel.total_msat - channel.to_us_msat; - channel.balancedness = (channel.total_msat === 0) ? 1 : (1 - Math.abs((channel.to_us_msat - (channel.total_msat - channel.to_us_msat)) / channel.total_msat)).toFixed(3); + channel.balancedness = (channel.total_msat === 0) ? 1 : (1 - Math.abs((channel.to_us_msat - channel.to_them_msat) / channel.total_msat)).toFixed(3); return getAlias(req.session.selectedNode, channel, 'peer_id'); - })).then((values) => { + }); + common.runWithConcurrencyLimit(getPeerAliasesTasks, 20, () => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List With Aliases Received', data: body.channels }); return res.status(200).json(body.channels || []); }); diff --git a/backend/controllers/cln/network.js b/backend/controllers/cln/network.js index 81c72d29..b31b1415 100644 --- a/backend/controllers/cln/network.js +++ b/backend/controllers/cln/network.js @@ -4,6 +4,7 @@ import { Common } from '../../utils/common.js'; let options = null; const logger = Logger; const common = Common; +const aliasCache = new Map(); export const getRoute = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' }); options = common.getOptions(req); @@ -80,20 +81,28 @@ export const listNodes = (req, res, next) => { }); }; export const getAlias = (selNode, peer, id) => { - options.url = selNode.settings.lnServerUrl + '/v1/listnodes'; - if (!peer[id]) { + const peerId = peer[id]; + if (!peerId) { logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); peer.alias = ''; - return peer; + return Promise.resolve(peer); } - options.body = { id: peer[id] }; + if (aliasCache.has(peerId)) { + peer.alias = aliasCache.get(peerId); + return Promise.resolve(peer); + } + options.url = selNode.settings.lnServerUrl + '/v1/listnodes'; + options.body = { id: peerId }; return request.post(options).then((body) => { logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Network', msg: 'Peer Alias Finished', data: body }); - peer.alias = body.nodes[0] && body.nodes[0].alias ? body.nodes[0].alias : peer[id].substring(0, 20); + const alias = body.nodes?.[0]?.alias || peerId.substring(0, 20); + aliasCache.set(peerId, alias); + peer.alias = alias; return peer; }).catch((errRes) => { common.handleError(errRes, 'Network', 'Peer Alias Error', selNode); - peer.alias = peer[id].substring(0, 20); + const alias = peerId.substring(0, 20); + peer.alias = alias; return peer; }); }; diff --git a/backend/utils/common.js b/backend/utils/common.js index d3994801..91dbe64d 100644 --- a/backend/utils/common.js +++ b/backend/utils/common.js @@ -608,6 +608,39 @@ export class CommonService { const dataStr = foundDataLine ? foundDataLine.substring((foundDataLine.indexOf(search_string)) + search_string.length) : '{}'; return JSON.parse(dataStr); }; + this.runWithConcurrencyLimit = (tasks, limit, done) => { + const results = new Array(tasks.length); + let nextIndex = 0; + let activeCount = 0; + const runNext = () => { + if (nextIndex >= tasks.length) { + if (activeCount === 0) { + done(results); // all tasks are finished + } + return; + } + const currentIndex = nextIndex++; + activeCount++; + const task = tasks[currentIndex]; + if (typeof task !== 'function') { + results[currentIndex] = { error: new Error('Invalid task at index ' + currentIndex) }; + activeCount--; + runNext(); + return; + } + Promise.resolve().then(() => task()).then((result) => { + results[currentIndex] = result; + }).catch((err) => { + results[currentIndex] = { error: err }; + }).finally(() => { + activeCount--; + runNext(); + }); + }; + for (let i = 0; i < limit && i < tasks.length; i++) { + runNext(); + } + }; } } export const Common = new CommonService(); diff --git a/frontend/index.html b/frontend/index.html index e39f1577..6f38081e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -12,8 +12,8 @@ - +