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:
parent
d4d3886379
commit
ea3e879068
1 changed files with 28 additions and 6 deletions
|
|
@ -163,18 +163,40 @@ fn build(s: &Server, name: &str) -> Option<ConnClass> {
|
||||||
Some(c)
|
Some(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Every configured class, resolved.
|
thread_local! {
|
||||||
pub fn all(s: &Server) -> Vec<ConnClass> {
|
/// (config_gen, resolved classes) — rebuilt only when the config changes. The
|
||||||
s.conf_all("connectclass")
|
/// 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()
|
.iter()
|
||||||
.filter_map(|l| l.split_whitespace().next())
|
.filter_map(|l| l.split_whitespace().next())
|
||||||
.filter_map(|name| build(s, name))
|
.filter_map(|name| build(s, name))
|
||||||
.collect()
|
.collect();
|
||||||
|
*cell.borrow_mut() = (s.config_gen, fresh);
|
||||||
|
}
|
||||||
|
let g = cell.borrow();
|
||||||
|
f(&g.1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Every configured class, resolved.
|
||||||
|
pub fn all(s: &Server) -> Vec<ConnClass> {
|
||||||
|
with_classes(s, <[ConnClass]>::to_vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 -----------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue