Exploring network timeouts

Ethan Glasser-Camp <[email protected]> Thu, 2 Mar 2017 09:36:45 -0800 (PST)
Newsgroups gmane.comp.mozilla.devel.netlib
Message-ID <[email protected]>
Hi,

I'm currently removing a network timeout behavior in a JS library that is used in Firefox and I'm trying to ensure that I won't consume network resources forever if the user is on a slow connection.

Consider this xpcshell test:

```
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://services-common/async.js");
Cu.importGlobalProperties(['fetch']);

function sleep(aMs) {
  return new Promise((resolve, error) => {
    let timer = Cc["@mozilla.org/timer;1"]
        .createInstance(Ci.nsITimer);

    timer.initWithCallback({
      notify: function () {
        resolve();
      },
    }, aMs, timer.TYPE_ONE_SHOT);
  });
}

add_task(function* test_something() {
  dump(`-------------- PREFS ----------------\n`);
  dump(`response timeout: ${Services.prefs.getIntPref("network.http.response.timeout")}\n`);
  dump(`keepalive timeout: ${Services.prefs.getIntPref("network.http.keep-alive.timeout")}\n`);

  Services.prefs.setIntPref("network.http.response.timeout", 3);
  Services.prefs.setIntPref("network.http.keep-alive.timeout", 115);

  const server = new HttpServer();
  server.start();

  server.registerPathHandler("/test-resource", () => {
    Async.promiseSpinningly(sleep(150000));
    response.setStatusLine(null, 200, "OK");
    response.write("Test resource response");
  });

  try {
    const result = yield fetch(`http://localhost:${server.identity.primaryPort}/test-resource`);
    dump(`${result.status} ${result.statusText}\n`);
    dump(`${result.text()}\n`);
  } finally {
    server.stop(() => {});
  }
});
```

Sometimes this test fails with an error message like:

 0:23.14 LOG: Thread-1 ERROR Unexpected exception TypeError: NetworkError when attempting to fetch resource. at resource://services-common/async.js:98

But it seems to fail at strange times -- for example, this time it failed at the 23 second mark, which doesn't seem related to either the 115-second keepalive timeout or the 3-second response timeout. And even worse, sometimes the test succeeds after 150 seconds. What's going on? Is this expected? More generally, are there any best practices I should use to ensure responsible use of network resources when writing JS code in Firefox?

Thanks,

Ethan