From: pines Date: Sun, 6 May 2007 09:01:31 +0000 (+0000) Subject: refactor and .cached_request method X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=81c54771d7d72caeeee982f5a1f4789bae7c2b3c;p=Evergreen.git refactor and .cached_request method git-svn-id: svn://svn.open-ils.org/ILS/trunk@7204 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/xul/staff_client/chrome/content/util/network.js b/Open-ILS/xul/staff_client/chrome/content/util/network.js index 356229e879..2d1bcf4928 100644 --- a/Open-ILS/xul/staff_client/chrome/content/util/network.js +++ b/Open-ILS/xul/staff_client/chrome/content/util/network.js @@ -15,9 +15,16 @@ util.network.prototype = { 'NETWORK_FAILURE' : null, - 'simple_request' : function(id,params,f,o_params) { - var secure = true; if (typeof api[id].secure != 'undefined') secure = api[id].secure; - return this.request(api[id].app,api[id].method,params,f,o_params,secure); + 'simple_request' : function(method_id,params,f,override_params) { + if (typeof api[method_id] == 'undefined') throw( 'Method not found for ' + method_id ); + var secure = true; if (typeof api[method_id].secure != 'undefined') secure = api[method_id].secure; + return this.request(api[method_id].app,api[method_id].method,params,f,override_params,{ 'secure' : secure, 'method_id' : method_id }); + }, + + 'cached_request' : function(method_id,params,f,override_params) { + if (typeof api[method_id] == 'undefined') throw( 'Method not found for ' + method_id ); + var secure = true; if (typeof api[method_id].secure != 'undefined') secure = api[method_id].secure; + return this.request(api[method_id].app,api[method_id].method,params,f,override_params,{ 'secure' : secure, 'want_cached' : true, 'method_id' : method_id }); }, 'get_result' : function (req) { @@ -40,24 +47,93 @@ util.network.prototype = { return result; }, - 'request' : function (app,name,params,f,o_params,secure) { - var request = this._request(app,name,params,f,o_params,secure); + 'is_cacheable' : function(method_id) { + return (api[method_id].cacheable); + }, + + 'request' : function (app,name,params,f,override_params,_params) { + + var obj = this; + + try { + + if (_params && _params.want_cached) if ( this.is_cacheable(_params.method_id) ) { + JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'}); + var key = (app + '+' + name + '+' + js2JSON(params)).replace(/\./g,'_'); + var x = data.cached_request[key]; + if (x) { + obj.error.sdump('D_CACHE','Cached request found for key = \n' + key + '\n' + js2JSON(x) + '\n'); + switch(x.status) { + case 'pending' : + if (f) { // Setup a self-destroying observer on the pending request to handle this request + obj.error.sdump('D_CACHE','Cached request pending, adding watch to handle current asynchronous request. key = \n' + key + '\n'); + var id = data.observers.add('cached_request.'+key+'.status',function(p,o,n) { + obj.error.sdump('D_OBSERVERS','Entering watch function for key = \n' + key + '\np = ' + p + '\no = ' + js2JSON(o) + '\nn = ' + js2JSON(n) + '\nx = ' + js2JSON(x) + '\n'); + if (n == 'complete') { + obj.error.sdump('D_CACHE','Cached request completed for key = \n' + key + '\nNow calling a previous async request watching this one.\n'); + f( { 'getResultObject' : function() { return JSON2js( js2JSON( x.request ) ); } } ); + setTimeout( function() { try { data.observers.remove(id); } catch(E) { alert(E); } }, 0 ); + } + return n; + } + ); + return null; + } else { + obj.error.sdump('D_CACHE','Pending request and synchronous request collision with key = \n' + key + '\nFalling through...\n'); + } + break; + case 'complete' : + if ( Number( new Date() ) < x.expire_time ) { + if (f) { + obj.error.sdump('D_CACHE','Cached request found completed, handling asynchronous request now. key = \n' + key + '\n'); + f( { 'getResultObject' : function() { return JSON2js( js2JSON( x.request ) ); } } ); + return null; + } else { + obj.error.sdump('D_CACHE','Cached request found completed, key = \n' + key + '\nreturning value =\n' + x.request + '\n'); + return JSON2js( js2JSON( x.request ) ); // FIXME -- cloning the object is a workaround, otherwise instanceOf somehow silently fails + } + } else { + obj.error.sdump('D_CACHE','Cached request found completed, however, it has expired. key = \n' + key + '\nFalling through...\n'); + } + break; + } + } else { + obj.error.sdump('D_CACHE','Cached request not found for key = \n' + key + '\n'); + } + } + + var request = this._request(app,name,params,f,override_params,_params); if (request) { return this.get_result(request); } else { return null; } + + } catch(E) { + alert(E); + } }, - '_request' : function (app,name,params,f,o_params,secure) { + '_request' : function (app,name,params,f,override_params,_params) { var obj = this; try { var sparams = js2JSON(params); obj.error.sdump('D_SES','request '+app+' '+name+' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+ - '\no_params = ' + o_params + '\nsecure = ' + secure + + '\noverride_params = ' + override_params + '\n_params = ' + _params + '\nResult #' + (++obj.link_id) + ( f ? ' asynced' : ' synced' ) ); + + var key; var x; var data; + if (_params && obj.is_cacheable(_params.method_id)) { + JSAN.use('OpenILS.data'); data = new OpenILS.data(); data.init({'via':'stash'}); + key = (app + '+' + name + '+' + js2JSON(params)).replace(/\./g,'_'); + data.cached_request[key] = { 'test' : 'test', 'status' : 'pending', 'status_time' : Number(new Date()) }; + data.stash('cached_request'); + x = data.cached_request[key]; + obj.error.sdump('D_CACHE','Current request is cacheable, setting pending status for key = \n' + key + '\nUpdating cache with ' + js2JSON(x) + '\n'); + } + var request = new RemoteRequest( app, name ); - if (secure) { + if (_params && _params.secure) { request.setSecure(true); } else { request.setSecure(false); @@ -76,12 +152,18 @@ util.network.prototype = { + (json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string) + '\n\nOriginal Request:\n\n' + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1)); - req = obj.rerequest_on_session_timeout(app,name,params,req,o_params,secure); - req = obj.rerequest_on_perm_failure(app,name,params,req,o_params,secure); - if (o_params) { - req = obj.rerequest_on_override(app,name,params,req,o_params,secure); + req = obj.rerequest_on_session_timeout(app,name,params,req,override_params,_params); + req = obj.rerequest_on_perm_failure(app,name,params,req,override_params,_params); + if (override_params) { + req = obj.rerequest_on_override(app,name,params,req,override_params,_params); + } + req = obj.check_for_offline(app,name,params,req,override_params,_params); + if (_params && obj.is_cacheable(_params.method_id)) { + x.request = obj.get_result(req); + x.status = 'complete'; x.status_time = Number(new Date()); x.expire_time = Number(x.status_time) + api[_params.method_id].ttl; + data.stash('cached_request'); + obj.error.sdump('D_CACHE','Previously pending cached request is now complete for key = \n' + key + '\nUpdating cache with ' + js2JSON(x) + '\n'); } - req = obj.check_for_offline(app,name,params,req,o_params,secure); f(req); obj.NETWORK_FAILURE = null; } catch(E) { @@ -111,13 +193,19 @@ util.network.prototype = { + obj.link_id + '\n\n' + ( json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string ) + '\n\nOriginal Request:\n\n' + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1)); - request = obj.rerequest_on_session_timeout(app,name,params,request,o_params,secure); - request = obj.rerequest_on_perm_failure(app,name,params,request,o_params,secure); - if (o_params) { - request = obj.rerequest_on_override(app,name,params,request,o_params,secure); + request = obj.rerequest_on_session_timeout(app,name,params,request,override_params,_params); + request = obj.rerequest_on_perm_failure(app,name,params,request,override_params,_params); + if (override_params) { + request = obj.rerequest_on_override(app,name,params,request,override_params,_params); } - request = obj.check_for_offline(app,name,params,request,o_params,secure); + request = obj.check_for_offline(app,name,params,request,override_params,_params); obj.NETWORK_FAILURE = null; + if (_params && obj.is_cacheable(_params.method_id)) { + x.request = result; + x.status = 'complete'; x.status_time = Number(new Date()); x.expire_time = Number(x.status_time) + api[_params.method_id].ttl; + data.stash('cached_request'); + obj.error.sdump('D_CACHE','Previously pending cached request is now complete for key = \n' + key + '\nUpdating cache with ' + js2JSON(x) + '\n'); + } return request; } @@ -130,7 +218,7 @@ util.network.prototype = { } }, - 'check_for_offline' : function (app,name,params,req,o_params,secure) { + 'check_for_offline' : function (app,name,params,req,override_params,_params) { var obj = this; var result = obj.get_result(req); if (result != null) return req; @@ -178,7 +266,7 @@ util.network.prototype = { switch(r) { case 0: - req = obj._request(app,name,params,null,o_params,secure); + req = obj._request(app,name,params,null,override_params,_params); if (obj.get_result(req)) proceed = true; /* daily WTF, why am I even doing this? :) */ return req; break; @@ -247,7 +335,7 @@ util.network.prototype = { } }, - 'rerequest_on_session_timeout' : function(app,name,params,req,o_params,secure) { + 'rerequest_on_session_timeout' : function(app,name,params,req,override_params,_params) { try { var obj = this; var robj = obj.get_result(req); @@ -256,7 +344,7 @@ util.network.prototype = { if (obj.get_new_session(name,undefined,true)) { JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'}); params[0] = data.session.key; - req = obj._request(app,name,params,null,o_params,secure); + req = obj._request(app,name,params,null,override_params,_params); } } } catch(E) { @@ -265,7 +353,7 @@ util.network.prototype = { return req; }, - 'rerequest_on_perm_failure' : function(app,name,params,req,o_params,secure) { + 'rerequest_on_perm_failure' : function(app,name,params,req,override_params,_params) { try { var obj = this; var robj = obj.get_result(req); @@ -286,7 +374,7 @@ util.network.prototype = { var data = new OpenILS.data(); data.init({'via':'stash'}); if (typeof data.temporary_session != 'undefined' && data.temporary_session != '') { params[0] = data.temporary_session.key; - req = obj._request(app,name,params,null,o_params,secure); + req = obj._request(app,name,params,null,override_params,_params); } } } @@ -296,10 +384,10 @@ util.network.prototype = { return req; }, - 'rerequest_on_override' : function (app,name,params,req,o_params,secure) { + 'rerequest_on_override' : function (app,name,params,req,override_params,_params) { var obj = this; try { - if (!o_params.text) o_params.text = {}; + if (!override_params.text) override_params.text = {}; function override(r) { try { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite'); @@ -310,7 +398,7 @@ util.network.prototype = { for (var i = 0; i < r.length; i++) { var t1 = String(r[i].ilsevent).replace(/&/g,'&').replace(//g,'>'); var t2 = String(r[i].textcode).replace(/&/g,'&').replace(//g,'>'); - var t3 = String((o_params.text[r[i].ilsevent] ? o_params.text[r[i].ilsevent](r[i]) : '')).replace(/&/g,'&').replace(//g,'>'); + var t3 = String((override_params.text[r[i].ilsevent] ? override_params.text[r[i].ilsevent](r[i]) : '')).replace(/&/g,'&').replace(//g,'>'); var t4 = String(r[i].desc).replace(/&/g,'&').replace(//g,'>'); xml += '' + '' + t2 + '' + @@ -327,7 +415,7 @@ util.network.prototype = { window.open( urls.XUL_FANCY_PROMPT + '?xml_in_stash=temp_override_xml' - + '&title=' + window.escape(o_params.title), + + '&title=' + window.escape(override_params.title), 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500' ); data.init({'via':'stash'}); @@ -343,12 +431,12 @@ util.network.prototype = { var result = obj.get_result(req); if (!result) return req; - if ( (typeof result.ilsevent != 'undefined') && (o_params.overridable_events.indexOf(result.ilsevent) != -1) ) { + if ( (typeof result.ilsevent != 'undefined') && (override_params.overridable_events.indexOf(result.ilsevent) != -1) ) { req = override([result]); } else { var found_good = false; var found_bad = false; for (var i = 0; i < result.length; i++) { - if ( (result[i].ilsevent != 'undefined') && (o_params.overridable_events.indexOf(result[i].ilsevent) != -1) ) { + if ( (result[i].ilsevent != 'undefined') && (override_params.overridable_events.indexOf(result[i].ilsevent) != -1) ) { found_good = true; } else { found_bad = true;