Allow specifying list of user ids in SocketGuild.DownloadUsersAsync#2676
Allow specifying list of user ids in SocketGuild.DownloadUsersAsync#2676compujuckel wants to merge 6 commits intodiscord-net:devfrom
Conversation
|
I like this idea. @Misha-133 can you stress test this PR and see what you can find for bugs/bottlenecks? |
await SocketGuild.DownloadUsersAsync(Array.Empty<ulong>());
UPD: awaiting the method in a event handler causes a deadlock on the gateway thread |
|
@quinchs Should
_________ |
|
Once thing that's currently missing from this PR is this:
so this must be chunked when requesting more than 100 members at once |
|
|
||
| if (data.Nonce.IsSpecified | ||
| && data.ChunkIndex + 1 >= data.ChunkCount | ||
| && _guildMembersRequestTasks.TryRemove(data.Nonce.Value, out var tcs)) |
There was a problem hiding this comment.
This being the only way of removing request tasks may result in a memory leak if client misses the event (due to temporary connection loss, discord requesting a reconnect, etc.)
I'm not exactly sure what's the best way around this, but I'd recommend adding a timeout to tasks so it retries/fails the task if the client doesn't receive the member chuck in X amount of time. This would also solve the issue of possible deadlock caused by this
There was a problem hiding this comment.
What do you think about allowing users to pass a CancellationToken in DownloadUsersAsync(IEnumerable<ulong> userIds)? A fixed timeout seems a bit too inflexible IMHO, since downloading >1k users will actually take a while (=> more than a few seconds). If no CancellationToken is given, we could apply a default timeout
There was a problem hiding this comment.
Added a default request timeout and a way for users to supply their own cancellation token.
- throw exception when client not connected - chunk user downloads
|
|
||
| /// <summary> | ||
| /// Downloads specific users for this guild with the default request timeout. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// This method downloads all users specified in <paramref name="userIds" /> through the Gateway and caches them. | ||
| /// Consider using <see cref="DownloadUsersAsync(IEnumerable{ulong}, CancellationToken)"/> when downloading a large number of users. | ||
| /// </remarks> | ||
| /// <param name="userIds">The list of Discord user IDs to download.</param> | ||
| /// <returns> | ||
| /// A task that represents the asynchronous download operation. | ||
| /// </returns> | ||
| /// <exception cref="OperationCanceledException">The timeout has elapsed.</exception> | ||
| Task DownloadUsersAsync(IEnumerable<ulong> userIds); |
There was a problem hiding this comment.
instead of defining 2 methods with the only difference being a cancel token, why not make the token parameter optional?
Discord supports specifying a list of user IDs in their Request Guild Members event, but Discord.NET currently does not expose this functionality.
I'm trying to use Discord.NET in a large server (>600k members) and my bot is interested in only a few (100-10,000) of those. Using
DownloadUsersAsyncto get all users takes very long and also shoots up RAM usage to >2GBThis PR is not really ready to merge (the changes work fine for my use case though), I'm mainly looking to get some feedback on what is needed to get this feature into Discord.NET.