WIP new shard implementation
This commit is contained in:
@@ -15,6 +15,7 @@ namespace Myriad.Gateway
|
||||
private readonly GatewaySettings _gatewaySettings;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ConcurrentDictionary<int, Shard> _shards = new();
|
||||
private ShardIdentifyRatelimiter? _ratelimiter;
|
||||
|
||||
public Cluster(GatewaySettings gatewaySettings, ILogger logger)
|
||||
{
|
||||
@@ -26,81 +27,35 @@ namespace Myriad.Gateway
|
||||
public event Action<Shard>? ShardCreated;
|
||||
|
||||
public IReadOnlyDictionary<int, Shard> Shards => _shards;
|
||||
public ClusterSessionState SessionState => GetClusterState();
|
||||
public User? User => _shards.Values.Select(s => s.User).FirstOrDefault(s => s != null);
|
||||
public ApplicationPartial? Application => _shards.Values.Select(s => s.Application).FirstOrDefault(s => s != null);
|
||||
|
||||
private ClusterSessionState GetClusterState()
|
||||
|
||||
public async Task Start(GatewayInfo.Bot info)
|
||||
{
|
||||
var shards = new List<ClusterSessionState.ShardState>();
|
||||
foreach (var (id, shard) in _shards)
|
||||
shards.Add(new ClusterSessionState.ShardState
|
||||
{
|
||||
Shard = shard.ShardInfo,
|
||||
Session = shard.SessionInfo
|
||||
});
|
||||
|
||||
return new ClusterSessionState {Shards = shards};
|
||||
var concurrency = GetActualShardConcurrency(info.SessionStartLimit.MaxConcurrency);
|
||||
_ratelimiter = new(_logger, concurrency);
|
||||
|
||||
await Start(info.Url, info.Shards);
|
||||
}
|
||||
|
||||
public async Task Start(GatewayInfo.Bot info, ClusterSessionState? lastState = null)
|
||||
{
|
||||
if (lastState != null && lastState.Shards.Count == info.Shards)
|
||||
await Resume(info.Url, lastState, info.SessionStartLimit.MaxConcurrency);
|
||||
else
|
||||
await Start(info.Url, info.Shards, info.SessionStartLimit.MaxConcurrency);
|
||||
}
|
||||
|
||||
public async Task Resume(string url, ClusterSessionState sessionState, int concurrency)
|
||||
{
|
||||
_logger.Information("Resuming session with {ShardCount} shards at {Url}", sessionState.Shards.Count, url);
|
||||
foreach (var shardState in sessionState.Shards)
|
||||
CreateAndAddShard(url, shardState.Shard, shardState.Session);
|
||||
|
||||
await StartShards(concurrency);
|
||||
}
|
||||
|
||||
public async Task Start(string url, int shardCount, int concurrency)
|
||||
public async Task Start(string url, int shardCount)
|
||||
{
|
||||
_logger.Information("Starting {ShardCount} shards at {Url}", shardCount, url);
|
||||
for (var i = 0; i < shardCount; i++)
|
||||
CreateAndAddShard(url, new ShardInfo(i, shardCount), null);
|
||||
CreateAndAddShard(url, new ShardInfo(i, shardCount));
|
||||
|
||||
await StartShards(concurrency);
|
||||
await StartShards();
|
||||
}
|
||||
private async Task StartShards(int concurrency)
|
||||
private async Task StartShards()
|
||||
{
|
||||
concurrency = GetActualShardConcurrency(concurrency);
|
||||
|
||||
var lastTime = DateTimeOffset.UtcNow;
|
||||
var identifyCalls = 0;
|
||||
|
||||
_logger.Information("Connecting shards...");
|
||||
foreach (var shard in _shards.Values)
|
||||
{
|
||||
if (identifyCalls >= concurrency)
|
||||
{
|
||||
var timeout = lastTime + TimeSpan.FromSeconds(5.5);
|
||||
var delay = timeout - DateTimeOffset.UtcNow;
|
||||
|
||||
if (delay > TimeSpan.Zero)
|
||||
{
|
||||
_logger.Information("Hit shard concurrency limit, waiting {Delay}", delay);
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
|
||||
identifyCalls = 0;
|
||||
lastTime = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
foreach (var shard in _shards.Values)
|
||||
await shard.Start();
|
||||
identifyCalls++;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateAndAddShard(string url, ShardInfo shardInfo, ShardSessionInfo? session)
|
||||
private void CreateAndAddShard(string url, ShardInfo shardInfo)
|
||||
{
|
||||
var shard = new Shard(_logger, new Uri(url), _gatewaySettings, shardInfo, session);
|
||||
var shard = new Shard(_gatewaySettings, shardInfo, _ratelimiter!, url, _logger);
|
||||
shard.OnEventReceived += evt => OnShardEventReceived(shard, evt);
|
||||
_shards[shardInfo.ShardId] = shard;
|
||||
|
||||
|
Reference in New Issue
Block a user