aboutsummaryrefslogtreecommitdiff
path: root/src/util/asyncMemo.ts
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/asyncMemo.ts
parent829acdd3d98f1014747f15ecb619b6fbaa06b640 (diff)
downloadwallet-core-f67d7f54f9d0fed97446898942e3dfee67ee2985.tar.xz
threads, retries and notifications WIP
Diffstat (limited to 'src/util/asyncMemo.ts')
-rw-r--r--src/util/asyncMemo.ts77
1 files changed, 57 insertions, 20 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
+}