Browse Source

Remove GatewayLimits class and other changes

- Remove GatewayLimits
- Transfer a few properties to DiscordSocketConfig
- Remove unnecessary usings
pull/1537/head
SubZero0 5 years ago
parent
commit
6550fafea0
8 changed files with 43 additions and 177 deletions
  1. +0
    -29
      src/Discord.Net.Rest/Entities/Gateway/GatewayLimit.cs
  2. +0
    -100
      src/Discord.Net.Rest/Entities/Gateway/GatewayLimits.cs
  3. +8
    -21
      src/Discord.Net.Rest/Net/Queue/GatewayBucket.cs
  4. +1
    -1
      src/Discord.Net.WebSocket/BaseSocketClient.cs
  5. +5
    -7
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  6. +2
    -2
      src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
  7. +2
    -5
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  8. +25
    -12
      src/Discord.Net.WebSocket/DiscordSocketConfig.cs

+ 0
- 29
src/Discord.Net.Rest/Entities/Gateway/GatewayLimit.cs View File

@@ -1,29 +0,0 @@
namespace Discord.Rest
{
/// <summary>
/// Represents the limits for a gateway request.
/// </summary>
public struct GatewayLimit
{
/// <summary>
/// Gets or sets the maximum amount of this type of request in a time frame, that is set by <see cref="Seconds"/>.
/// </summary>
/// <returns>
/// Returns the maximum amount of this type of request in a time frame to not trigger the rate limit.
/// </returns>
public int Count { get; set; }
/// <summary>
/// Gets or sets the amount of seconds until the rate limiter resets the remaining requests back to <see cref="Count"/>.
/// </summary>
/// <returns>
/// Returns the amount of seconds that define the time frame to reset.
/// </returns>
public int Seconds { get; set; }

internal GatewayLimit(int count, int seconds)
{
Count = count;
Seconds = seconds;
}
}
}

+ 0
- 100
src/Discord.Net.Rest/Entities/Gateway/GatewayLimits.cs View File

@@ -1,100 +0,0 @@
using System;

namespace Discord.Rest
{
/// <summary>
/// Contains the rate limits for the gateway.
/// </summary>
public class GatewayLimits
{
/// <summary>
/// Creates a new <see cref="GatewayLimits"/> with the default values.
/// </summary>
public static GatewayLimits Default => new GatewayLimits();

/// <summary>
/// Gets or sets the global limits for the gateway rate limiter.
/// </summary>
/// <remarks>
/// This property includes all the other limits, like Identify,
/// and it is per websocket.
/// </remarks>
public GatewayLimit Global { get; set; }

/// <summary>
/// Gets or sets the limits of Identify requests.
/// </summary>
/// <remarks>
/// This limit is included into <see cref="Global"/> but it is
/// also per account.
/// </remarks>
public GatewayLimit Identify { get; set; }

/// <summary>
/// Gets or sets the limits of Presence Update requests.
/// </summary>
/// <remarks>
/// Presence updates include activity (playing, watching, etc)
/// and status (online, idle, etc)
/// </remarks>
public GatewayLimit PresenceUpdate { get; set; }

/// <summary>
/// Gets or sets the name of the master <see cref="System.Threading.Semaphore"/>
/// used by identify.
/// </summary>
/// <remarks>
/// It is used to define what slave <see cref="System.Threading.Semaphore"/>
/// is free to run for concurrent identify requests.
/// </remarks>
public string IdentifyMasterSemaphoreName { get; set; }

/// <summary>
/// Gets or sets the name of the slave <see cref="System.Threading.Semaphore"/>
/// used by identify.
/// </summary>
/// <remarks>
/// If the maximum concurrency is higher than one and you are using the sharded client,
/// it will be dinamilly renamed to fit the necessary needs.
/// </remarks>
public string IdentifySemaphoreName { get; set; }

/// <summary>
/// Gets or sets the maximum identify concurrency.
/// </summary>
/// <remarks>
/// This limit is provided by Discord.
/// </remarks>
public int IdentifyMaxConcurrency { get; set; }

/// <summary>
/// Initializes a new <see cref="GatewayLimits"/> with the default values.
/// </summary>
public GatewayLimits()
{
Global = new GatewayLimit(120, 60);
Identify = new GatewayLimit(1, 5);
PresenceUpdate = new GatewayLimit(5, 60);
IdentifyMasterSemaphoreName = Guid.NewGuid().ToString();
IdentifySemaphoreName = Guid.NewGuid().ToString();
IdentifyMaxConcurrency = 1;
}

internal GatewayLimits(GatewayLimits limits)
{
Global = new GatewayLimit(limits.Global.Count, limits.Global.Seconds);
Identify = new GatewayLimit(limits.Identify.Count, limits.Identify.Seconds);
PresenceUpdate = new GatewayLimit(limits.PresenceUpdate.Count, limits.PresenceUpdate.Seconds);
IdentifyMasterSemaphoreName = limits.IdentifyMasterSemaphoreName;
IdentifySemaphoreName = limits.IdentifySemaphoreName;
IdentifyMaxConcurrency = limits.IdentifyMaxConcurrency;
}

internal static GatewayLimits GetOrCreate(GatewayLimits limits)
=> limits ?? Default;

public GatewayLimits Clone()
=> new GatewayLimits(this);
}
}

+ 8
- 21
src/Discord.Net.Rest/Net/Queue/GatewayBucket.cs View File

@@ -11,32 +11,16 @@ namespace Discord.Net.Queue
}
internal struct GatewayBucket
{
private static ImmutableDictionary<GatewayBucketType, GatewayBucket> DefsByType;
private static ImmutableDictionary<string, GatewayBucket> DefsById;
private static readonly ImmutableDictionary<GatewayBucketType, GatewayBucket> DefsByType;
private static readonly ImmutableDictionary<string, GatewayBucket> DefsById;

static GatewayBucket()
{
SetLimits(GatewayLimits.GetOrCreate(null));
}

public static GatewayBucket Get(GatewayBucketType type) => DefsByType[type];
public static GatewayBucket Get(string id) => DefsById[id];

public static void SetLimits(GatewayLimits limits)
{
limits = GatewayLimits.GetOrCreate(limits);
Preconditions.GreaterThan(limits.Global.Count, 0, nameof(limits.Global.Count), "Global count must be greater than zero.");
Preconditions.GreaterThan(limits.Global.Seconds, 0, nameof(limits.Global.Seconds), "Global seconds must be greater than zero.");
Preconditions.GreaterThan(limits.Identify.Count, 0, nameof(limits.Identify.Count), "Identify count must be greater than zero.");
Preconditions.GreaterThan(limits.Identify.Seconds, 0, nameof(limits.Identify.Seconds), "Identify seconds must be greater than zero.");
Preconditions.GreaterThan(limits.PresenceUpdate.Count, 0, nameof(limits.PresenceUpdate.Count), "PresenceUpdate count must be greater than zero.");
Preconditions.GreaterThan(limits.PresenceUpdate.Seconds, 0, nameof(limits.PresenceUpdate.Seconds), "PresenceUpdate seconds must be greater than zero.");

var buckets = new[]
{
new GatewayBucket(GatewayBucketType.Unbucketed, "<gateway-unbucketed>", limits.Global.Count, limits.Global.Seconds),
new GatewayBucket(GatewayBucketType.Identify, "<gateway-identify>", limits.Identify.Count, limits.Identify.Seconds),
new GatewayBucket(GatewayBucketType.PresenceUpdate, "<gateway-presenceupdate>", limits.Identify.Count, limits.Identify.Seconds),
new GatewayBucket(GatewayBucketType.Unbucketed, "<gateway-unbucketed>", 120, 60),
new GatewayBucket(GatewayBucketType.Identify, "<gateway-identify>", 1, 5),
new GatewayBucket(GatewayBucketType.PresenceUpdate, "<gateway-presenceupdate>", 5, 60),
};

var builder = ImmutableDictionary.CreateBuilder<GatewayBucketType, GatewayBucket>();
@@ -50,6 +34,9 @@ namespace Discord.Net.Queue
DefsById = builder2.ToImmutable();
}

public static GatewayBucket Get(GatewayBucketType type) => DefsByType[type];
public static GatewayBucket Get(string id) => DefsById[id];

public GatewayBucketType Type { get; }
public string Id { get; }
public int WindowCount { get; set; }


+ 1
- 1
src/Discord.Net.WebSocket/BaseSocketClient.cs View File

@@ -80,7 +80,7 @@ namespace Discord.WebSocket
internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client)
: base(config, client) => BaseConfig = config;
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayLimits,
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config,
rateLimitPrecision: config.RateLimitPrecision,
useSystemClock: config.UseSystemClock);



+ 5
- 7
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -6,7 +6,6 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
using Discord.Net.Queue;

namespace Discord.WebSocket
{
@@ -67,7 +66,6 @@ namespace Discord.WebSocket
config.DisplayInitialLog = false;
_baseConfig = config;
_connectionGroupLock = new SemaphoreSlim(1, 1);
GatewayBucket.SetLimits(GatewayLimits.GetOrCreate(config.GatewayLimits));

if (config.TotalShards == null)
_automaticShards = true;
@@ -81,15 +79,15 @@ namespace Discord.WebSocket
_shardIdsToIndex.Add(_shardIds[i], i);
var newConfig = config.Clone();
newConfig.ShardId = _shardIds[i];
if (config.GatewayLimits.IdentifyMaxConcurrency != 1)
newConfig.GatewayLimits.IdentifySemaphoreName += $"_{i / config.GatewayLimits.IdentifyMaxConcurrency}";
if (config.IdentifyMaxConcurrency != 1)
newConfig.IdentifySemaphoreName += $"_{i / config.IdentifyMaxConcurrency}";
_shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock, i != 0 ? _shards[0] : null);
RegisterEvents(_shards[i], i == 0);
}
}
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayLimits,
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config,
rateLimitPrecision: config.RateLimitPrecision);

internal override async Task OnLoginAsync(TokenType tokenType, string token)
@@ -101,7 +99,7 @@ namespace Discord.WebSocket
_totalShards = _shardIds.Length;
_shards = new DiscordSocketClient[_shardIds.Length];
int maxConcurrency = botGateway.SessionStartLimit.MaxConcurrency;
_baseConfig.GatewayLimits.IdentifyMaxConcurrency = maxConcurrency;
_baseConfig.IdentifyMaxConcurrency = maxConcurrency;
for (int i = 0; i < _shardIds.Length; i++)
{
_shardIdsToIndex.Add(_shardIds[i], i);
@@ -109,7 +107,7 @@ namespace Discord.WebSocket
newConfig.ShardId = _shardIds[i];
newConfig.TotalShards = _totalShards;
if (maxConcurrency != 1)
newConfig.GatewayLimits.IdentifySemaphoreName += $"_{i / maxConcurrency}";
newConfig.IdentifySemaphoreName += $"_{i / maxConcurrency}";
_shards[i] = new DiscordSocketClient(newConfig, _connectionGroupLock, i != 0 ? _shards[0] : null);
RegisterEvents(_shards[i], i == 0);
}


+ 2
- 2
src/Discord.Net.WebSocket/DiscordSocketApiClient.cs View File

@@ -38,11 +38,11 @@ namespace Discord.API

public ConnectionState ConnectionState { get; private set; }

public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent, GatewayLimits limits,
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent, DiscordSocketConfig config,
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second,
bool useSystemClock = true)
: base(restClientProvider, userAgent, new RequestQueue(limits.IdentifyMasterSemaphoreName, limits.IdentifySemaphoreName, limits.IdentifyMaxConcurrency), defaultRetryMode, serializer, rateLimitPrecision, useSystemClock)
: base(restClientProvider, userAgent, new RequestQueue(config.IdentifyMasterSemaphoreName, config.IdentifySemaphoreName, config.IdentifyMaxConcurrency), defaultRetryMode, serializer, rateLimitPrecision, useSystemClock)
{
_gatewayUrl = url;
if (url != null)


+ 2
- 5
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -119,10 +119,7 @@ namespace Discord.WebSocket
/// </summary>
/// <param name="config">The configuration to be used with the client.</param>
#pragma warning disable IDISP004
public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null)
{
GatewayBucket.SetLimits(GatewayLimits.GetOrCreate(config.GatewayLimits));
}
public DiscordSocketClient(DiscordSocketConfig config) : this(config, CreateApiClient(config), null, null) { }
internal DiscordSocketClient(DiscordSocketConfig config, SemaphoreSlim groupLock, DiscordSocketClient parentClient) : this(config, CreateApiClient(config), groupLock, parentClient) { }
#pragma warning restore IDISP004
private DiscordSocketClient(DiscordSocketConfig config, API.DiscordSocketApiClient client, SemaphoreSlim groupLock, DiscordSocketClient parentClient)
@@ -182,7 +179,7 @@ namespace Discord.WebSocket
_largeGuilds = new ConcurrentQueue<ulong>();
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayLimits, config.GatewayHost,
=> new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config, config.GatewayHost,
rateLimitPrecision: config.RateLimitPrecision);
/// <inheritdoc />
internal override void Dispose(bool disposing)


+ 25
- 12
src/Discord.Net.WebSocket/DiscordSocketConfig.cs View File

@@ -1,7 +1,7 @@
using Discord.Net.Queue;
using Discord.Net.Udp;
using Discord.Net.WebSockets;
using Discord.Rest;
using System;

namespace Discord.WebSocket
{
@@ -126,14 +126,32 @@ namespace Discord.WebSocket
public bool GuildSubscriptions { get; set; } = true;

/// <summary>
/// Gets or sets the gateway limits.
/// Gets or sets the name of the master <see cref="System.Threading.Semaphore"/>
/// used by identify.
/// </summary>
/// <remarks>
/// <note type="warning">
/// This property should only be changed for bots that have special limits provided by Discord.
/// </note>
/// It is used to define what slave <see cref="System.Threading.Semaphore"/>
/// is free to run for concurrent identify requests.
/// </remarks>
public GatewayLimits GatewayLimits { get; set; } = GatewayLimits.Default;
public string IdentifyMasterSemaphoreName { get; set; } = Guid.NewGuid().ToString();

/// <summary>
/// Gets or sets the name of the slave <see cref="System.Threading.Semaphore"/>
/// used by identify.
/// </summary>
/// <remarks>
/// If the maximum concurrency is higher than one and you are using the sharded client,
/// it will be dinamilly renamed to fit the necessary needs.
/// </remarks>
public string IdentifySemaphoreName { get; set; } = Guid.NewGuid().ToString();

/// <summary>
/// Gets or sets the maximum identify concurrency.
/// </summary>
/// <remarks>
/// This information is provided by Discord.
/// </remarks>
public int IdentifyMaxConcurrency { get; set; } = 1;

/// <summary>
/// Initializes a default configuration.
@@ -144,11 +162,6 @@ namespace Discord.WebSocket
UdpSocketProvider = DefaultUdpSocketProvider.Instance;
}

internal DiscordSocketConfig Clone()
{
var clone = MemberwiseClone() as DiscordSocketConfig;
clone.GatewayLimits = GatewayLimits.Clone();
return clone;
}
internal DiscordSocketConfig Clone() => MemberwiseClone() as DiscordSocketConfig;
}
}

Loading…
Cancel
Save