-
Notifications
You must be signed in to change notification settings - Fork 23
High disk IO when running WHO query #9
Comments
This is indeed insane, when you look at the code. =) E.g. for each entry in the buffer, when playing it back, we’re reading the last seen timestamp again and again… |
We’d be way better off if all the data was kept in memory with occasional (even as often once a second) dump to disk. |
I'd like to mention the optional third parameter for You could then always call (Does it make sense to make this change in ZNC instead, so that it always writes Edit: Oh and ZNC does already keep all the NV-data in memory. :-) |
@psychon, awesome! ❤️ So this is trivial to fix (cc @RX14): diff --git a/clientbuffer.cpp b/clientbuffer.cpp
index 7a9079a..925ae7c 100644
--- a/clientbuffer.cpp
+++ b/clientbuffer.cpp
@@ -29,6 +29,21 @@
#error The clientbuffer module requires ZNC version 1.6.0 or later.
#endif
+class CClientBufferCacheJob : public CTimer
+{
+public:
+ CClientBufferCacheJob(CModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription)
+ : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {}
+ virtual ~CClientBufferCacheJob() {}
+
+protected:
+ virtual void RunJob();
+};
+
+void CClientBufferCacheJob::RunJob() {
+ GetModule()->SaveRegistry();
+}
+
class CClientBufferMod : public CModule
{
public:
@@ -38,6 +53,7 @@ public:
AddCommand("AddClient", static_cast<CModCommand::ModCmdFunc>(&CClientBufferMod::OnAddClientCommand), "<identifier>", "Add a client.");
AddCommand("DelClient", static_cast<CModCommand::ModCmdFunc>(&CClientBufferMod::OnDelClientCommand), "<identifier>", "Delete a client.");
AddCommand("ListClients", static_cast<CModCommand::ModCmdFunc>(&CClientBufferMod::OnListClientsCommand), "", "List known clients.");
+ AddTimer(new CClientBufferCacheJob(this, 60 /* sec */, 0, "ClientBufferCache", "Periodically save ClientBuffer registry to disk"));
}
void OnAddClientCommand(const CString& line);
@@ -211,7 +227,7 @@ CModule::EModRet CClientBufferMod::OnPrivBufferPlayLine2(CClient& client, CStrin
// returns true if the new client was successfully written to disk
bool CClientBufferMod::AddClient(const CString& identifier)
{
- return SetNV(identifier, "");
+ return SetNV(identifier, "", false);
}
bool CClientBufferMod::DelClient(const CString& identifier)
@@ -224,7 +240,7 @@ bool CClientBufferMod::DelClient(const CString& identifier)
}
bool success = true;
for (const CString& key : keys)
- success &= DelNV(key);
+ success &= DelNV(key, false);
return success;
}
@@ -270,7 +286,7 @@ bool CClientBufferMod::SetTimestamp(const CString& identifier, const CString& ta
{
char timestamp[32];
std::snprintf(timestamp, 32, "%ld.%06ld", tv.tv_sec, tv.tv_usec);
- return SetNV(identifier + "/" + target, timestamp);
+ return SetNV(identifier + "/" + target, timestamp, false);
}
timeval CClientBufferMod::GetTimestamp(const CString& identifier, const CString& target) @psychon, yes, I would argue that this seems like a common pattern and it should be abstracted away to the ZNC core. A good flow might be:
This minimizes IO and benefits all. There’s this slight downside: if a module tries to save something with the new default I’ll copy this to the ZNC repo. @psychon, as you clearly know ZNC’s innards, could you, please, also take a look at #7 (comment) ? |
See jpnurmi#9 Adapted from MAGICCC@dd848d4
See jpnurmi#9 Adapted from MAGICCC@dd848d4
@michalrus Thanks! I've improved on your patch (which @BtbN incorporated as a commit) by only flushing when we edited the registry. I agree that making this the standard behaviour for ZNC in general would be much better, though. |
makefile: respect PREFIX, LIBDIR and DESTDIR
When a WHO query is run through znc, for the entire time who responses are being received, ~5mbps of disk IO happens.
strace
shows this (who on a channel with 975 members):The culprit seems to be an
open("/data/znc/znc-data//users/RX14/networks/esper/moddata/clientbuffer/.registry", O_WRONLY|O_CREAT|O_TRUNC, 0600)
, followed by a crazy amount ofwrite
calls (15433 for a who on a channel with only 7 members).See znc/znc#1275 for more details.
The text was updated successfully, but these errors were encountered: