feat(eventsub): properly unsubscribe once no more handles are interested (#5943)

This commit is contained in:
pajlada
2025-02-09 13:53:31 +01:00
committed by GitHub
parent 7dad35b7a7
commit 9527421bcd
6 changed files with 167 additions and 49 deletions
+18 -10
View File
@@ -22,6 +22,9 @@ class IController
public:
virtual ~IController() = default;
/// Removes one reference for the given subscription request
///
/// Should realistically only be called in the dtor of SubscriptionHandle
virtual void removeRef(const SubscriptionRequest &request) = 0;
/// Subscribe will make a request to each open connection and ask them to
@@ -47,16 +50,18 @@ public:
const SubscriptionRequest &request) override;
private:
void subscribe(const SubscriptionRequest &request, bool isQueued);
void subscribe(const SubscriptionRequest &request, bool isRetry);
void createConnection();
void registerConnection(std::weak_ptr<lib::Session> &&connection);
void queueSubscription(const SubscriptionRequest &request,
boost::posix_time::time_duration delay);
void retrySubscription(const SubscriptionRequest &request,
boost::posix_time::time_duration delay,
int32_t maxAttempts);
void markRequestSubscribed(const SubscriptionRequest &request,
std::weak_ptr<lib::Session> connection);
std::weak_ptr<lib::Session> connection,
const QString &subscriptionID);
const std::string userAgent;
@@ -72,17 +77,20 @@ private:
std::vector<std::weak_ptr<lib::Session>> connections;
struct XD {
struct Subscription {
int32_t refCount = 0;
std::weak_ptr<lib::Session> connection;
/// The ID of the subscription the Twitch Helix API has given us
QString subscriptionID;
/// The timer, if any, for retrying the subscription creation
std::unique_ptr<boost::asio::deadline_timer> retryTimer;
int32_t retryAttempts = 0;
};
std::mutex subscriptionsMutex;
std::unordered_map<SubscriptionRequest, XD> activeSubscriptions;
std::unordered_map<SubscriptionRequest,
std::unique_ptr<boost::asio::deadline_timer>>
queuedSubscriptions;
std::unordered_map<SubscriptionRequest, Subscription> subscriptions;
};
class DummyController : public IController