mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Add incremental backoff to the filter/permchannels/xline_db modules.
Closes #1671.
This commit is contained in:
parent
1a746b2c7f
commit
68480cee67
@ -1909,12 +1909,20 @@
|
||||
# 'saveperiod' determines how often to check if the database needs to be
|
||||
# saved to disk. Defaults to every five seconds.
|
||||
#
|
||||
# 'backoff' is the value to multiply the saveperiod by every time a save
|
||||
# fails. When the save succeeds the period will be reset.
|
||||
#
|
||||
# 'maxbackoff' is the maximum write period that should be allowed even
|
||||
# if incremental backoff is enabled.
|
||||
#
|
||||
# 'operonly' determines whether a server operator or services server is
|
||||
# needed to enable the permchannels mode. You should generally keep this
|
||||
# set to yes unless you know what you are doing.
|
||||
#<permchanneldb filename="permchannels.conf"
|
||||
# listmodes="yes"
|
||||
# saveperiod="5s"
|
||||
# backoff="2"
|
||||
# maxbackoff="5m"
|
||||
# operonly="yes">
|
||||
#<include file="permchannels.conf" missingokay="yes">
|
||||
#
|
||||
@ -2658,7 +2666,10 @@
|
||||
|
||||
# Specify the filename for the xline database and how often to check whether
|
||||
# the database needs to be saved here.
|
||||
#<xlinedb filename="xline.db" saveperiod="5s">
|
||||
#<xlinedb filename="xline.db"
|
||||
# saveperiod="5s"
|
||||
# backoff="2"
|
||||
# maxbackoff="5m">
|
||||
|
||||
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
|
||||
# ____ _ _____ _ _ ____ _ _ _ #
|
||||
|
@ -206,6 +206,9 @@ private:
|
||||
bool dirty = false;
|
||||
std::string filterconf;
|
||||
Regex::Engine* factory;
|
||||
unsigned long saveperiod;
|
||||
unsigned long maxbackoff;
|
||||
unsigned char backoff;
|
||||
void FreeFilters();
|
||||
|
||||
public:
|
||||
@ -238,6 +241,7 @@ public:
|
||||
ModResult OnPreCommand(std::string& command, CommandBase::Params& parameters, LocalUser* user, bool validated) override;
|
||||
void OnUnloadModule(Module* mod) override;
|
||||
bool Tick() override;
|
||||
bool WriteDatabase();
|
||||
bool AppliesToMe(User* user, const FilterResult& filter, int flags);
|
||||
void ReadFilters();
|
||||
static bool StringToFilterAction(const std::string& str, FilterAction& fa);
|
||||
@ -645,7 +649,10 @@ void ModuleFilter::ReadConfig(ConfigStatus& status)
|
||||
filterconf = tag->getString("filename");
|
||||
if (!filterconf.empty())
|
||||
filterconf = ServerInstance->Config->Paths.PrependConfig(filterconf);
|
||||
SetInterval(tag->getDuration("saveperiod", 5));
|
||||
saveperiod = tag->getDuration("saveperiod", 5);
|
||||
backoff = tag->getNum<uint8_t>("backoff", 0);
|
||||
maxbackoff = tag->getDuration("maxbackoff", saveperiod * 120, saveperiod);
|
||||
SetInterval(saveperiod);
|
||||
|
||||
factory = RegexEngine ? (RegexEngine.operator->()) : nullptr;
|
||||
|
||||
@ -934,9 +941,29 @@ void ModuleFilter::OnUnloadModule(Module* mod)
|
||||
|
||||
bool ModuleFilter::Tick()
|
||||
{
|
||||
if (!dirty) // No need to write.
|
||||
return true;
|
||||
if (dirty)
|
||||
{
|
||||
if (WriteDatabase())
|
||||
{
|
||||
// If we were previously unable to write but now can then reset the time interval.
|
||||
if (GetInterval() != saveperiod)
|
||||
SetInterval(saveperiod, false);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Back off a bit to avoid spamming opers.
|
||||
if (backoff > 1)
|
||||
SetInterval(std::min(GetInterval() * backoff, maxbackoff), false);
|
||||
ServerInstance->Logs.Debug(MODNAME, "Trying again in {} seconds", GetInterval());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool ModuleFilter::WriteDatabase()
|
||||
{
|
||||
if (filterconf.empty()) // Nothing to write to.
|
||||
{
|
||||
dirty = false;
|
||||
@ -949,7 +976,7 @@ bool ModuleFilter::Tick()
|
||||
{
|
||||
ServerInstance->SNO.WriteToSnoMask('f', "Unable to save filters to \"{}\": {} ({})",
|
||||
newfilterconf, strerror(errno), errno);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
stream
|
||||
@ -977,7 +1004,7 @@ bool ModuleFilter::Tick()
|
||||
{
|
||||
ServerInstance->SNO.WriteToSnoMask('f', "Unable to save filters to \"{}\": {} ({})",
|
||||
newfilterconf, strerror(errno), errno);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
stream.close();
|
||||
|
||||
@ -990,7 +1017,7 @@ bool ModuleFilter::Tick()
|
||||
{
|
||||
ServerInstance->SNO.WriteToSnoMask('f', "Unable to replace old filter config \"{}\" with \"{}\": {} ({})",
|
||||
filterconf, newfilterconf, strerror(errno), errno);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
dirty = false;
|
||||
|
@ -176,10 +176,15 @@ class ModulePermanentChannels final
|
||||
, public Timer
|
||||
|
||||
{
|
||||
private:
|
||||
PermChannel p;
|
||||
bool dirty = false;
|
||||
bool loaded = false;
|
||||
bool save_listmodes;
|
||||
unsigned long saveperiod;
|
||||
unsigned long maxbackoff;
|
||||
unsigned char backoff;
|
||||
|
||||
public:
|
||||
|
||||
ModulePermanentChannels()
|
||||
@ -195,7 +200,10 @@ public:
|
||||
permchannelsconf = tag->getString("filename");
|
||||
save_listmodes = tag->getBool("listmodes", true);
|
||||
p.SetOperOnly(tag->getBool("operonly", true));
|
||||
SetInterval(tag->getDuration("saveperiod", 5));
|
||||
saveperiod = tag->getDuration("saveperiod", 5);
|
||||
backoff = tag->getNum<uint8_t>("backoff", 0);
|
||||
maxbackoff = tag->getDuration("maxbackoff", saveperiod * 120, saveperiod);
|
||||
SetInterval(saveperiod);
|
||||
|
||||
if (!permchannelsconf.empty())
|
||||
permchannelsconf = ServerInstance->Config->Paths.PrependConfig(permchannelsconf);
|
||||
@ -289,8 +297,23 @@ public:
|
||||
bool Tick() override
|
||||
{
|
||||
if (dirty)
|
||||
WriteDatabase(p, save_listmodes);
|
||||
dirty = false;
|
||||
{
|
||||
if (WriteDatabase(p, save_listmodes))
|
||||
{
|
||||
// If we were previously unable to write but now can then reset the time interval.
|
||||
if (GetInterval() != saveperiod)
|
||||
SetInterval(saveperiod, false);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Back off a bit to avoid spamming opers.
|
||||
if (backoff > 1)
|
||||
SetInterval(std::min(GetInterval() * backoff, maxbackoff), false);
|
||||
ServerInstance->Logs.Debug(MODNAME, "Trying again in {} seconds", GetInterval());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,9 @@ class ModuleXLineDB final
|
||||
private:
|
||||
bool dirty;
|
||||
std::string xlinedbpath;
|
||||
unsigned long saveperiod;
|
||||
unsigned long maxbackoff;
|
||||
unsigned char backoff;
|
||||
|
||||
public:
|
||||
ModuleXLineDB()
|
||||
@ -57,7 +60,10 @@ public:
|
||||
*/
|
||||
const auto& Conf = ServerInstance->Config->ConfValue("xlinedb");
|
||||
xlinedbpath = ServerInstance->Config->Paths.PrependData(Conf->getString("filename", "xline.db", 1));
|
||||
SetInterval(Conf->getDuration("saveperiod", 5));
|
||||
saveperiod = Conf->getDuration("saveperiod", 5);
|
||||
backoff = Conf->getNum<uint8_t>("backoff", 0);
|
||||
maxbackoff = Conf->getDuration("maxbackoff", saveperiod * 120, saveperiod);
|
||||
SetInterval(saveperiod);
|
||||
|
||||
// Read xlines before attaching to events
|
||||
ReadDatabase();
|
||||
@ -91,7 +97,20 @@ public:
|
||||
if (dirty)
|
||||
{
|
||||
if (WriteDatabase())
|
||||
{
|
||||
// If we were previously unable to write but now can then reset the time interval.
|
||||
if (GetInterval() != saveperiod)
|
||||
SetInterval(saveperiod, false);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Back off a bit to avoid spamming opers.
|
||||
if (backoff > 1)
|
||||
SetInterval(std::min(GetInterval() * backoff, maxbackoff), false);
|
||||
ServerInstance->Logs.Debug(MODNAME, "Trying again in {} seconds", GetInterval());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user