Fixed rapid reconnects and reconnects triggering before a successful connect
This commit is contained in:
@@ -35,6 +35,7 @@ namespace Discord
|
||||
private int _unavailableGuilds;
|
||||
private long _lastGuildAvailableTime;
|
||||
private int _nextAudioId;
|
||||
private bool _canReconnect;
|
||||
|
||||
/// <summary> Gets the shard if of this client. </summary>
|
||||
public int ShardId { get; }
|
||||
@@ -114,7 +115,7 @@ namespace Discord
|
||||
protected override async Task OnLogoutAsync()
|
||||
{
|
||||
if (ConnectionState != ConnectionState.Disconnected)
|
||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
||||
await DisconnectInternalAsync(null, false).ConfigureAwait(false);
|
||||
|
||||
_voiceRegions = ImmutableDictionary.Create<string, VoiceRegion>();
|
||||
}
|
||||
@@ -125,7 +126,7 @@ namespace Discord
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await ConnectInternalAsync().ConfigureAwait(false);
|
||||
await ConnectInternalAsync(false).ConfigureAwait(false);
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
|
||||
@@ -136,17 +137,17 @@ namespace Discord
|
||||
await _guildDownloadTask.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
private async Task ConnectInternalAsync()
|
||||
private async Task ConnectInternalAsync(bool isReconnecting)
|
||||
{
|
||||
if (LoginState != LoginState.LoggedIn)
|
||||
throw new InvalidOperationException("You must log in before connecting.");
|
||||
|
||||
if (_reconnectCancelToken != null && !_reconnectCancelToken.IsCancellationRequested)
|
||||
if (!isReconnecting && _reconnectCancelToken != null && !_reconnectCancelToken.IsCancellationRequested)
|
||||
_reconnectCancelToken.Cancel();
|
||||
|
||||
var state = ConnectionState;
|
||||
if (state == ConnectionState.Connecting || state == ConnectionState.Connected)
|
||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
||||
await DisconnectInternalAsync(null, isReconnecting).ConfigureAwait(false);
|
||||
|
||||
ConnectionState = ConnectionState.Connecting;
|
||||
await _gatewayLogger.InfoAsync("Connecting").ConfigureAwait(false);
|
||||
@@ -164,12 +165,13 @@ namespace Discord
|
||||
await ApiClient.SendIdentifyAsync().ConfigureAwait(false);
|
||||
|
||||
await _connectTask.Task.ConfigureAwait(false);
|
||||
_canReconnect = true;
|
||||
ConnectionState = ConnectionState.Connected;
|
||||
await _gatewayLogger.InfoAsync("Connected").ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
||||
await DisconnectInternalAsync(null, isReconnecting).ConfigureAwait(false);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -180,7 +182,7 @@ namespace Discord
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
||||
await DisconnectInternalAsync(null, false).ConfigureAwait(false);
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
}
|
||||
@@ -190,14 +192,18 @@ namespace Discord
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await DisconnectInternalAsync(ex).ConfigureAwait(false);
|
||||
await DisconnectInternalAsync(ex, false).ConfigureAwait(false);
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
}
|
||||
private async Task DisconnectInternalAsync(Exception ex)
|
||||
private async Task DisconnectInternalAsync(Exception ex, bool isReconnecting)
|
||||
{
|
||||
if (_reconnectCancelToken != null && !_reconnectCancelToken.IsCancellationRequested)
|
||||
_reconnectCancelToken.Cancel();
|
||||
if (!isReconnecting)
|
||||
{
|
||||
_canReconnect = false;
|
||||
if (_reconnectCancelToken != null && !_reconnectCancelToken.IsCancellationRequested)
|
||||
_reconnectCancelToken.Cancel();
|
||||
}
|
||||
|
||||
ulong guildId;
|
||||
|
||||
@@ -242,7 +248,8 @@ namespace Discord
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await DisconnectInternalAsync(null).ConfigureAwait(false);
|
||||
if (!_canReconnect || _reconnectTask != null) return;
|
||||
await DisconnectInternalAsync(null, true).ConfigureAwait(false);
|
||||
_reconnectCancelToken = new CancellationTokenSource();
|
||||
_reconnectTask = ReconnectInternalAsync(_reconnectCancelToken.Token);
|
||||
}
|
||||
@@ -253,34 +260,37 @@ namespace Discord
|
||||
try
|
||||
{
|
||||
int nextReconnectDelay = 1000;
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(nextReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
nextReconnectDelay *= 2;
|
||||
if (nextReconnectDelay > 30000)
|
||||
nextReconnectDelay = 30000;
|
||||
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await Task.Delay(nextReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
nextReconnectDelay *= 2;
|
||||
if (nextReconnectDelay > 30000)
|
||||
nextReconnectDelay = 30000;
|
||||
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (cancelToken.IsCancellationRequested) return;
|
||||
await ConnectInternalAsync().ConfigureAwait(false);
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
if (cancelToken.IsCancellationRequested) return;
|
||||
await ConnectInternalAsync(true).ConfigureAwait(false);
|
||||
_reconnectTask = null;
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _gatewayLogger.WarningAsync("Reconnect failed", ex).ConfigureAwait(false);
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
finally
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
_reconnectTask = null;
|
||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
await _gatewayLogger.DebugAsync("Reconnect cancelled").ConfigureAwait(false);
|
||||
_reconnectTask = null;
|
||||
}
|
||||
finally { _connectionLock.Release(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user