taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit c7817f930fcffb8cc8b1f2011b30e45d54013e74
parent 1cc9592c856ecc8677a78d003bf5c350ae78fe24
Author: Florian Dold <florian@dold.me>
Date:   Sat, 18 Apr 2026 00:05:46 +0200

wallet-core: only restart exchange-update task on forced update

Diffstat:
Mpackages/taler-wallet-core/src/db.ts | 2+-
Mpackages/taler-wallet-core/src/exchanges.ts | 33+++++++++++++++++++++++----------
Mpackages/taler-wallet-core/src/shepherd.ts | 23+++++++++++++----------
3 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts @@ -807,7 +807,7 @@ export interface ExchangeEntryRecord { * existing exchange entry. * * We keep the retry counter here instead of using the task retries, - * as the task succeeded, the exchange is just not usable. + * as the shepherd task succeeded, the exchange is just not usable. */ updateRetryCounter?: number; diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts @@ -1182,22 +1182,28 @@ export async function startUpdateExchangeEntry( await tx.exchanges.put(r); const newExchangeState = getExchangeState(r); const taskId = TaskIdentifiers.forExchangeUpdate(r); - return { oldExchangeState, newExchangeState, taskId }; + tx.notify({ + type: NotificationType.ExchangeStateTransition, + exchangeBaseUrl, + newExchangeState: newExchangeState, + oldExchangeState: oldExchangeState, + }); + return { taskId }; }); if (!res) { // Exchange entry is already good. + logger.trace(`exchange entry already up to date`); return; } - const { oldExchangeState, newExchangeState, taskId } = res; - wex.ws.notify({ - type: NotificationType.ExchangeStateTransition, - exchangeBaseUrl, - newExchangeState: newExchangeState, - oldExchangeState: oldExchangeState, - }); + const { taskId } = res; + logger.info(`updating exchange in task ${taskId}`); - await wex.taskScheduler.resetTaskRetries(taskId); + if (options.forceUpdate) { + await wex.taskScheduler.resetTaskRetries(taskId); + } else { + wex.taskScheduler.startShepherdTask(taskId); + } } /** @@ -1388,7 +1394,14 @@ async function waitReadyExchange( if (!options.forceUpdate) { ready = true; } - if (retryInfo && !options.noBail) { + if ( + !options.noBail && + retryInfo && + retryInfo.retryInfo.retryCounter > 1 + ) { + logger.trace( + `exchange in ready-update with retryInfo=${j2s(retryInfo)}`, + ); const reason = retryInfo?.lastError ?? exchange.unavailableReason; if (reason) { throw TalerError.fromUncheckedDetail(reason); diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts @@ -335,17 +335,20 @@ export class TaskSchedulerImpl implements TaskScheduler { } async resetTaskRetries(taskId: TaskIdStr): Promise<void> { - const maybeNotification = await this.ws.runStandaloneLegacyWalletDbTx( - async (tx) => { - logger.trace(`storing task [reset] for ${taskId}`); - await tx.operationRetries.delete(taskId); - return taskToRetryNotification(this.ws, tx, taskId, undefined); - }, - ); + await this.ws.runStandaloneLegacyWalletDbTx(async (tx) => { + logger.trace(`storing task [reset] for ${taskId}`); + await tx.operationRetries.delete(taskId); + const notif = await taskToRetryNotification( + this.ws, + tx, + taskId, + undefined, + ); + if (notif) { + tx.notify(notif); + } + }); this.stopShepherdTask(taskId); - if (maybeNotification) { - this.ws.notify(maybeNotification); - } this.startShepherdTask(taskId); }