aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-02-18 23:34:57 +0100
committerFlorian Dold <florian@dold.me>2024-02-18 23:34:57 +0100
commitb55bf0779946b6a1554a687e05841d131b9951b3 (patch)
tree0eeb2df50228280ba92140f06a7037d9ba8baf0d /packages/taler-wallet-core
parent90c7dc49b7d377b4b3e691f45b84b51f6b03f9af (diff)
downloadwallet-core-b55bf0779946b6a1554a687e05841d131b9951b3.tar.xz
fix non-termination in run-until done
Also add a test for this.
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r--packages/taler-wallet-core/src/shepherd.ts48
1 files changed, 45 insertions, 3 deletions
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts
index 4aea2d15d..a3735e78f 100644
--- a/packages/taler-wallet-core/src/shepherd.ts
+++ b/packages/taler-wallet-core/src/shepherd.ts
@@ -77,6 +77,32 @@ interface ShepherdInfo {
cts: CancellationToken.Source;
}
+/**
+ * Check if a task is alive, i.e. whether it prevents
+ * the main task loop from exiting.
+ */
+function taskGivesLiveness(taskId: string): boolean {
+ const parsedTaskId = parseTaskIdentifier(taskId);
+ switch (parsedTaskId.tag) {
+ case PendingTaskType.Backup:
+ case PendingTaskType.ExchangeUpdate:
+ return false;
+ case PendingTaskType.Deposit:
+ case PendingTaskType.PeerPullCredit:
+ case PendingTaskType.PeerPullDebit:
+ case PendingTaskType.PeerPushCredit:
+ case PendingTaskType.Refresh:
+ case PendingTaskType.Recoup:
+ case PendingTaskType.RewardPickup:
+ case PendingTaskType.Withdraw:
+ case PendingTaskType.PeerPushDebit:
+ case PendingTaskType.Purchase:
+ return true;
+ default:
+ assertUnreachable(parsedTaskId);
+ }
+}
+
export class TaskScheduler {
private sheps: Map<TaskId, ShepherdInfo> = new Map();
@@ -89,6 +115,8 @@ export class TaskScheduler {
async loadTasksFromDb(): Promise<void> {
const activeTasks = await getActiveTaskIds(this.ws);
+ logger.info(`active tasks from DB: ${j2s(activeTasks)}`);
+
for (const tid of activeTasks.taskIds) {
this.startShepherdTask(tid);
}
@@ -98,10 +126,24 @@ export class TaskScheduler {
logger.info("Running task loop.");
this.ws.isTaskLoopRunning = true;
await this.loadTasksFromDb();
+ logger.info("loaded!");
+ logger.info(`sheps: ${this.sheps.size}`);
while (true) {
- if (opts.stopWhenDone && this.sheps.size === 0) {
- logger.info("Breaking out of task loop (no more work).");
- break;
+ if (opts.stopWhenDone) {
+ let alive = false;
+ const taskIds = [...this.sheps.keys()];
+ logger.info(`current task IDs: ${j2s(taskIds)}`);
+ logger.info(`sheps: ${this.sheps.size}`);
+ for (const taskId of taskIds) {
+ if (taskGivesLiveness(taskId)) {
+ alive = true;
+ break;
+ }
+ }
+ if (!alive) {
+ logger.info("Breaking out of task loop (no more work).");
+ break;
+ }
}
if (this.ws.stopped) {
logger.info("Breaking out of task loop (wallet stopped).");