Browse Source

Fix Ready and AlwaysDownloadUsers

Ready could fire before downloading all guild data and downloading guild users one guild per time without gateway intents is a waste of a gateway request that can support up to 1000.
pull/1548/head
Paulo 5 years ago
parent
commit
4d318356f0
3 changed files with 38 additions and 4 deletions
  1. +6
    -1
      src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs
  2. +6
    -3
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  3. +26
    -0
      src/Discord.Net.WebSocket/DiscordSocketConfig.cs

+ 6
- 1
src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs View File

@@ -21,7 +21,12 @@ namespace Discord.WebSocket
remove { _disconnectedEvent.Remove(value); } remove { _disconnectedEvent.Remove(value); }
} }
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>(); private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>();
/// <summary> Fired when guild data has finished downloading. </summary>
/// <summary>
/// Fired when guild data has finished downloading.
/// </summary>
/// <remarks>
/// It is possible that some guilds might be unsynced if <see cref="DiscordSocketConfig.MaxWaitBetweenGuildAvailablesBeforeReady" /> was not long enough to receive all GUILD_AVAILABLES before READY.
/// </remarks>
public event Func<Task> Ready public event Func<Task> Ready
{ {
add { _readyEvent.Add(value); } add { _readyEvent.Add(value); }


+ 6
- 3
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -167,7 +167,7 @@ namespace Discord.WebSocket


GuildAvailable += g => GuildAvailable += g =>
{ {
if (ConnectionState == ConnectionState.Connected && AlwaysDownloadUsers && !g.HasAllMembers)
if (_guildDownloadTask?.IsCompleted == true && ConnectionState == ConnectionState.Connected && AlwaysDownloadUsers && !g.HasAllMembers)
{ {
var _ = g.DownloadUsersAsync(); var _ = g.DownloadUsersAsync();
} }
@@ -368,7 +368,7 @@ namespace Discord.WebSocket
{ {
var cachedGuilds = guilds.ToImmutableArray(); var cachedGuilds = guilds.ToImmutableArray();


const short batchSize = 50;
const short batchSize = 1000; //TODO: Gateway Intents will limit to a maximum of 1 guild_id
ulong[] batchIds = new ulong[Math.Min(batchSize, cachedGuilds.Length)]; ulong[] batchIds = new ulong[Math.Min(batchSize, cachedGuilds.Length)];
Task[] batchTasks = new Task[batchIds.Length]; Task[] batchTasks = new Task[batchIds.Length];
int batchCount = (cachedGuilds.Length + (batchSize - 1)) / batchSize; int batchCount = (cachedGuilds.Length + (batchSize - 1)) / batchSize;
@@ -576,6 +576,9 @@ namespace Discord.WebSocket
} }
else if (_connection.CancelToken.IsCancellationRequested) else if (_connection.CancelToken.IsCancellationRequested)
return; return;
if (BaseConfig.AlwaysDownloadUsers)
_ = DownloadUsersAsync(Guilds.Where(x => x.IsAvailable && !x.HasAllMembers));


await TimedInvokeAsync(_readyEvent, nameof(Ready)).ConfigureAwait(false); await TimedInvokeAsync(_readyEvent, nameof(Ready)).ConfigureAwait(false);
await _gatewayLogger.InfoAsync("Ready").ConfigureAwait(false); await _gatewayLogger.InfoAsync("Ready").ConfigureAwait(false);
@@ -1742,7 +1745,7 @@ namespace Discord.WebSocket
try try
{ {
await logger.DebugAsync("GuildDownloader Started").ConfigureAwait(false); await logger.DebugAsync("GuildDownloader Started").ConfigureAwait(false);
while ((_unavailableGuildCount != 0) && (Environment.TickCount - _lastGuildAvailableTime < 2000))
while ((_unavailableGuildCount != 0) && (Environment.TickCount - _lastGuildAvailableTime < BaseConfig.MaxWaitBetweenGuildAvailablesBeforeReady))
await Task.Delay(500, cancelToken).ConfigureAwait(false); await Task.Delay(500, cancelToken).ConfigureAwait(false);
await logger.DebugAsync("GuildDownloader Stopped").ConfigureAwait(false); await logger.DebugAsync("GuildDownloader Stopped").ConfigureAwait(false);
} }


+ 26
- 0
src/Discord.Net.WebSocket/DiscordSocketConfig.cs View File

@@ -124,6 +124,32 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public bool GuildSubscriptions { get; set; } = true; public bool GuildSubscriptions { get; set; } = true;


/// <summary>
/// Gets or sets the maximum wait time in milliseconds between GUILD_AVAILABLE events before firing READY.
///
/// If zero, READY will fire as soon as it is received and all guilds will be unavailable.
/// </summary>
/// <remarks>
/// <para>This property is measured in milliseconds, negative values will throw an exception.</para>
/// <para>If a guild is not received before READY, it will be unavailable.</para>
/// </remarks>
/// <returns>
/// The maximum wait time in milliseconds between GUILD_AVAILABLE events before firing READY.
/// </returns>
/// <exception cref="System.ArgumentException">Value must be at least 0.</exception>
public int MaxWaitBetweenGuildAvailablesBeforeReady {
get
{
return _maxWaitForGuildAvailable;
}
set
{
Preconditions.AtLeast(value, 0, nameof(MaxWaitBetweenGuildAvailablesBeforeReady));
_maxWaitForGuildAvailable = value;
}
}
private int _maxWaitForGuildAvailable = 10000;

/// <summary> /// <summary>
/// Initializes a default configuration. /// Initializes a default configuration.
/// </summary> /// </summary>


Loading…
Cancel
Save