summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-02-27 22:47:59 +0100
committerFlorian Dold <florian@dold.me>2024-02-27 22:47:59 +0100
commit2c86a9ec76b60ad065da65e5d2adfd1a79189ae6 (patch)
treeed04791360812b9ed3df5c2f8bbc3938e7f2fd7a /packages/taler-wallet-core
parentd3572014b06f60250e3bb9e99898b89cd11a4294 (diff)
downloadwallet-core-2c86a9ec76b60ad065da65e5d2adfd1a79189ae6.tar.gz
wallet-core-2c86a9ec76b60ad065da65e5d2adfd1a79189ae6.tar.bz2
wallet-core-2c86a9ec76b60ad065da65e5d2adfd1a79189ae6.zip
DB observability
Diffstat (limited to 'packages/taler-wallet-core')
-rw-r--r--packages/taler-wallet-core/src/db.ts7
-rw-r--r--packages/taler-wallet-core/src/observable-wrappers.ts81
-rw-r--r--packages/taler-wallet-core/src/query.ts24
-rw-r--r--packages/taler-wallet-core/src/shepherd.ts3
-rw-r--r--packages/taler-wallet-core/src/wallet.ts3
5 files changed, 112 insertions, 6 deletions
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index 3a593a523..9efc9fbe0 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -63,6 +63,7 @@ import {
import { DbRetryInfo, TaskIdentifiers } from "./common.js";
import {
DbAccess,
+ DbAccessImpl,
DbReadOnlyTransaction,
DbReadWriteTransaction,
IndexDescriptor,
@@ -3164,7 +3165,7 @@ export async function openStoredBackupsDatabase(
onStoredBackupsDbUpgradeNeeded,
);
- const handle = new DbAccess(backupsDbHandle, StoredBackupStores);
+ const handle = new DbAccessImpl(backupsDbHandle, StoredBackupStores);
return handle;
}
@@ -3187,7 +3188,7 @@ export async function openTalerDatabase(
onMetaDbUpgradeNeeded,
);
- const metaDb = new DbAccess(metaDbHandle, walletMetadataStore);
+ const metaDb = new DbAccessImpl(metaDbHandle, walletMetadataStore);
let currentMainVersion: string | undefined;
await metaDb.runReadWriteTx(["metaConfig"], async (tx) => {
const dbVersionRecord = await tx.metaConfig.get(CURRENT_DB_CONFIG_KEY);
@@ -3236,7 +3237,7 @@ export async function openTalerDatabase(
onTalerDbUpgradeNeeded,
);
- const handle = new DbAccess(mainDbHandle, WalletStoresV1);
+ const handle = new DbAccessImpl(mainDbHandle, WalletStoresV1);
await applyFixups(handle);
diff --git a/packages/taler-wallet-core/src/observable-wrappers.ts b/packages/taler-wallet-core/src/observable-wrappers.ts
index 77839e047..3df084268 100644
--- a/packages/taler-wallet-core/src/observable-wrappers.ts
+++ b/packages/taler-wallet-core/src/observable-wrappers.ts
@@ -21,6 +21,7 @@
/**
* Imports.
*/
+import { IDBDatabase } from "@gnu-taler/idb-bridge";
import {
ObservabilityContext,
ObservabilityEventType,
@@ -33,6 +34,12 @@ import {
HttpResponse,
} from "@gnu-taler/taler-util/http";
import { TaskIdStr } from "./common.js";
+import {
+ DbAccess,
+ DbReadOnlyTransaction,
+ DbReadWriteTransaction,
+ StoreNames,
+} from "./query.js";
import { TaskScheduler } from "./shepherd.js";
/**
@@ -129,3 +136,77 @@ export class ObservableHttpClientLibrary implements HttpRequestLibrary {
}
}
}
+
+const locRegex = /\s*at\s*([a-zA-Z0-9_.!]*)\s*/;
+
+export function getCallerInfo(up: number = 2): string {
+ const stack = new Error().stack ?? "";
+ const identifies: string[] = [];
+ for (const line of stack.split("\n")) {
+ let l = line.match(locRegex);
+ if (l) {
+ identifies.push(l[1]);
+ }
+ }
+ return identifies.slice(up, up + 2).join("/");
+}
+
+export class ObservableDbAccess<StoreMap> implements DbAccess<StoreMap> {
+ constructor(
+ private impl: DbAccess<StoreMap>,
+ private oc: ObservabilityContext,
+ ) {}
+ idbHandle(): IDBDatabase {
+ return this.impl.idbHandle();
+ }
+
+ runAllStoresReadWriteTx<T>(
+ txf: (
+ tx: DbReadWriteTransaction<StoreMap, StoreNames<StoreMap>[]>,
+ ) => Promise<T>,
+ ): Promise<T> {
+ this.oc.observe({
+ type: ObservabilityEventType.DbQueryStart,
+ name: "<unknown>",
+ location: getCallerInfo(),
+ });
+ return this.impl.runAllStoresReadWriteTx(txf);
+ }
+
+ runAllStoresReadOnlyTx<T>(
+ txf: (
+ tx: DbReadOnlyTransaction<StoreMap, StoreNames<StoreMap>[]>,
+ ) => Promise<T>,
+ ): Promise<T> {
+ this.oc.observe({
+ type: ObservabilityEventType.DbQueryStart,
+ name: "<unknown>",
+ location: getCallerInfo(),
+ });
+ return this.impl.runAllStoresReadOnlyTx(txf);
+ }
+
+ runReadWriteTx<T, StoreNameArray extends StoreNames<StoreMap>[]>(
+ storeNames: StoreNameArray,
+ txf: (tx: DbReadWriteTransaction<StoreMap, StoreNameArray>) => Promise<T>,
+ ): Promise<T> {
+ this.oc.observe({
+ type: ObservabilityEventType.DbQueryStart,
+ name: "<unknown>",
+ location: getCallerInfo(),
+ });
+ return this.impl.runReadWriteTx(storeNames, txf);
+ }
+
+ runReadOnlyTx<T, StoreNameArray extends StoreNames<StoreMap>[]>(
+ storeNames: StoreNameArray,
+ txf: (tx: DbReadOnlyTransaction<StoreMap, StoreNameArray>) => Promise<T>,
+ ): Promise<T> {
+ this.oc.observe({
+ type: ObservabilityEventType.DbQueryStart,
+ name: "<unknown>",
+ location: getCallerInfo(),
+ });
+ return this.impl.runReadOnlyTx(storeNames, txf);
+ }
+}
diff --git a/packages/taler-wallet-core/src/query.ts b/packages/taler-wallet-core/src/query.ts
index 4c169946c..994a6a96d 100644
--- a/packages/taler-wallet-core/src/query.ts
+++ b/packages/taler-wallet-core/src/query.ts
@@ -742,12 +742,34 @@ function makeWriteContext(
return ctx;
}
+export interface DbAccess<StoreMap> {
+ idbHandle(): IDBDatabase;
+ runAllStoresReadWriteTx<T>(
+ txf: (
+ tx: DbReadWriteTransaction<StoreMap, Array<StoreNames<StoreMap>>>,
+ ) => Promise<T>,
+ ): Promise<T>;
+ runAllStoresReadOnlyTx<T>(
+ txf: (
+ tx: DbReadOnlyTransaction<StoreMap, Array<StoreNames<StoreMap>>>,
+ ) => Promise<T>,
+ ): Promise<T>;
+ runReadWriteTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>(
+ storeNames: StoreNameArray,
+ txf: (tx: DbReadWriteTransaction<StoreMap, StoreNameArray>) => Promise<T>,
+ ): Promise<T>;
+ runReadOnlyTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>(
+ storeNames: StoreNameArray,
+ txf: (tx: DbReadOnlyTransaction<StoreMap, StoreNameArray>) => Promise<T>,
+ ): Promise<T>;
+}
+
/**
* Type-safe access to a database with a particular store map.
*
* A store map is the metadata that describes the store.
*/
-export class DbAccess<StoreMap> {
+export class DbAccessImpl<StoreMap> implements DbAccess<StoreMap> {
constructor(
private db: IDBDatabase,
private stores: StoreMap,
diff --git a/packages/taler-wallet-core/src/shepherd.ts b/packages/taler-wallet-core/src/shepherd.ts
index 1c23ab6b5..66c39ee48 100644
--- a/packages/taler-wallet-core/src/shepherd.ts
+++ b/packages/taler-wallet-core/src/shepherd.ts
@@ -64,6 +64,7 @@ import {
} from "./deposits.js";
import { updateExchangeFromUrlHandler } from "./exchanges.js";
import {
+ ObservableDbAccess,
ObservableHttpClientLibrary,
ObservableTaskScheduler,
} from "./observable-wrappers.js";
@@ -593,7 +594,7 @@ async function callOperationHandlerForTaskId(
ws,
cancellationToken,
cryptoApi: ws.cryptoApi,
- db: ws.db,
+ db: new ObservableDbAccess(ws.db, oc),
http: new ObservableHttpClientLibrary(ws.http, oc),
taskScheduler: new ObservableTaskScheduler(ws.taskScheduler, oc),
oc,
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 9185ee48c..c3aa68303 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -201,6 +201,7 @@ import {
getMaxPeerPushAmount,
} from "./instructedAmountConversion.js";
import {
+ ObservableDbAccess,
ObservableHttpClientLibrary,
ObservableTaskScheduler,
} from "./observable-wrappers.js";
@@ -1388,7 +1389,7 @@ async function handleCoreApiRequest(
ws,
cancellationToken: CancellationToken.CONTINUE,
cryptoApi: ws.cryptoApi,
- db: ws.db,
+ db: new ObservableDbAccess(ws.db, oc),
http: new ObservableHttpClientLibrary(ws.http, oc),
taskScheduler: new ObservableTaskScheduler(ws.taskScheduler, oc),
oc,