server: a query that finds every permit taken waits for one instead of failing, the budget is 64, permit and upstream turns wait on a futex with one thread each, the thread pool has no task limit, and transparent huge pages are off for the process
This commit is contained in:
@@ -60,7 +60,6 @@ pub const StatsSnapshot = struct {
|
||||
tls_handshake_failures: u64,
|
||||
idle_timeouts: u64,
|
||||
connection_errors: u64,
|
||||
dropped_no_permit: u64,
|
||||
};
|
||||
|
||||
pub const DotServer = struct {
|
||||
@@ -83,6 +82,7 @@ pub const DotServer = struct {
|
||||
pub const Owner = DotServer;
|
||||
pub const ConnPayload = Payload;
|
||||
pub const serveConn = serveOne;
|
||||
pub const closing = wakeBudgetWaiters;
|
||||
pub const read_buffer_len = stream_buffer_len;
|
||||
pub const write_buffer_len = stream_buffer_len;
|
||||
pub const log = std.log.scoped(.dot_server);
|
||||
@@ -121,6 +121,10 @@ pub const DotServer = struct {
|
||||
self.core.serve(io);
|
||||
}
|
||||
|
||||
fn wakeBudgetWaiters(self: *DotServer, io: std.Io) void {
|
||||
self.budget.wakeWaiters(io);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *DotServer, io: std.Io) void {
|
||||
self.core.deinit(io);
|
||||
self.* = undefined;
|
||||
@@ -138,7 +142,6 @@ pub const DotServer = struct {
|
||||
.tls_handshake_failures = self.stats.tls_handshake_failures.load(.monotonic),
|
||||
.idle_timeouts = core.idle_timeouts.load(.monotonic),
|
||||
.connection_errors = core.connection_errors.load(.monotonic),
|
||||
.dropped_no_permit = core.dropped_no_permit.load(.monotonic),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -219,11 +222,11 @@ pub const DotServer = struct {
|
||||
},
|
||||
}
|
||||
|
||||
// There is no framing for "no answer", so the connection ends.
|
||||
const work = self.budget.tryAcquire(io) orelse {
|
||||
listener.bump(&stats.dropped_no_permit);
|
||||
return;
|
||||
};
|
||||
// Bounded like a read: a query still waiting when the idle budget
|
||||
// runs out ends the connection, with the timeout counted by the
|
||||
// budget. There is no framing for "no answer".
|
||||
const permit_deadline: std.Io.Clock.Timestamp = .fromNow(io, budget);
|
||||
const work = self.budget.acquire(io, permit_deadline, &self.core.run_state) catch return;
|
||||
defer self.budget.release(io, work);
|
||||
|
||||
const outcome = self.handler.handle(
|
||||
|
||||
Reference in New Issue
Block a user