From 095da4eb5b81d150443dbb854bbef172d1132896 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sat, 22 Oct 2022 12:36:16 +0300 Subject: [PATCH] cleanup + prevented a couple of obscure issues + docs... Signed-off-by: Alex A. Naanou --- pwiki/store/base.js | 55 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/pwiki/store/base.js b/pwiki/store/base.js index 5cd306d..d2f3abf 100755 --- a/pwiki/store/base.js +++ b/pwiki/store/base.js @@ -37,22 +37,33 @@ var pwpath = require('../path') // () // ('get') // -> +// -> +// +// Get cached result and do "lazy" background update... (XXX EXPERIMENTAL) +// ('lazy') +// -> +// -> +// NOTE: 'lazy' mode is generally faster as it does all the checks and +// updating (if needed) in a background promise, but can return +// outdated cached results. // // Get local data (uncached)... // ('local') // -> +// -> // // Clear cache... // ('clear') -// -> // // Reset cache (clear then get)... // ('reset') // -> +// -> // // Run custom action... // (), ...) // -> +// -> // // // @@ -142,15 +153,23 @@ function(name, generate, options={}){ return res } // make local cache... var _make = function(that){ - return _stamp(that, - that[special] != null ? + return that[special] != null ? that[special]() : (generate - && generate.call(that))) } + && generate.call(that)) } + var _smake = function(that){ + return _stamp(that, _make(that)) } // unwrap a promised value into cache... + var promise = `__${name}_promise` var _await = function(obj, val){ if(val instanceof Promise){ + // NOTE: this avoids a race condition when a getter is called + // while a previous getter is still pending... + val = obj[promise] = + obj[promise] + ?? val val.then(function(value){ + delete obj[promise] obj[cache] = value }) } return val } @@ -159,6 +178,20 @@ function(name, generate, options={}){ return (meth = Object.assign( function(action='get', ...args){ var that = this + // XXX EXPERIMENTAL... + // action: lazy... + if(action == 'lazy'){ + if(this[cache] instanceof Promise){ + return this[cache] } + var res = meth('get') + return (this[cache] + && res instanceof Promise) ? + this[cache] + : res } + // action: local... + // NOTE: this is intentionally not cached... + if(action == 'local'){ + return _make(this) } // action: clear/reset... if(action == 'clear' || action == 'reset'){ @@ -198,13 +231,9 @@ function(name, generate, options={}){ res !== cur && _stamp(this, res) return res } - // action: get/local... - return _await(this, - // NOTE: this is intentionally not cached... - action == 'local' ? - _make(this) - // get... - : (this[cache] = + // action: get... + return _await(this, + this[cache] = // cached... this[cache] != null ? this[cache] @@ -212,9 +241,9 @@ function(name, generate, options={}){ : this[merge] != null ? // NOTE: need to set the timestamp after the merge... _stamp(this, - this[merge](_make(this))) + this[merge](_smake(this))) // generate... - : _make(this)) ) }, + : _smake(this)) }, { index: name, indexed: true,