mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 04:21:51 +00:00
proxy_client: resubscribe when a push is rejected as stale
pushNotificationReceived() drops a notification whose session id does not match, and does nothing else. Nothing tells the server it is notifying with a session the client no longer knows, so it keeps waking the device for notifications that can only be discarded, and the values they announce are never fetched. Observed on Android: a call arrives while the account is deactivated in doze. The push carrying the connection request is rejected as stale, so the daemon never learns which value to fetch. The call is only saved by the wake-up side effect: the account reconnects and rediscovers the value through the DHT, which took between 1.7 and 31 seconds across the runs measured. Delivery is left to a race the caller sometimes loses. Treat a session mismatch as evidence that the server holds stale listeners and ask for the subscriptions to be sent again. Reuse listenerRestartTimer_ and the pushSubscriptionPending_ flag, so the recovery path is the same one used when a subscription could not be sent at token time. Stale listeners notify in bursts and rearming the timer cancels the pending wait, so a burst coalesces into a single pass. This complements, and does not replace, sending the subscriptions once the connection is up: that change prevents the mismatch, this one recovers from it if it happens anyway. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
1 parent
79ba60f647
commit
dc912fa8cf
1 file changed
+16
@@ -1285,6 +1285,22 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
|
||||
if (sessionId != notification.end() and sessionId->second != pushSessionId_) {
|
||||
if (logger_)
|
||||
logger_->debug("[proxy:client] [push] ignoring push for other session");
|
||||
// A mismatch proves the server still has a listener registered under a previous
|
||||
// session: it keeps waking this device for notifications that can only be
|
||||
// discarded, and the values they announce are never fetched. Ask for the
|
||||
// subscriptions to be sent again so the server learns the current session,
|
||||
// instead of waiting for an unrelated event to trigger one.
|
||||
//
|
||||
// restartListeners() is rate limited by its own timer: stale listeners notify in
|
||||
// bursts, and rearming the timer on each one simply coalesces them into a single
|
||||
// pass.
|
||||
{
|
||||
std::lock_guard l(lockCurrentProxyInfos_);
|
||||
pushSubscriptionPending_ = true;
|
||||
}
|
||||
listenerRestartTimer_->expires_at(std::chrono::steady_clock::now());
|
||||
listenerRestartTimer_->async_wait(
|
||||
std::bind(&DhtProxyClient::restartListeners, this, std::placeholders::_1));
|
||||
return PushNotificationResult::IgnoredWrongSession;
|
||||
}
|
||||
std::lock_guard lock(searchLock_);
|
||||
|
||||
Reference in new issue
Block a user