From 97b98ec4b9ffcbc1a6f0917c851259d47514bfce Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 22 Aug 2021 18:58:45 +0100 Subject: [PATCH] discussion of hardcoded backpressure constants Signed-off-by: Ian Jackson --- server/server.rs | 28 +++++++++++++++++++++++----- server/sweb.rs | 2 +- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/server/server.rs b/server/server.rs index 0b5dde3..c28e017 100644 --- a/server/server.rs +++ b/server/server.rs @@ -22,7 +22,26 @@ pub struct Opts { pub const METADATA_MAX_LEN: usize = MAX_OVERHEAD; -pub const MAXQUEUE_ROUTE2WEB: usize = 15; // xxx: config + +// ----- Backpressure discussion ----- + +// These two kinds of channels are sent blockingly, so this means the +// task which calls route_packet can get this far ahead, before a +// context switch to the receiving task is forced. +pub const MAXQUEUE_ROUTE2USER: usize = 15; +pub const MAXQUEUE_ROUTE2LOCAL: usize = 50; + +// This channel is sent with try_send, ie non-blocking. If the user +// task becomes overloaded, requests will start to be rejected. +pub const MAXQUEUE_WEBREQ2USER: usize = 5; + +// The user task prioritises 1. returning requests or discarding data, +// 2. handling data routed to it. Ie it prefers to drain queues. +// +// The slocal task prioritises handling routed data and writing it +// (synchronously) to the local kernel. So if the local kernel starts +// blocking, all tasks may end up blocked waiting for things to drain. + #[derive(Debug)] pub struct Global { @@ -116,11 +135,10 @@ async fn main() { let (client_handles_send, client_handles_recv) = ics.iter() .map(|_ic| { let (web_send, web_recv) = mpsc::channel( - 5 // xxx should me max_requests_outstanding but that's - // marked client-only so needs rework + MAXQUEUE_WEBREQ2USER ); let (route_send, route_recv) = mpsc::channel( - MAXQUEUE_ROUTE2WEB + MAXQUEUE_ROUTE2USER ); ((web_send, route_send), (web_recv, route_recv)) }).unzip::<_,_,Vec<_>,Vec<_>>(); @@ -138,7 +156,7 @@ async fn main() { }).collect(); let (local_rx_send, local_tx_recv) = mpsc::channel( - 50 // xxx configurable? + MAXQUEUE_ROUTE2LOCAL ); let global = Arc::new(Global { diff --git a/server/sweb.rs b/server/sweb.rs index 49416c6..0e52fb9 100644 --- a/server/sweb.rs +++ b/server/sweb.rs @@ -192,7 +192,7 @@ pub async fn handle( }; client.web.try_send(wreq) - .map_err(|_| anyhow!("client task shut down!"))?; + .map_err(|_| anyhow!("client user task overloaded"))?; let reply: WebResponse = reply_recv.await?; warnings = reply.warnings; -- 2.30.2