From b4d8f8178532c2ec2d31b7aaf711e236cd5061f0 Mon Sep 17 00:00:00 2001 From: Juan P Lopez Date: Thu, 31 Oct 2024 20:54:04 -0500 Subject: [PATCH] fix: avoid multiple queries to db for the same account --- core/api/src/servers/exporter.ts | 27 ++++++++++++++++---- core/api/src/services/ledger/admin-legacy.ts | 26 ++++++++++++++++--- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/core/api/src/servers/exporter.ts b/core/api/src/servers/exporter.ts index 7b725c33d9..02f33e3a5f 100644 --- a/core/api/src/servers/exporter.ts +++ b/core/api/src/servers/exporter.ts @@ -301,14 +301,31 @@ const createWalletGauge = ({ }) } +const inProgressBalanceQueries = new Map>() + const getWalletBalance = async (walletId: WalletId): Promise => { - const walletBalance = await LedgerService().getWalletBalance(walletId) - if (walletBalance instanceof Error) { - logger.warn({ walletId, walletBalance }, "impossible to get balance") - return 0 + const inProgressKey = `wallet-${walletId}` + + const inProgress = inProgressBalanceQueries.get(inProgressKey) + if (inProgress) { + return inProgress } - return walletBalance + const balancePromise = (async () => { + try { + const walletBalance = await LedgerService().getWalletBalance(walletId) + if (walletBalance instanceof Error) { + logger.warn({ walletId, walletBalance }, "impossible to get balance") + return 0 + } + return walletBalance + } finally { + inProgressBalanceQueries.delete(inProgressKey) + } + })() + + inProgressBalanceQueries.set(inProgressKey, balancePromise) + return balancePromise } const createColdStorageWalletGauge = () => { diff --git a/core/api/src/services/ledger/admin-legacy.ts b/core/api/src/services/ledger/admin-legacy.ts index 77a2b59f1a..cb49008fb0 100644 --- a/core/api/src/services/ledger/admin-legacy.ts +++ b/core/api/src/services/ledger/admin-legacy.ts @@ -16,12 +16,30 @@ import { UnknownLedgerError, } from "@/domain/ledger" +const inProgressQueries = new Map>() + const getWalletBalance = async (account: string, query = {}) => { const params = { account, currency: "BTC", ...query } - const { balance } = await MainBookAdmin.balance(params, { - readPreference: "secondaryPreferred", - }) - return balance + const inProgressKey = `${account}-${JSON.stringify(params)}` + + const inProgress = inProgressQueries.get(inProgressKey) + if (inProgress) { + return inProgress + } + + const balancePromise = (async () => { + try { + const { balance } = await MainBookAdmin.balance(params, { + readPreference: "secondaryPreferred", + }) + return balance + } finally { + inProgressQueries.delete(inProgressKey) + } + })() + + inProgressQueries.set(inProgressKey, balancePromise) + return balancePromise } export const getAssetsBalance = (endDate?: Date) =>