server_multie10s_update.sjs (3130B)
1 // stolen from file_blocked_script.sjs 2 function setGlobalState(data, key) { 3 x = { 4 data, 5 QueryInterface(iid) { 6 return this; 7 }, 8 }; 9 x.wrappedJSObject = x; 10 setObjectState(key, x); 11 } 12 13 function getGlobalState(key) { 14 var data; 15 getObjectState(key, function (x) { 16 data = x && x.wrappedJSObject.data; 17 }); 18 return data; 19 } 20 21 function completeBlockingRequest(response) { 22 response.write("42"); 23 response.finish(); 24 } 25 26 // This stores the response that's currently blocking, or true if the release 27 // got here before the blocking request. 28 const BLOCKING_KEY = "multie10s-update-release"; 29 // This tracks the number of blocking requests we received up to this point in 30 // time. This value will be cleared when fetched. It's on the caller to make 31 // sure that all the blocking requests that might occurr have already occurred. 32 const COUNT_KEY = "multie10s-update-count"; 33 34 /** 35 * Serve a request that will only be completed when the ?release variant of this 36 * .sjs is fetched. This allows us to avoid using a timer, which slows down the 37 * tests and is brittle under slow hardware. 38 */ 39 function handleBlockingRequest(request, response) { 40 response.processAsync(); 41 response.setHeader("Content-Type", "application/javascript", false); 42 43 const existingCount = getGlobalState(COUNT_KEY) || 0; 44 setGlobalState(existingCount + 1, COUNT_KEY); 45 46 const alreadyReleased = getGlobalState(BLOCKING_KEY); 47 if (alreadyReleased === true) { 48 completeBlockingRequest(response); 49 setGlobalState(null, BLOCKING_KEY); 50 } else if (alreadyReleased) { 51 // If we've got another response stacked up, this means something is wrong 52 // with the test. The count mechanism will detect this, so just let this 53 // one through so we fail fast rather than hanging. 54 dump("we got multiple blocking requests stacked up!!\n"); 55 completeBlockingRequest(response); 56 } else { 57 setGlobalState(response, BLOCKING_KEY); 58 } 59 } 60 61 function handleReleaseRequest(request, response) { 62 const blockingResponse = getGlobalState(BLOCKING_KEY); 63 if (blockingResponse) { 64 completeBlockingRequest(blockingResponse); 65 setGlobalState(null, BLOCKING_KEY); 66 } else { 67 setGlobalState(true, BLOCKING_KEY); 68 } 69 70 response.setHeader("Content-Type", "application/json", false); 71 response.write(JSON.stringify({ released: true })); 72 } 73 74 function handleCountRequest(request, response) { 75 const count = getGlobalState(COUNT_KEY) || 0; 76 // --verify requires that we clear this so the test can be re-run. 77 setGlobalState(0, COUNT_KEY); 78 79 response.setHeader("Content-Type", "application/json", false); 80 response.write(JSON.stringify({ count })); 81 } 82 83 function handleRequest(request, response) { 84 dump( 85 "server_multie10s_update.sjs: processing request for " + 86 request.path + 87 "?" + 88 request.queryString + 89 "\n" 90 ); 91 const query = new URLSearchParams(request.queryString); 92 if (query.has("release")) { 93 handleReleaseRequest(request, response); 94 } else if (query.has("get-and-clear-count")) { 95 handleCountRequest(request, response); 96 } else { 97 handleBlockingRequest(request, response); 98 } 99 }