disable: cache the disabled-command set (config_gen-tagged HashSet) instead of re-splitting disabled_commands on every non-oper command — the hottest hook in the server; re-parses only on rehash

This commit is contained in:
Jean Chevronnet 2026-08-19 01:51:31 +00:00
parent 78be7279b0
commit 09b4adabbf

View file

@ -2,11 +2,19 @@
//! `disabled_commands = LIST WHO KNOCK` (space-separated; repeatable). A disabled //! `disabled_commands = LIST WHO KNOCK` (space-separated; repeatable). A disabled
//! command replies with `421` as if it didn't exist. Off unless configured. //! command replies with `421` as if it didn't exist. Off unless configured.
use crate::map::HashSet;
use crate::module::{ModResult, Module}; use crate::module::{ModResult, Module};
use crate::numeric::ERR_UNKNOWNCOMMAND; use crate::numeric::ERR_UNKNOWNCOMMAND;
use crate::server::Server; use crate::server::Server;
use crate::Uid; use crate::Uid;
/// The disabled-command set, parsed once and re-parsed only when the config changes.
#[derive(Default)]
struct DisabledCache {
gen: u64,
cmds: HashSet<String>, // uppercased command names
}
pub struct Disable; pub struct Disable;
impl Module for Disable { impl Module for Disable {
@ -25,11 +33,22 @@ impl Module for Disable {
if srv.is_oper(uid) { if srv.is_oper(uid) {
return ModResult::Passthru; return ModResult::Passthru;
} }
// (re)build the set only when the config generation changes, not per command
let gen = srv.config_gen;
let stale = srv.ext.get::<DisabledCache>().map(|c| c.gen != gen).unwrap_or(true);
if stale {
let cmds: HashSet<String> = srv
.conf_all("disabled_commands")
.iter()
.flat_map(|line| line.split_whitespace())
.map(|c| c.to_ascii_uppercase())
.collect();
srv.ext.set(DisabledCache { gen, cmds });
}
let disabled = srv let disabled = srv
.conf_all("disabled_commands") .ext
.iter() .get::<DisabledCache>()
.flat_map(|line| line.split_whitespace()) .is_some_and(|c| c.cmds.contains(&cmd.to_ascii_uppercase()));
.any(|c| c.eq_ignore_ascii_case(cmd));
if disabled { if disabled {
srv.numeric( srv.numeric(
uid, uid,