distd: read timeout 2s -> 250ms (interim, PLAN-HTTPZ)
Each idle browser preconnect blocks the sequential accept loop for the full SO_RCVTIMEO serially (measured: ~1.9s behind one, ~3.9s behind two), so the timeout must stay well under human patience until the readiness loop lands (PLAN-HTTPZ A1 retires the mechanism). set_read_timeout takes milliseconds now.
This commit is contained in:
@@ -1052,7 +1052,7 @@ run_server :: (store_dir: string, port: i64) -> !ServeErr {
|
||||
while true {
|
||||
client := sock.accept(fd, null, null);
|
||||
if client < 0 { continue; }
|
||||
http.set_read_timeout(client, 2);
|
||||
http.set_read_timeout(client, 250);
|
||||
|
||||
gpa := GPA.init();
|
||||
arena := Arena.init(xx gpa, 65536);
|
||||
|
||||
@@ -80,12 +80,15 @@ Timeval :: struct {
|
||||
pad: i32 = 0;
|
||||
}
|
||||
|
||||
// Bound blocking reads on `fd` to `secs` seconds. A sequential accept
|
||||
// Bound blocking reads on `fd` to `ms` milliseconds. A sequential accept
|
||||
// loop needs this: browsers open speculative preconnections that never
|
||||
// send bytes, and an unbounded read on one of those wedges the whole
|
||||
// server while real requests sit in the backlog.
|
||||
set_read_timeout :: (fd: i32, secs: i64) {
|
||||
tv : Timeval = .{ tv_sec = secs };
|
||||
// server while real requests sit in the backlog. Every idle socket costs
|
||||
// the full timeout serially, so it must stay well under human patience;
|
||||
// a LAN client delivers its request bytes within a few ms of connecting.
|
||||
// (Retired by PLAN-HTTPZ A1, when the loop goes readiness-based.)
|
||||
set_read_timeout :: (fd: i32, ms: i64) {
|
||||
tv : Timeval = .{ tv_sec = ms / 1000, tv_usec = xx ((ms % 1000) * 1000) };
|
||||
sock.setsockopt(fd, sock.SOL_SOCKET, SO_RCVTIMEO, xx @tv, 16);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user