mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 07:04:27 +00:00
Fix reconnection with connection being lost
After changes regarding to callbacks handling, we accidentally broke the reconnection logic. In particular, forced connection implicitly did disconnect with disconnect callback, but disconnect callback killed our callbacks handling loop for future connection since it was instructed to not reconnect... Pretty convulated logic. Let's attempt to fix and simplify it. There is no forced connection concept anymore, but rather a new reconnect function which either, triggers reconnection through usual disconnection logic, or connects in edge case if we attempted to reconnect with already disconnnected client. This way the status transition is more predictable, as we Connect() only in 3 cases: - Initial start, including !start command, when we actually spawn the callbacks handling loop - Upon disconnection, if we're configured to reconnect - Reconnection, in case we're already disconnected and can't use above And we use reconnect when: - Failure in heartbeats to detect disconnections sooner - Failure in refreshing access tokens, since if we lose our refresh token then the only way to get a new one is to reconnect And finally disconnect is triggered when: - Stopping the bot, especially !stop - Bulletproofing against trying to connect when !KeepRunning and likewise - Usual Steam maintenance and other network issues (which usually trigger reconnection) The codebase is too huge to analyze every possible edge case, but with this logic I can no longer reproduce the previous issue
This commit is contained in:
parent
061e61b740
commit
cefa3e1e1e
1 changed files with 19 additions and 10 deletions
|
@ -1648,7 +1648,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
|
||||
if (string.IsNullOrEmpty(RefreshToken)) {
|
||||
// Without refresh token we can't get fresh access tokens, relog needed
|
||||
await Connect(true).ConfigureAwait(false);
|
||||
await Reconnect().ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1663,7 +1663,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
|
||||
BotDatabase.RefreshToken = RefreshToken = null;
|
||||
|
||||
await Connect(true).ConfigureAwait(false);
|
||||
await Reconnect().ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1674,7 +1674,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
|
||||
ArchiLogger.LogGenericWarning(Strings.FormatWarningFailedWithError(nameof(SteamClient.Authentication.GenerateAccessTokenForAppAsync)));
|
||||
|
||||
await Connect(true).ConfigureAwait(false);
|
||||
await Reconnect().ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1690,7 +1690,7 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
// We got the tokens, but failed to authorize? Purge them just to be sure and reconnect
|
||||
BotDatabase.AccessToken = AccessToken = null;
|
||||
|
||||
await Connect(true).ConfigureAwait(false);
|
||||
await Reconnect().ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
} finally {
|
||||
|
@ -2025,14 +2025,14 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
return gamesToRedeemInBackground;
|
||||
}
|
||||
|
||||
private async Task Connect(bool force = false) {
|
||||
if (!force && (!KeepRunning || SteamClient.IsConnected)) {
|
||||
private async Task Connect() {
|
||||
if (!KeepRunning || SteamClient.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
await LimitLoginRequestsAsync().ConfigureAwait(false);
|
||||
|
||||
if (!force && (!KeepRunning || SteamClient.IsConnected)) {
|
||||
if (!KeepRunning || SteamClient.IsConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2079,11 +2079,11 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
await PluginsCore.OnBotDestroy(this).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void Disconnect() {
|
||||
private void Disconnect(bool reconnect = false) {
|
||||
StopConnectionFailureTimer();
|
||||
|
||||
LastLogOnResult = EResult.OK;
|
||||
ReconnectOnUserInitiated = false;
|
||||
ReconnectOnUserInitiated = reconnect;
|
||||
|
||||
SteamClient.Disconnect();
|
||||
}
|
||||
|
@ -2324,7 +2324,8 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
if (++HeartBeatFailures >= (byte) Math.Ceiling(connectionTimeout / 10.0)) {
|
||||
HeartBeatFailures = byte.MaxValue;
|
||||
ArchiLogger.LogGenericWarning(Strings.BotConnectionLost);
|
||||
Utilities.InBackground(() => Connect(true));
|
||||
|
||||
Utilities.InBackground(Reconnect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3535,6 +3536,14 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
|
|||
WalletCurrency = callback.Currency;
|
||||
}
|
||||
|
||||
private async Task Reconnect() {
|
||||
if (SteamClient.IsConnected) {
|
||||
Disconnect(true);
|
||||
} else {
|
||||
await Connect().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RedeemGamesInBackground(object? state = null) {
|
||||
if (!await GamesRedeemerInBackgroundSemaphore.WaitAsync(0).ConfigureAwait(false)) {
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue