commit 1a12e2fc8e5d15ceba80090dc796457f22442fd9
parent 9856854690b71435536790e5f406e95624da599f
Author: Antoine A <>
Date: Wed, 30 Apr 2025 13:06:55 +0200
wallet: clean cache logic
Diffstat:
3 files changed, 45 insertions(+), 41 deletions(-)
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -1782,9 +1782,7 @@ export async function updateExchangeFromUrlHandler(
return;
}
- wex.ws.refreshCostCache.clear();
- wex.ws.exchangeCache.clear();
- wex.ws.denomInfoCache.clear();
+ wex.ws.clearAllCaches();
const oldExchangeState = getExchangeState(r);
const existingDetails = await getExchangeRecordsInternal(tx, r.baseUrl);
diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts
@@ -416,26 +416,21 @@ export async function getTotalRefreshCost(
refreshedDenom: DenominationInfo,
amountLeft: AmountJson,
): Promise<AmountJson> {
- const cacheKey = `denom=${refreshedDenom.exchangeBaseUrl}/${
- refreshedDenom.denomPubHash
- };left=${Amounts.stringify(amountLeft)}`;
- const cacheRes = wex.ws.refreshCostCache.get(cacheKey);
- if (cacheRes) {
- return cacheRes;
- }
- const allDenoms = await getWithdrawableDenomsTx(
- wex,
- tx,
- refreshedDenom.exchangeBaseUrl,
- Amounts.currencyOf(amountLeft),
- );
- const res = getTotalRefreshCostInternal(
- allDenoms,
- refreshedDenom,
- amountLeft,
- );
- wex.ws.refreshCostCache.put(cacheKey, res);
- return res;
+ const { exchangeBaseUrl, denomPubHash } = refreshedDenom;
+ const key = `denom=${exchangeBaseUrl}/${denomPubHash};left=${Amounts.stringify(amountLeft)}`;
+ return wex.ws.refreshCostCache.getOrPut(key, async () => {
+ const allDenoms = await getWithdrawableDenomsTx(
+ wex,
+ tx,
+ exchangeBaseUrl,
+ Amounts.currencyOf(amountLeft),
+ );
+ return getTotalRefreshCostInternal(
+ allDenoms,
+ refreshedDenom,
+ amountLeft,
+ );
+ })
}
/**
@@ -455,8 +450,7 @@ export function getTotalRefreshCostInternal(
amountLeft: AmountJson,
): AmountJson {
logger.trace(
- `computing total refresh cost, denom value ${
- refreshedDenom.value
+ `computing total refresh cost, denom value ${refreshedDenom.value
}, amount left ${Amounts.stringify(amountLeft)}`,
);
const withdrawAmount = Amounts.sub(
@@ -1621,7 +1615,7 @@ async function refreshReveal(
);
checkDbInvariant(
car.pendingRefreshOutputCount != null &&
- car.pendingRefreshOutputCount > 0,
+ car.pendingRefreshOutputCount > 0,
`no pendingRefreshOutputCount for denom ${coin.denomPubHash} age ${coin.maxAge}`,
);
car.pendingRefreshOutputCount--;
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
@@ -517,18 +517,15 @@ export async function getDenomInfo(
exchangeBaseUrl: string,
denomPubHash: string,
): Promise<DenominationInfo | undefined> {
- const cacheKey = `${exchangeBaseUrl}:${denomPubHash}`;
- const cached = wex.ws.denomInfoCache.get(cacheKey);
- if (cached) {
- return cached;
- }
- const d = await tx.denominations.get([exchangeBaseUrl, denomPubHash]);
- if (d) {
- const denomInfo = DenominationRecord.toDenomInfo(d);
- wex.ws.denomInfoCache.put(cacheKey, denomInfo);
- return denomInfo;
- }
- return undefined;
+ const key = `${exchangeBaseUrl}:${denomPubHash}`;
+ return wex.ws.denomInfoCache.getOrPut(key, async () => {
+ const d = await tx.denominations.get([exchangeBaseUrl, denomPubHash]);
+ if (d != null) {
+ return DenominationRecord.toDenomInfo(d);
+ } else {
+ return undefined
+ }
+ })
}
/**
@@ -2464,7 +2461,7 @@ async function dispatchWalletCoreApiRequest(
wex = getObservedWalletExecutionContext(ws, cts.token, cts, oc);
} else {
oc = {
- observe(evt) {},
+ observe(evt) { },
};
wex = getNormalWalletExecutionContext(ws, cts.token, cts, oc);
}
@@ -2619,7 +2616,7 @@ export class Cache<T> {
constructor(
private maxCapacity: number,
private cacheDuration: Duration,
- ) {}
+ ) { }
get(key: string): T | undefined {
const r = this.map.get(key);
@@ -2635,6 +2632,21 @@ export class Cache<T> {
return r[1];
}
+ async getOrPut(key: string, lambda: () => Promise<T>): Promise<T>;
+ async getOrPut(key: string, lambda: () => Promise<T | undefined>): Promise<T | undefined>;
+ async getOrPut(key: string, lambda: () => Promise<T | undefined>): Promise<T | undefined> {
+ const cached = this.get(key);
+ if (cached != null) {
+ return cached
+ } else {
+ const computed = await lambda();
+ if (computed != null) {
+ this.put(key, computed)
+ }
+ return computed;
+ }
+ }
+
clear(): void {
this.map.clear();
}
@@ -2655,7 +2667,7 @@ export class Cache<T> {
* Implementation of triggers for the wallet DB.
*/
class WalletDbTriggerSpec implements TriggerSpec {
- constructor(public ws: InternalWalletState) {}
+ constructor(public ws: InternalWalletState) { }
afterCommit(info: AfterCommitInfo): void {
if (info.mode !== "readwrite") {