Clear sequentialize cache when empty to remove chance of memory leaks (#26)

This commit is contained in:
Fred Cox 2019-02-02 16:23:16 +02:00 committed by Kyle Spearrin
parent 9e97b1e656
commit e7f4dccfc3
2 changed files with 10 additions and 11 deletions

View File

@ -120,7 +120,7 @@ class Foo {
calls = 0; calls = 0;
@sequentialize((args) => 'bar' + args[0]) @sequentialize((args) => 'bar' + args[0])
bar(a: any) { bar(a: number) {
this.calls++; this.calls++;
return new Promise((res) => { return new Promise((res) => {
setTimeout(() => { setTimeout(() => {
@ -130,7 +130,7 @@ class Foo {
} }
@sequentialize((args) => 'baz' + args[0]) @sequentialize((args) => 'baz' + args[0])
baz(a: any) { baz(a: number) {
this.calls++; this.calls++;
return new Promise((res) => { return new Promise((res) => {
setTimeout(() => { setTimeout(() => {

View File

@ -6,7 +6,6 @@
* *
* Results are not cached, once the promise has returned, the next call will result in a fresh call * Results are not cached, once the promise has returned, the next call will result in a fresh call
* *
* WARNING: The decorator's scope is singleton, so using it on transient objects can lead to memory leaks.
* Read more at https://github.com/bitwarden/jslib/pull/7 * Read more at https://github.com/bitwarden/jslib/pull/7
*/ */
export function sequentialize(cacheKey: (args: any[]) => string) { export function sequentialize(cacheKey: (args: any[]) => string) {
@ -26,20 +25,20 @@ export function sequentialize(cacheKey: (args: any[]) => string) {
return { return {
value: function(...args: any[]) { value: function(...args: any[]) {
const argsCacheKey = cacheKey(args);
const cache = getCache(this); const cache = getCache(this);
const argsCacheKey = cacheKey(args);
let response = cache.get(argsCacheKey); let response = cache.get(argsCacheKey);
if (response != null) { if (response != null) {
return response; return response;
} }
response = originalMethod.apply(this, args).then((val: any) => { response = originalMethod.apply(this, args)
cache.delete(argsCacheKey); .finally(() => {
return val; cache.delete(argsCacheKey);
}).catch((err: any) => { if (cache.size === 0) {
cache.delete(argsCacheKey); caches.delete(this);
throw err; }
}); });
cache.set(argsCacheKey, response); cache.set(argsCacheKey, response);
return response; return response;