aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2019-12-05 19:38:19 +0100
committerFlorian Dold <florian.dold@gmail.com>2019-12-05 19:38:19 +0100
commitf67d7f54f9d0fed97446898942e3dfee67ee2985 (patch)
tree2b81738025e8f61250ede10908cbf81071e16975 /src/util
parent829acdd3d98f1014747f15ecb619b6fbaa06b640 (diff)
downloadwallet-core-f67d7f54f9d0fed97446898942e3dfee67ee2985.tar.xz
threads, retries and notifications WIP
Diffstat (limited to 'src/util')
-rw-r--r--src/util/asyncMemo.ts77
-rw-r--r--src/util/query.ts3
-rw-r--r--src/util/taleruri-test.ts14
-rw-r--r--src/util/taleruri.ts19
4 files changed, 72 insertions, 41 deletions
diff --git a/src/util/asyncMemo.ts b/src/util/asyncMemo.ts
index 34868ab4f..193ce6df6 100644
--- a/src/util/asyncMemo.ts
+++ b/src/util/asyncMemo.ts
@@ -14,39 +14,76 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-export interface MemoEntry<T> {
+interface MemoEntry<T> {
p: Promise<T>;
t: number;
n: number;
}
-export class AsyncOpMemo<T> {
+export class AsyncOpMemoMap<T> {
private n = 0;
- private memo: { [k: string]: MemoEntry<T> } = {};
- put(key: string, p: Promise<T>): Promise<T> {
+ private memoMap: { [k: string]: MemoEntry<T> } = {};
+
+ private cleanUp(key: string, n: number) {
+ const r = this.memoMap[key];
+ if (r && r.n === n) {
+ delete this.memoMap[key];
+ }
+ }
+
+ memo(key: string, pg: () => Promise<T>): Promise<T> {
+ const res = this.memoMap[key];
+ if (res) {
+ return res.p;
+ }
const n = this.n++;
- this.memo[key] = {
+ // Wrap the operation in case it immediately throws
+ const p = Promise.resolve().then(() => pg());
+ p.finally(() => {
+ this.cleanUp(key, n);
+ });
+ this.memoMap[key] = {
p,
n,
t: new Date().getTime(),
};
- p.finally(() => {
- const r = this.memo[key];
- if (r && r.n === n) {
- delete this.memo[key];
- }
- });
return p;
}
- find(key: string): Promise<T> | undefined {
- const res = this.memo[key];
- const tNow = new Date().getTime();
- if (res && res.t < tNow - 10 * 1000) {
- delete this.memo[key];
- return;
- } else if (res) {
+ clear() {
+ this.memoMap = {};
+ }
+}
+
+
+export class AsyncOpMemoSingle<T> {
+ private n = 0;
+ private memoEntry: MemoEntry<T> | undefined;
+
+ private cleanUp(n: number) {
+ if (this.memoEntry && this.memoEntry.n === n) {
+ this.memoEntry = undefined;
+ }
+ }
+
+ memo(pg: () => Promise<T>): Promise<T> {
+ const res = this.memoEntry;
+ if (res) {
return res.p;
}
- return;
+ const n = this.n++;
+ // Wrap the operation in case it immediately throws
+ const p = Promise.resolve().then(() => pg());
+ p.finally(() => {
+ this.cleanUp(n);
+ });
+ this.memoEntry = {
+ p,
+ n,
+ t: new Date().getTime(),
+ };
+ return p;
+ }
+ clear() {
+ this.memoEntry = undefined;
}
-} \ No newline at end of file
+}
diff --git a/src/util/query.ts b/src/util/query.ts
index b1b19665b..e05656bb7 100644
--- a/src/util/query.ts
+++ b/src/util/query.ts
@@ -316,7 +316,7 @@ export function oneShotIterIndex<S extends IDBValidKey, T>(
return new ResultStream<T>(req);
}
-class TransactionHandle {
+export class TransactionHandle {
constructor(private tx: IDBTransaction) {}
put<T>(store: Store<T>, value: T, key?: any): Promise<any> {
@@ -406,6 +406,7 @@ function runWithTransaction<T>(
};
tx.onerror = () => {
console.error("error in transaction");
+ console.error(stack);
};
tx.onabort = () => {
if (tx.error) {
diff --git a/src/util/taleruri-test.ts b/src/util/taleruri-test.ts
index 02eecf209..c687a6717 100644
--- a/src/util/taleruri-test.ts
+++ b/src/util/taleruri-test.ts
@@ -169,10 +169,8 @@ test("taler refund uri parsing", t => {
t.fail();
return;
}
- t.is(
- r1.refundUrl,
- "https://merchant.example.com/public/refund?order_id=1234",
- );
+ t.is(r1.merchantBaseUrl, "https://merchant.example.com/public/");
+ t.is(r1.orderId, "1234");
});
test("taler refund uri parsing with instance", t => {
@@ -182,10 +180,8 @@ test("taler refund uri parsing with instance", t => {
t.fail();
return;
}
- t.is(
- r1.refundUrl,
- "https://merchant.example.com/public/instances/myinst/refund?order_id=1234",
- );
+ t.is(r1.orderId, "1234");
+ t.is(r1.merchantBaseUrl, "https://merchant.example.com/public/instances/myinst/");
});
test("taler tip pickup uri", t => {
@@ -197,7 +193,7 @@ test("taler tip pickup uri", t => {
}
t.is(
r1.merchantBaseUrl,
- "https://merchant.example.com/public/tip-pickup?tip_id=tipid",
+ "https://merchant.example.com/public/",
);
});
diff --git a/src/util/taleruri.ts b/src/util/taleruri.ts
index aa6705c07..50886a916 100644
--- a/src/util/taleruri.ts
+++ b/src/util/taleruri.ts
@@ -24,7 +24,8 @@ export interface WithdrawUriResult {
}
export interface RefundUriResult {
- refundUrl: string;
+ merchantBaseUrl: string;
+ orderId: string;
}
export interface TipUriResult {
@@ -184,17 +185,13 @@ export function parseRefundUri(s: string): RefundUriResult | undefined {
maybeInstancePath = `instances/${maybeInstance}/`;
}
- const refundUrl =
- "https://" +
- host +
- "/" +
- maybePath +
- maybeInstancePath +
- "refund" +
- "?order_id=" +
- orderId;
+ const merchantBaseUrl = "https://" + host +
+ "/" +
+ maybePath +
+ maybeInstancePath
return {
- refundUrl,
+ merchantBaseUrl,
+ orderId,
};
}