Browse Source

Added async disposable interface to various components

pull/1562/head
James Grant 5 years ago
parent
commit
37431ba6ac
8 changed files with 130 additions and 4 deletions
  1. +1
    -1
      src/Discord.Net.Core/IDiscordClient.cs
  2. +15
    -0
      src/Discord.Net.Rest/BaseDiscordClient.cs
  3. +22
    -1
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  4. +8
    -0
      src/Discord.Net.Rest/DiscordRestClient.cs
  5. +16
    -2
      src/Discord.Net.Rest/Net/Queue/RequestQueue.cs
  6. +20
    -0
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  7. +29
    -0
      src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
  8. +19
    -0
      src/Discord.Net.WebSocket/DiscordSocketClient.cs

+ 1
- 1
src/Discord.Net.Core/IDiscordClient.cs View File

@@ -8,7 +8,7 @@ namespace Discord
/// <summary> /// <summary>
/// Represents a generic Discord client. /// Represents a generic Discord client.
/// </summary> /// </summary>
public interface IDiscordClient : IDisposable
public interface IDiscordClient : IDisposable, IAsyncDisposable
{ {
/// <summary> /// <summary>
/// Gets the current state of connection. /// Gets the current state of connection.


+ 15
- 0
src/Discord.Net.Rest/BaseDiscordClient.cs View File

@@ -145,9 +145,24 @@ namespace Discord.Rest
_isDisposed = true; _isDisposed = true;
} }
} }

internal virtual async ValueTask DisposeAsync(bool disposing)
{
if (!_isDisposed)
{
#pragma warning disable IDISP007
await ApiClient.DisposeAsync().ConfigureAwait(false);
#pragma warning restore IDISP007
_stateLock?.Dispose();
_isDisposed = true;
}
}

/// <inheritdoc /> /// <inheritdoc />
public void Dispose() => Dispose(true); public void Dispose() => Dispose(true);


public ValueTask DisposeAsync() => DisposeAsync(true);

/// <inheritdoc /> /// <inheritdoc />
public Task<int> GetRecommendedShardCountAsync(RequestOptions options = null) public Task<int> GetRecommendedShardCountAsync(RequestOptions options = null)
=> ClientHelper.GetRecommendShardCountAsync(this, options); => ClientHelper.GetRecommendShardCountAsync(this, options);


+ 22
- 1
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -22,7 +22,7 @@ using System.Threading.Tasks;


namespace Discord.API namespace Discord.API
{ {
internal class DiscordRestApiClient : IDisposable
internal class DiscordRestApiClient : IDisposable, IAsyncDisposable
{ {
private static readonly ConcurrentDictionary<string, Func<BucketIds, string>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, string>>(); private static readonly ConcurrentDictionary<string, Func<BucketIds, string>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, string>>();


@@ -106,8 +106,29 @@ namespace Discord.API
_isDisposed = true; _isDisposed = true;
} }
} }

internal virtual async ValueTask DisposeAsync(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
_loginCancelToken?.Dispose();
RestClient?.Dispose();

if (!(RequestQueue is null))
await RequestQueue.DisposeAsync().ConfigureAwait(false);

_stateLock?.Dispose();
}
_isDisposed = true;
}
}

public void Dispose() => Dispose(true); public void Dispose() => Dispose(true);


public ValueTask DisposeAsync() => DisposeAsync(true);

public async Task LoginAsync(TokenType tokenType, string token, RequestOptions options = null) public async Task LoginAsync(TokenType tokenType, string token, RequestOptions options = null)
{ {
await _stateLock.WaitAsync().ConfigureAwait(false); await _stateLock.WaitAsync().ConfigureAwait(false);


+ 8
- 0
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -41,6 +41,14 @@ namespace Discord.Rest
base.Dispose(disposing); base.Dispose(disposing);
} }


internal override async ValueTask DisposeAsync(bool disposing)
{
if (disposing)
await ApiClient.DisposeAsync().ConfigureAwait(false);

base.Dispose(disposing);
}

/// <inheritdoc /> /// <inheritdoc />
internal override async Task OnLoginAsync(TokenType tokenType, string token) internal override async Task OnLoginAsync(TokenType tokenType, string token)
{ {


+ 16
- 2
src/Discord.Net.Rest/Net/Queue/RequestQueue.cs View File

@@ -1,3 +1,4 @@
using Newtonsoft.Json.Bson;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
#if DEBUG_LIMITS #if DEBUG_LIMITS
@@ -10,7 +11,7 @@ using System.Threading.Tasks;


namespace Discord.Net.Queue namespace Discord.Net.Queue
{ {
internal class RequestQueue : IDisposable
internal class RequestQueue : IDisposable, IAsyncDisposable
{ {
public event Func<string, RateLimitInfo?, Task> RateLimitTriggered; public event Func<string, RateLimitInfo?, Task> RateLimitTriggered;


@@ -143,12 +144,25 @@ namespace Discord.Net.Queue
if (!(_cancelTokenSource is null)) if (!(_cancelTokenSource is null))
{ {
_cancelTokenSource.Cancel(); _cancelTokenSource.Cancel();
_cancelTokenSource?.Dispose();
_cancelTokenSource.Dispose();
_cleanupTask.GetAwaiter().GetResult(); _cleanupTask.GetAwaiter().GetResult();
} }
_tokenLock?.Dispose(); _tokenLock?.Dispose();
_clearToken?.Dispose(); _clearToken?.Dispose();
_requestCancelTokenSource?.Dispose(); _requestCancelTokenSource?.Dispose();
} }

public async ValueTask DisposeAsync()
{
if (!(_cancelTokenSource is null))
{
_cancelTokenSource.Cancel();
_cancelTokenSource.Dispose();
await _cleanupTask.ConfigureAwait(false);
}
_tokenLock?.Dispose();
_clearToken?.Dispose();
_requestCancelTokenSource?.Dispose();
}
} }
} }

+ 20
- 0
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -402,5 +402,25 @@ namespace Discord.WebSocket


base.Dispose(disposing); base.Dispose(disposing);
} }

internal override ValueTask DisposeAsync(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
if (_shards != null)
{
foreach (var client in _shards)
client?.Dispose();
}
_connectionGroupLock?.Dispose();
}

_isDisposed = true;
}

return base.DisposeAsync(disposing);
}
} }
} }

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

@@ -114,6 +114,35 @@ namespace Discord.API
base.Dispose(disposing); base.Dispose(disposing);
} }


#if NETSTANDARD2_1
internal override async ValueTask DisposeAsync(bool disposing)
#else
internal override ValueTask DisposeAsync(bool disposing)
#endif
{
if (!_isDisposed)
{
if (disposing)
{
_connectCancelToken?.Dispose();
(WebSocketClient as IDisposable)?.Dispose();
#if NETSTANDARD2_1
if (!(_decompressor is null))
await _decompressor.DisposeAsync().ConfigureAwait(false);
#else
_decompressor?.Dispose();
#endif
}
_isDisposed = true;
}

#if NETSTANDARD2_1
await base.DisposeAsync(disposing).ConfigureAwait(false);
#else
return base.DisposeAsync(disposing);
#endif
}

public async Task ConnectAsync() public async Task ConnectAsync()
{ {
await _stateLock.WaitAsync().ConfigureAwait(false); await _stateLock.WaitAsync().ConfigureAwait(false);


+ 19
- 0
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -197,6 +197,25 @@ namespace Discord.WebSocket
base.Dispose(disposing); base.Dispose(disposing);
} }


internal override async ValueTask DisposeAsync(bool disposing)
{
if (!_isDisposed)
{
if (disposing)
{
await StopAsync().ConfigureAwait(false);

if (!(ApiClient is null))
await ApiClient.DisposeAsync().ConfigureAwait(false);

_stateLock?.Dispose();
}
_isDisposed = true;
}

await base.DisposeAsync(disposing).ConfigureAwait(false);
}

/// <inheritdoc /> /// <inheritdoc />
internal override async Task OnLoginAsync(TokenType tokenType, string token) internal override async Task OnLoginAsync(TokenType tokenType, string token)
{ {


Loading…
Cancel
Save