connclass: cache resolved connect classes in a config_gen-tagged thread_local — all()/named() (and thus pick/assign and every per-ping/per-message getter) re-parsed the connectclass config and re-resolved parent inheritance on each call; now rebuilt only on rehash

This commit is contained in:
Jean Chevronnet 2026-08-19 01:56:22 +00:00
parent d4d3886379
commit ea3e879068

View file

@ -163,18 +163,40 @@ fn build(s: &Server, name: &str) -> Option<ConnClass> {
Some(c) Some(c)
} }
thread_local! {
/// (config_gen, resolved classes) — rebuilt only when the config changes. The
/// core is single-threaded, so this thread_local cache lets the `&Server`
/// entry points (pick/assign/named and the per-ping/per-message getters) avoid
/// re-parsing + re-resolving parent inheritance on every call.
static CLASSES: std::cell::RefCell<(u64, Vec<ConnClass>)> =
const { std::cell::RefCell::new((u64::MAX, Vec::new())) };
}
/// Run `f` over the resolved connect classes, (re)building them only on config change.
fn with_classes<R>(s: &Server, f: impl FnOnce(&[ConnClass]) -> R) -> R {
CLASSES.with(|cell| {
if cell.borrow().0 != s.config_gen {
let fresh: Vec<ConnClass> = s
.conf_all("connectclass")
.iter()
.filter_map(|l| l.split_whitespace().next())
.filter_map(|name| build(s, name))
.collect();
*cell.borrow_mut() = (s.config_gen, fresh);
}
let g = cell.borrow();
f(&g.1)
})
}
/// Every configured class, resolved. /// Every configured class, resolved.
pub fn all(s: &Server) -> Vec<ConnClass> { pub fn all(s: &Server) -> Vec<ConnClass> {
s.conf_all("connectclass") with_classes(s, <[ConnClass]>::to_vec)
.iter()
.filter_map(|l| l.split_whitespace().next())
.filter_map(|name| build(s, name))
.collect()
} }
/// A single resolved class by name. /// A single resolved class by name.
pub fn named(s: &Server, name: &str) -> Option<ConnClass> { pub fn named(s: &Server, name: &str) -> Option<ConnClass> {
build(s, name) with_classes(s, |c| c.iter().find(|x| x.name == name).cloned())
} }
// --- mask matching ----------------------------------------------------------- // --- mask matching -----------------------------------------------------------