From f67d7f54f9d0fed97446898942e3dfee67ee2985 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 5 Dec 2019 19:38:19 +0100 Subject: threads, retries and notifications WIP --- src/util/asyncMemo.ts | 77 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 20 deletions(-) (limited to 'src/util/asyncMemo.ts') 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 */ -export interface MemoEntry { +interface MemoEntry { p: Promise; t: number; n: number; } -export class AsyncOpMemo { +export class AsyncOpMemoMap { private n = 0; - private memo: { [k: string]: MemoEntry } = {}; - put(key: string, p: Promise): Promise { + private memoMap: { [k: string]: MemoEntry } = {}; + + 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): Promise { + 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 | 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 { + private n = 0; + private memoEntry: MemoEntry | undefined; + + private cleanUp(n: number) { + if (this.memoEntry && this.memoEntry.n === n) { + this.memoEntry = undefined; + } + } + + memo(pg: () => Promise): Promise { + 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 +} -- cgit v1.2.3