define([ "./session", "dojo/Deferred", "dojo/_base/array", "dojo/_base/lang", "dojo/_base/xhr", "dojo/on" ], function(session, Deferred, array, lang, xhr, on) { var queue = []; var user; var generation = 0; on(session, 'change', setUser); setUser(session.get()); function setUser(newUser) { user = newUser; generation += 1; if ( user ) { // we make a local copy, just in case the requests cause // events to happen var q = queue; queue = []; array.forEach(q,real_request); } else { session.restore(); } } function real_request(item) { var req_generation = generation; var req = xhr(item.method,lang.mixin(item.options||{},{ failOk: true })); item.promise.ioArgs = req.ioArgs; console.log("Do request",item.options.url); req.then(function(result) { item.dfd.resolve(result); }, function(error){ if ( error.response.status === 401 ) { if ( user ) { if ( req_generation === generation ) { console.log("Retry after reauthentication",item.options.url); // we need to reauth queue.push(item); setUser(null); } else { console.log("Retry immediately",item.options.url); // we already did, redo request right away real_request(item); } } else { console.log("Retry when authenticated",item.options.url); queue.push(item); } } else { item.dfd.reject(error); } }); } var _xhr = function(method, options) { var item = { method: method, options: options, dfd: new Deferred() }; item.promise = lang.delegate(item.dfd.promise); // only do the request directly if we are authenticated if ( user ) { console.log("Immediate",options.url); real_request(item); } else { console.log("Delay until authenticated",options.url); queue.push(item); } return item.promise; }; return _xhr; });