1
0
mirror of https://github.com/bitwarden/jslib synced 2025-12-17 08:43:18 +00:00

Add sequentialize to prevent parralel loading of cipher keys (#7)

* Add sequentialize to prevent parralel loading of cipher keys

Massively improves start up performance of extensions

* Add tests for sequentialize

* Fix sequentialize as it was caching calls for all instances together

* Add sequentialize to the functions that have internal caches

* Adding sequentialize to getOrgKeys makes big performance difference

* Update cipher.service.ts

* Update collection.service.ts

* Update folder.service.ts
This commit is contained in:
Fred Cox
2018-07-23 21:23:30 +03:00
committed by Kyle Spearrin
parent 3a34d3b174
commit 04014a8e78
4 changed files with 197 additions and 0 deletions

52
src/misc/sequentialize.ts Normal file
View File

@@ -0,0 +1,52 @@
/**
* Use as a Decorator on async functions, it will prevent multiple 'active' calls as the same time
*
* If a promise was returned from a previous call to this function, that hasn't yet resolved it will
* be returned, instead of calling the original function again
*
* Results are not cached, once the promise has returned, the next call will result in a fresh call
*/
export function sequentialize(key: (args: any[]) => string = JSON.stringify) {
return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
const originalMethod: () => Promise<any> = descriptor.value;
const caches = new Map<any, Map<string, Promise<any>>>();
const getCache = (obj: any) => {
let cache = caches.get(obj);
if (cache) {
return cache;
}
cache = new Map<string, Promise<any>>();
caches.set(obj, cache);
return cache;
};
return {
value: function(...args: any[]) {
const argsKey = key(args);
const cache = getCache(this);
let res = cache.get(argsKey);
if (res) {
return res;
}
res = originalMethod.apply(this, args)
.then((val: any) => {
cache.delete(argsKey);
return val;
})
.catch((err: any) => {
cache.delete(argsKey);
throw err;
});
cache.set(argsKey, res);
return res;
},
};
};
}