Attempt at a more resilient shard handler
Signed-off-by: Ske <voltasalt@gmail.com>
This commit is contained in:
parent
8b948bcfbb
commit
6ea1309ae0
@ -74,6 +74,7 @@ namespace Myriad.Gateway
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ConnectInner();
|
await ConnectInner();
|
||||||
|
|
||||||
await HandleConnectionOpened();
|
await HandleConnectionOpened();
|
||||||
|
|
||||||
while (_conn.State == WebSocketState.Open)
|
while (_conn.State == WebSocketState.Open)
|
||||||
@ -92,6 +93,7 @@ namespace Myriad.Gateway
|
|||||||
|
|
||||||
if (_reconnectDelay > TimeSpan.Zero)
|
if (_reconnectDelay > TimeSpan.Zero)
|
||||||
await Task.Delay(_reconnectDelay);
|
await Task.Delay(_reconnectDelay);
|
||||||
|
_reconnectDelay = TimeSpan.Zero;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -120,11 +122,23 @@ namespace Myriad.Gateway
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task ConnectInner()
|
private async Task ConnectInner()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
await _ratelimiter.Acquire(_info.ShardId);
|
await _ratelimiter.Acquire(_info.ShardId);
|
||||||
|
|
||||||
_logger.Information("Shard {ShardId}: Connecting to WebSocket", _info.ShardId);
|
_logger.Information("Shard {ShardId}: Connecting to WebSocket", _info.ShardId);
|
||||||
|
try
|
||||||
|
{
|
||||||
await _conn.Connect(_url, default);
|
await _conn.Connect(_url, default);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (WebSocketException e)
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Shard {ShardId}: Error connecting to WebSocket, retrying in 5 seconds...", _info.ShardId);
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DisconnectInner(WebSocketCloseStatus closeStatus)
|
private async Task DisconnectInner(WebSocketCloseStatus closeStatus)
|
||||||
|
@ -39,7 +39,8 @@ namespace Myriad.Gateway
|
|||||||
|
|
||||||
public async Task Send(GatewayPacket packet)
|
public async Task Send(GatewayPacket packet)
|
||||||
{
|
{
|
||||||
if (_client == null || _client.State != WebSocketState.Open)
|
// from `ManagedWebSocket.s_validSendStates`
|
||||||
|
if (_client is not {State: WebSocketState.Open or WebSocketState.CloseReceived})
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -60,7 +61,8 @@ namespace Myriad.Gateway
|
|||||||
|
|
||||||
public async Task<GatewayPacket?> Read()
|
public async Task<GatewayPacket?> Read()
|
||||||
{
|
{
|
||||||
if (_client == null || _client.State != WebSocketState.Open)
|
// from `ManagedWebSocket.s_validReceiveStates`
|
||||||
|
if (_client is not {State: WebSocketState.Open or WebSocketState.CloseSent})
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -71,6 +73,8 @@ namespace Myriad.Gateway
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Error(e, "Error reading from WebSocket");
|
_logger.Error(e, "Error reading from WebSocket");
|
||||||
|
// force close so we can "reset"
|
||||||
|
await CloseInner(WebSocketCloseStatus.NormalClosure, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -86,19 +90,33 @@ namespace Myriad.Gateway
|
|||||||
if (_client == null)
|
if (_client == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_client.State != WebSocketState.Connecting && _client.State != WebSocketState.Open)
|
var client = _client;
|
||||||
return;
|
_client = null;
|
||||||
|
|
||||||
|
// from `ManagedWebSocket.s_validCloseStates`
|
||||||
|
if (client.State is WebSocketState.Open or WebSocketState.CloseReceived or WebSocketState.CloseSent)
|
||||||
|
{
|
||||||
// Close with timeout, mostly to work around https://github.com/dotnet/runtime/issues/51590
|
// Close with timeout, mostly to work around https://github.com/dotnet/runtime/issues/51590
|
||||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _client.CloseAsync(closeStatus, description, cts.Token);
|
await client.CloseAsync(closeStatus, description, cts.Token);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Error(e, "Error closing WebSocket connection");
|
_logger.Error(e, "Error closing WebSocket connection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This shouldn't need to be wrapped in a try/catch but doing it anyway :/
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(e, "Error disposing WebSocket connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user