mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-17 05:23:13 +01:00
Backport commit r48009, committed by Nathan Gray.
Data improvements: - pass UID as additional parameter to data callbacks - cache actual data separately from cached fetch response to avoid duplication - use callbacks to keep localStorage data consistent with data in memory - use callback to update cached fetch response if a record is removed (set to null)
This commit is contained in:
parent
e40065917b
commit
6ff6db42e6
@ -35,6 +35,12 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
*/
|
*/
|
||||||
var CACHE_LIFETIME = 29; // seconds
|
var CACHE_LIFETIME = 29; // seconds
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached fetches are differentiated from actual results by using this prefix
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
var CACHE_KEY_PREFIX = 'cached_fetch_';
|
||||||
|
|
||||||
var lastModification = null;
|
var lastModification = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,9 +81,11 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
var indexes = [];
|
var indexes = [];
|
||||||
for(var i = 0; i < window.localStorage.length; i++)
|
for(var i = 0; i < window.localStorage.length; i++)
|
||||||
{
|
{
|
||||||
if(window.localStorage.key(i).indexOf('cache_'+_prefix) == 0)
|
var key = window.localStorage.key(i);
|
||||||
|
|
||||||
|
// This is a cached fetch for many rows
|
||||||
|
if(key.indexOf(CACHE_KEY_PREFIX+_prefix) == 0)
|
||||||
{
|
{
|
||||||
var key = window.localStorage.key(i);
|
|
||||||
var cached = JSON.parse(window.localStorage.getItem(key));
|
var cached = JSON.parse(window.localStorage.getItem(key));
|
||||||
|
|
||||||
if(cached.lastModification)
|
if(cached.lastModification)
|
||||||
@ -93,6 +101,23 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Actual cached data
|
||||||
|
else if (key.indexOf(_prefix) == 0)
|
||||||
|
{
|
||||||
|
var cached = JSON.parse(window.localStorage.getItem(key));
|
||||||
|
if(cached.timestamp)
|
||||||
|
{
|
||||||
|
indexes.push({
|
||||||
|
key: key,
|
||||||
|
lastModification: cached.timestamp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No way to know how old it is, just remove it
|
||||||
|
window.localStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Nothing for that prefix? Clear all cached data.
|
// Nothing for that prefix? Clear all cached data.
|
||||||
if(_prefix && indexes.length == 0)
|
if(_prefix && indexes.length == 0)
|
||||||
@ -181,9 +206,37 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
var cache_key = false
|
var cache_key = false
|
||||||
if(cache_key = cc.callback.call(cc.context, _context))
|
if(cache_key = cc.callback.call(cc.context, _context))
|
||||||
{
|
{
|
||||||
cache_key = 'cache_' + _context.prefix + '::' + cache_key;
|
cache_key = CACHE_KEY_PREFIX + _context.prefix + '::' + cache_key;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
for (var key in _result.data)
|
||||||
|
{
|
||||||
|
var uid = UID(key, (typeof _context == "object" && _context != null) ? _context.prefix : "");
|
||||||
|
|
||||||
|
// Register a handler on each data so we can know if it is updated or removed
|
||||||
|
egw.dataUnregisterUID(uid, null, cache_key);
|
||||||
|
egw.dataRegisterUID(uid, function(data, _uid) {
|
||||||
|
// If data item is removed, remove it from cached fetch too
|
||||||
|
if(data == null)
|
||||||
|
{
|
||||||
|
var cached = JSON.parse(window.localStorage[this]) || false;
|
||||||
|
if(cached && cached.order && cached.order.indexOf(_uid) >= 0)
|
||||||
|
{
|
||||||
|
cached.order.splice(cached.order.indexOf(_uid),1);
|
||||||
|
if(cached.total) cached.total--;
|
||||||
|
window.localStorage[this] = JSON.stringify(cached);
|
||||||
|
}
|
||||||
|
window.localStorage.removeItem(_uid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Update or store data in long-term storage
|
||||||
|
window.localStorage[_uid] = JSON.stringify({timestamp: (new Date).getTime(), data: data});
|
||||||
|
}
|
||||||
|
},cache_key);
|
||||||
|
}
|
||||||
|
// Don't keep data in long-term cache with request also
|
||||||
|
_result.data = {};
|
||||||
window.localStorage.setItem(cache_key,JSON.stringify(_result));
|
window.localStorage.setItem(cache_key,JSON.stringify(_result));
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
@ -324,7 +377,7 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
var cache_key = false
|
var cache_key = false
|
||||||
if(cache_key = cc.callback.call(cc.context, _context))
|
if(cache_key = cc.callback.call(cc.context, _context))
|
||||||
{
|
{
|
||||||
cache_key = 'cache_' + _context.prefix + '::' + cache_key;
|
cache_key = CACHE_KEY_PREFIX + _context.prefix + '::' + cache_key;
|
||||||
|
|
||||||
var cached = window.localStorage.getItem(cache_key);
|
var cached = window.localStorage.getItem(cache_key);
|
||||||
if(cached)
|
if(cached)
|
||||||
@ -388,7 +441,7 @@ egw.extend("data", egw.MODULE_APP_LOCAL, function (_app, _wnd) {
|
|||||||
/**
|
/**
|
||||||
* Turn on long-term client side cache of a particular request
|
* Turn on long-term client side cache of a particular request
|
||||||
* (cache the nextmatch query results) for fast, immediate response
|
* (cache the nextmatch query results) for fast, immediate response
|
||||||
* with old data.
|
* with old data.
|
||||||
*
|
*
|
||||||
* The request is still sent to the server, and the cache is updated
|
* The request is still sent to the server, and the cache is updated
|
||||||
* with fresh data, and any needed callbacks are called again with
|
* with fresh data, and any needed callbacks are called again with
|
||||||
@ -509,6 +562,9 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
|||||||
|
|
||||||
// Delete the data from the localStorage
|
// Delete the data from the localStorage
|
||||||
delete localStorage[uid];
|
delete localStorage[uid];
|
||||||
|
|
||||||
|
// We don't clean long-term storage because of age until it runs
|
||||||
|
// out of space
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, CLEANUP_INTERVAL);
|
}, CLEANUP_INTERVAL);
|
||||||
@ -551,7 +607,13 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
|||||||
{
|
{
|
||||||
// Update the timestamp and call the given callback function
|
// Update the timestamp and call the given callback function
|
||||||
localStorage[_uid].timestamp = (new Date).getTime();
|
localStorage[_uid].timestamp = (new Date).getTime();
|
||||||
_callback.call(_context, localStorage[_uid].data);
|
_callback.call(_context, localStorage[_uid].data, _uid);
|
||||||
|
}
|
||||||
|
// Check long-term storage
|
||||||
|
else if(window.localStorage && window.localStorage[_uid])
|
||||||
|
{
|
||||||
|
localStorage[_uid] = JSON.parse(window.localStorage[_uid]);
|
||||||
|
_callback.call(_context, localStorage[_uid].data, _uid);
|
||||||
}
|
}
|
||||||
else if (_execId && _widgetId)
|
else if (_execId && _widgetId)
|
||||||
{
|
{
|
||||||
@ -694,7 +756,8 @@ egw.extend("data_storage", egw.MODULE_GLOBAL, function (_app, _wnd) {
|
|||||||
try {
|
try {
|
||||||
registeredCallbacks[_uid][i].callback.call(
|
registeredCallbacks[_uid][i].callback.call(
|
||||||
registeredCallbacks[_uid][i].context,
|
registeredCallbacks[_uid][i].context,
|
||||||
_data
|
_data,
|
||||||
|
_uid
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Remove this callback from the list
|
// Remove this callback from the list
|
||||||
|
Loading…
Reference in New Issue
Block a user