aboutsummaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_filter.cpp39
-rw-r--r--src/modules/m_permchannels.cpp29
-rw-r--r--src/modules/m_xline_db.cpp21
3 files changed, 79 insertions, 10 deletions
diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp
index 312bbc91a..53acb329c 100644
--- a/src/modules/m_filter.cpp
+++ b/src/modules/m_filter.cpp
@@ -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;
diff --git a/src/modules/m_permchannels.cpp b/src/modules/m_permchannels.cpp
index 1d0c713b7..37e11fa55 100644
--- a/src/modules/m_permchannels.cpp
+++ b/src/modules/m_permchannels.cpp
@@ -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;
}
diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp
index 7a3d6e683..aa79e1e10 100644
--- a/src/modules/m_xline_db.cpp
+++ b/src/modules/m_xline_db.cpp
@@ -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;
}