-
Notifications
You must be signed in to change notification settings - Fork 23
correct reading/writing of complete unix timestamps #7
Conversation
Previously timestamps saved with SetNV() were truncated to two decimal places: 1472670993.01 1472670993.012345 Additionally they were also loaded as a double from GetNV() instead of as two longs, and this opened up for comparison errors and meant that when playing back buffers from private queries, the last query was always replayed if it had a certain timestamp, which it would half of the time. ;)
Oh my god. You are my hero. Thank you! |
Awesome, thank you! |
@@ -279,16 +289,15 @@ timeval CClientBufferMod::GetTimestamp(const CBuffer& buffer) const | |||
bool CClientBufferMod::HasSeenTimestamp(const CString& identifier, const CString& target, const timeval& tv) | |||
{ | |||
const timeval seen = GetTimestamp(identifier, target); | |||
return timercmp(&seen, &tv, >); | |||
return timercmp(&seen, &tv, >=); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to man timercmp
, this might be unportable. Consider instead return !timercmp(&seen, &tv, <);
tv.tv_sec = timestamp; | ||
tv.tv_usec = (timestamp - tv.tv_sec) * 1000000; | ||
CString timestamp = GetNV(identifier + "/" + target); | ||
std::sscanf(timestamp.c_str(), "%ld.%06ld", &tv.tv_sec, &tv.tv_usec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to assume that time_t
is 64-bit.
Thank you, confirmed that this patch works! Aside from the portability nits, LGTM :) |
So there’s this one slight issue left… When using |
Yup, I have this issue too. |
My first guess would be that sending a message from a client (identifier) does not update its Let me read into the code… |
Oh, it seems like it’s more complicated. So the timestamp of me sending the PRIVMSG is indeed updated. But the timestamp of this entry in the buffer is slightly off. 300 µs in my case. Hmmmmmmmmmmmmm. Now, that’s a bummer. What do? |
Similar difference (about 300 µs) is happening with channel buffers. But, somehow, we’re not getting those again. From quick look at znc’s source code, I can’t really tell what’s the difference. Both query and channel |
Frankly, I dunno. Until we get something better, here’s a very silly/naïve one, that I’m not proud off… Adding 500 µs to every timestamp. 😞 diff --git a/clientbuffer.cpp b/clientbuffer.cpp
index 7a9079a..3054af3 100644
--- a/clientbuffer.cpp
+++ b/clientbuffer.cpp
@@ -307,6 +307,7 @@ void CClientBufferMod::UpdateTimestamp(const CClient* client, const CString& tar
if (HasClient(identifier)) {
timeval tv;
gettimeofday(&tv, NULL);
+ tv.tv_usec += 500;
SetTimestamp(identifier, target, tv);
}
} |
How did you measure the timestamp difference? I could check this with my setup if I knew how. |
@Jay2k1, here: diff --git a/clientbuffer.cpp b/clientbuffer.cpp
index 7a9079a..1432b3a 100644
--- a/clientbuffer.cpp
+++ b/clientbuffer.cpp
@@ -270,6 +270,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);
+ PutModule("→ SetTimestamp(" + identifier + ", " + target + ", " + timestamp + ")");
return SetNV(identifier + "/" + target, timestamp);
}
It’s more like a rough estimate… But connect with two clients, start a query with someone else, and compare timestamps of your own message between the two connected clients. Nb. this |
OK, did that, results:
I'd like to help think, but I don't understand enough of znc and the language to actually understand how the module works... |
So it’s 600 µs in your case. That’s exactly why my solution is nonsensical and just duct tape. 😜 Each message/line in ZNC, from beginning to end, should have a single timestamp associated with it and accessible from within modules. /cc @psychon |
Sounds like a good idea. An implementation idea would be to add this to Done. I took a look just as requested. :-P |
Uh-huh. =) TY! I’ll copy this to the ZNC repo, too. |
Aha, great 😄 |
Previously timestamps saved with SetNV() were truncated to two decimal places:
1472670993.01
1472670993.012345
Additionally they were also loaded as a double from GetNV() instead of as
two longs, and this opened up for comparison errors and meant that when
playing back buffers from private queries, the last query was always replayed
if it had a certain timestamp, which it would half of the time. ;)
This addresses issue #6