JsonRpcConnection: Don't drop client from cache prematurely

PR #7445 incorrectly assumed that a peer that had already disconnected
and never reconnected was due to the endpoint client being dropped after
a successful socket shutdown. However, the issue at that time was that
there was not a single timeout guards that could cancel the `async_shutdown`
call, petentially blocking indefinetely. Although removing the client from
cache early might have allowed the endpoint to reconnect, it did not
resolve the underlying problem. Now that we have a proper cancellation
timeout, we can wait until the currently used socket is fully closed
before dropping the client from our cache. When our socket termination
works reliably, the `ApiListener` reconnect timer should attempt to
reconnect this endpoint after the next tick. Additionally, we now have
logs both for before and after socket termination, which may help
identify if it is hanging somewhere in between.
This commit is contained in:
Yonas Habteab 2024-10-31 10:19:40 +01:00
parent fba56f0e61
commit 3af7cfe2ec
1 changed files with 6 additions and 10 deletions

View File

@ -254,16 +254,6 @@ void JsonRpcConnection::Disconnect()
Log(LogWarning, "JsonRpcConnection")
<< "API client disconnected for identity '" << m_Identity << "'";
// We need to unregister the endpoint client as soon as possible not to confuse Icinga 2,
// given that Endpoint::GetConnected() is just performing a check that the endpoint's client
// cache is not empty, which could result in an already disconnected endpoint never trying to
// reconnect again. See #7444.
if (m_Endpoint) {
m_Endpoint->RemoveClient(this);
} else {
ApiListener::GetInstance()->RemoveAnonymousClient(this);
}
m_OutgoingMessagesQueued.Set();
m_WriterDone.Wait(yc);
@ -272,6 +262,12 @@ void JsonRpcConnection::Disconnect()
m_HeartbeatTimer.cancel();
m_Stream->GracefulDisconnect(m_IoStrand, yc);
if (m_Endpoint) {
m_Endpoint->RemoveClient(this);
} else {
ApiListener::GetInstance()->RemoveAnonymousClient(this);
}
});
}
}