Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Exploring network timeouts

28 views
Skip to first unread message

Ethan Glasser-Camp

unread,
Mar 2, 2017, 12:36:46 PM3/2/17
to
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

patrick....@gmail.com

unread,
Mar 6, 2017, 11:54:33 AM3/6/17
to
any prefs are global to firefox and aren't guarantees at the xhr or fetch layer.. I would be shocked to see our chrome code setting them. you should use js timeouts and cancel things as needed as the only reliable way to deal with this stuff at the js layer for xhr. (I forget if fetch has an attribute to deal with it - but that would basically be implemented the same way)

Ethan Glasser-Camp

unread,
Mar 8, 2017, 11:52:55 AM3/8/17
to
I spoke to :mcmanus on IRC to clarify. I'm not trying to use the prefs to enforce a timeout, and doing so would be wrong. You should definitely institute your own timeout at the JS layer if you need to, e.g. for a UX that requires some kind of update.

Necko itself doesn't commit to any kind of network timeout happening. Under certain circumstances, Necko will report an "error" on a certain channel, but exactly what those circumstances are is best viewed as an implementation detail, subject to change, and not part of the API contract in any way.

That said, we use TCP keepalives to ensure that connections are still active. If those keepalives stop getting responses, the OS will tell us that the connection was lost, and we'll detect a network error. So eventually all the connections will get cleaned up, and I don't need to worry about it at the JS layer.

Thanks :mcmanus for the patient explanations.

Ethan
0 new messages