fix: request more historical messages on wake (#5018)

This commit is contained in:
iProdigy 2023-12-16 06:38:35 -06:00 committed by GitHub
parent 5f8c4c6b66
commit e75ce5db54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 48 additions and 19 deletions

View file

@ -88,6 +88,7 @@
- Dev: Move `clang-tidy` checker to its own CI job. (#4996) - Dev: Move `clang-tidy` checker to its own CI job. (#4996)
- Dev: Refactored the Image Uploader feature. (#4971) - Dev: Refactored the Image Uploader feature. (#4971)
- Dev: Fixed deadlock and use-after-free in tests. (#4981) - Dev: Fixed deadlock and use-after-free in tests. (#4981)
- Dev: Load less message history upon reconnects. (#5001, #5018)
- Dev: Load less message history upon reconnects. (#5001) - Dev: Load less message history upon reconnects. (#5001)
- Dev: BREAKING: Replace custom `import()` with normal Lua `require()`. (#5014) - Dev: BREAKING: Replace custom `import()` with normal Lua `require()`. (#5014)
- Dev: Fixed most compiler warnings. (#5028) - Dev: Fixed most compiler warnings. (#5028)

View file

@ -85,6 +85,9 @@ AbstractIrcServer::AbstractIrcServer()
} }
this->readConnection_->smartReconnect(); this->readConnection_->smartReconnect();
}); });
this->connections_.managedConnect(this->readConnection_->heartbeat, [this] {
this->markChannelsConnected();
});
} }
void AbstractIrcServer::initializeIrc() void AbstractIrcServer::initializeIrc()
@ -358,11 +361,21 @@ void AbstractIrcServer::onDisconnected()
if (auto *channel = dynamic_cast<TwitchChannel *>(chan.get())) if (auto *channel = dynamic_cast<TwitchChannel *>(chan.get()))
{ {
channel->markDisconnectedNow(); channel->markDisconnected();
} }
} }
} }
void AbstractIrcServer::markChannelsConnected()
{
this->forEachChannel([](const ChannelPtr &chan) {
if (auto *channel = dynamic_cast<TwitchChannel *>(chan.get()))
{
channel->markConnected();
}
});
}
std::shared_ptr<Channel> AbstractIrcServer::getCustomChannel( std::shared_ptr<Channel> AbstractIrcServer::getCustomChannel(
const QString &channelName) const QString &channelName)
{ {

View file

@ -73,6 +73,7 @@ protected:
virtual void onReadConnected(IrcConnection *connection); virtual void onReadConnected(IrcConnection *connection);
virtual void onWriteConnected(IrcConnection *connection); virtual void onWriteConnected(IrcConnection *connection);
virtual void onDisconnected(); virtual void onDisconnected();
void markChannelsConnected();
virtual std::shared_ptr<Channel> getCustomChannel( virtual std::shared_ptr<Channel> getCustomChannel(
const QString &channelName); const QString &channelName);

View file

@ -64,6 +64,7 @@ IrcConnection::IrcConnection(QObject *parent)
// If we're still receiving messages, all is well // If we're still receiving messages, all is well
this->recentlyReceivedMessage_ = false; this->recentlyReceivedMessage_ = false;
this->waitingForPong_ = false; this->waitingForPong_ = false;
this->heartbeat.invoke();
return; return;
} }

View file

@ -19,6 +19,9 @@ public:
// receiver to trigger a reconnect, if desired // receiver to trigger a reconnect, if desired
pajlada::Signals::Signal<bool> connectionLost; pajlada::Signals::Signal<bool> connectionLost;
// Signal to indicate the connection is still healthy
pajlada::Signals::NoArgSignal heartbeat;
// Request a reconnect with a minimum interval between attempts. // Request a reconnect with a minimum interval between attempts.
// This won't violate RECONNECT_MIN_INTERVAL // This won't violate RECONNECT_MIN_INTERVAL
void smartReconnect(); void smartReconnect();

View file

@ -103,10 +103,11 @@ TwitchChannel::TwitchChannel(const QString &name)
// We can safely ignore this signal connection this has no external dependencies - once the signal // We can safely ignore this signal connection this has no external dependencies - once the signal
// is destroyed, it will no longer be able to fire // is destroyed, it will no longer be able to fire
std::ignore = this->joined.connect([this]() { std::ignore = this->joined.connect([this]() {
if (this->disconnectedAt_.has_value()) if (this->disconnected_)
{ {
this->loadRecentMessagesReconnect(); this->loadRecentMessagesReconnect();
this->disconnectedAt_ = std::nullopt; this->lastConnectedAt_ = std::chrono::system_clock::now();
this->disconnected_ = false;
} }
}); });
@ -731,6 +732,8 @@ void TwitchChannel::setRoomId(const QString &id)
*this->roomID_.access() = id; *this->roomID_.access() = id;
this->roomIdChanged(); this->roomIdChanged();
this->loadRecentMessages(); this->loadRecentMessages();
this->disconnected_ = false;
this->lastConnectedAt_ = std::chrono::system_clock::now();
} }
} }
@ -1105,7 +1108,15 @@ bool TwitchChannel::setLive(bool newLiveStatus)
return true; return true;
} }
void TwitchChannel::markDisconnectedNow() void TwitchChannel::markConnected()
{
if (this->lastConnectedAt_.has_value() && !this->disconnected_)
{
this->lastConnectedAt_ = std::chrono::system_clock::now();
}
}
void TwitchChannel::markDisconnected()
{ {
if (this->roomId().isEmpty()) if (this->roomId().isEmpty())
{ {
@ -1113,14 +1124,7 @@ void TwitchChannel::markDisconnectedNow()
return; return;
} }
if (this->disconnectedAt_.has_value()) this->disconnected_ = true;
{
// don't overwrite prior timestamp since
// a reconnection hasn't happened yet
return;
}
this->disconnectedAt_ = std::chrono::system_clock::now();
} }
void TwitchChannel::loadRecentMessages() void TwitchChannel::loadRecentMessages()
@ -1194,14 +1198,14 @@ void TwitchChannel::loadRecentMessagesReconnect()
const auto now = std::chrono::system_clock::now(); const auto now = std::chrono::system_clock::now();
int limit = getSettings()->twitchMessageHistoryLimit.getValue(); int limit = getSettings()->twitchMessageHistoryLimit.getValue();
if (this->disconnectedAt_.has_value()) if (this->lastConnectedAt_.has_value())
{ {
// calculate how many messages could have occured // calculate how many messages could have occured
// while we were not connected to the channel // while we were not connected to the channel
// assuming a maximum of 10 messages per second // assuming a maximum of 10 messages per second
const auto secondsSinceDisconnect = const auto secondsSinceDisconnect =
std::chrono::duration_cast<std::chrono::seconds>( std::chrono::duration_cast<std::chrono::seconds>(
now - this->disconnectedAt_.value()) now - this->lastConnectedAt_.value())
.count(); .count();
limit = limit =
std::min(static_cast<int>(secondsSinceDisconnect + 1) * 10, limit); std::min(static_cast<int>(secondsSinceDisconnect + 1) * 10, limit);
@ -1233,7 +1237,7 @@ void TwitchChannel::loadRecentMessagesReconnect()
tc->loadingRecentMessages_.clear(); tc->loadingRecentMessages_.clear();
}, },
limit, this->disconnectedAt_, now, true); limit, this->lastConnectedAt_, now, true);
} }
void TwitchChannel::refreshPubSub() void TwitchChannel::refreshPubSub()

View file

@ -137,10 +137,14 @@ public:
SharedAccessGuard<const StreamStatus> accessStreamStatus() const; SharedAccessGuard<const StreamStatus> accessStreamStatus() const;
/** /**
* Records the current timestamp the channel was disconnected. * Records that the channel is no longer joined.
* This can be used to calculate the time spent disconnected after a successful reconnect
*/ */
void markDisconnectedNow(); void markDisconnected();
/**
* Records that the channel's read connection is healthy.
*/
void markConnected();
// Emotes // Emotes
std::optional<EmotePtr> bttvEmote(const EmoteName &name) const; std::optional<EmotePtr> bttvEmote(const EmoteName &name) const;
@ -364,8 +368,9 @@ private:
int chatterCount_{}; int chatterCount_{};
UniqueAccess<StreamStatus> streamStatus_; UniqueAccess<StreamStatus> streamStatus_;
UniqueAccess<RoomModes> roomModes_; UniqueAccess<RoomModes> roomModes_;
bool disconnected_{};
std::optional<std::chrono::time_point<std::chrono::system_clock>> std::optional<std::chrono::time_point<std::chrono::system_clock>>
disconnectedAt_{}; lastConnectedAt_{};
std::atomic_flag loadingRecentMessages_ = ATOMIC_FLAG_INIT; std::atomic_flag loadingRecentMessages_ = ATOMIC_FLAG_INIT;
std::unordered_map<QString, std::weak_ptr<MessageThread>> threads_; std::unordered_map<QString, std::weak_ptr<MessageThread>> threads_;

View file

@ -220,6 +220,7 @@ void TwitchIrcServer::readConnectionMessageReceived(
{ {
this->addGlobalSystemMessage( this->addGlobalSystemMessage(
"Twitch Servers requested us to reconnect, reconnecting"); "Twitch Servers requested us to reconnect, reconnecting");
this->markChannelsConnected();
this->connect(); this->connect();
} }
else if (command == "GLOBALUSERSTATE") else if (command == "GLOBALUSERSTATE")