mirror of https://github.com/dapr/dotnet-sdk.git
Add IDisposable to DaprClient (#563)
Fixes: #559 This change adds disposable support to DaprClient, and updates samples to dispose it. I didn't update tests because there are literally hundreds of non-find-and-replacable cases, and we're not actually doing networking in our tests so it won't cause an issue.
This commit is contained in:
parent
9ca4a43cc7
commit
8a7bac13b3
|
|
@ -18,7 +18,7 @@ namespace Samples.Client
|
|||
// Note: the data types used in this sample are generated from data.proto in GrpcServiceSample
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
Console.WriteLine("Invoking grpc balance");
|
||||
var request = new GetAccountRequest() { Id = "17", };
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Samples.Client
|
|||
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
// Invokes a POST method named "deposit" that takes input of type "Transaction" as define in the RoutingSample.
|
||||
Console.WriteLine("Invoking deposit");
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Samples.Client
|
|||
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
var eventData = new { Id = "17", Amount = 10m, };
|
||||
await client.PublishEventAsync(pubsubName, "deposit", eventData, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Samples.Client
|
|||
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
// Save state which will create a new etag
|
||||
await client.SaveStateAsync<Widget>(storeName, stateKeyName, new Widget() { Size = "small", Color = "yellow", }, cancellationToken: cancellationToken);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Samples.Client
|
|||
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
var state = new Widget() { Size = "small", Color = "yellow", };
|
||||
await client.SaveStateAsync(storeName, stateKeyName, state, cancellationToken: cancellationToken);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Samples.Client
|
|||
|
||||
public override async Task RunAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var client = new DaprClientBuilder().Build();
|
||||
using var client = new DaprClientBuilder().Build();
|
||||
|
||||
var value = new Widget() { Size = "small", Color = "yellow", };
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,21 @@ namespace Dapr.Client
|
|||
using Google.Protobuf;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Defines client methods for interacting with Dapr endpoints.
|
||||
/// Use <see cref="DaprClientBuilder"/> to create <see cref="DaprClient"/>
|
||||
/// Use <see cref="DaprClientBuilder"/> to create <see cref="DaprClient"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Implementations of <see cref="DaprClient" /> implement <see cref="IDisposable" /> because the client
|
||||
/// accesses network resources. For best performance, create a single long-lived client instance and share
|
||||
/// it for the lifetime of the application. Avoid creating and disposing a client instance for each operation
|
||||
/// that the application performs - this can lead to socket exhaustion and other problems.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public abstract class DaprClient
|
||||
public abstract class DaprClient : IDisposable
|
||||
{
|
||||
private bool disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JsonSerializerOptions" /> used for JSON serialization operations.
|
||||
/// </summary>
|
||||
|
|
@ -684,5 +694,23 @@ namespace Dapr.Client
|
|||
string storeName,
|
||||
IReadOnlyDictionary<string, string> metadata = default,
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
if (!this.disposed)
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
this.disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the resources associated with the object.
|
||||
/// </summary>
|
||||
/// <param name="disposing"><c>true</c> if called by a call to the <c>Dispose</c> method; otherwise false.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,11 +134,11 @@ namespace Dapr.Client
|
|||
{
|
||||
throw new InvalidOperationException("The HTTP endpoint must use http or https.");
|
||||
}
|
||||
|
||||
|
||||
var channel = GrpcChannel.ForAddress(this.GrpcEndpoint, this.GrpcChannelOptions);
|
||||
var client = new Autogenerated.Dapr.DaprClient(channel);
|
||||
|
||||
return new DaprClientGrpc(client, new HttpClient(), httpEndpoint, this.JsonSerializerOptions);
|
||||
return new DaprClientGrpc(channel, client, new HttpClient(), httpEndpoint, this.JsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Dapr.Client
|
|||
using Autogenerated = Dapr.Client.Autogen.Grpc.v1;
|
||||
using System.Net.Http.Json;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Net.Client;
|
||||
|
||||
/// <summary>
|
||||
/// A client for interacting with the Dapr endpoints.
|
||||
|
|
@ -27,6 +28,8 @@ namespace Dapr.Client
|
|||
private readonly HttpClient httpClient;
|
||||
|
||||
private readonly JsonSerializerOptions jsonSerializerOptions;
|
||||
|
||||
private readonly GrpcChannel channel;
|
||||
private readonly Autogenerated.Dapr.DaprClient client;
|
||||
|
||||
// property exposed for testing purposes
|
||||
|
|
@ -35,11 +38,13 @@ namespace Dapr.Client
|
|||
public override JsonSerializerOptions JsonSerializerOptions => jsonSerializerOptions;
|
||||
|
||||
internal DaprClientGrpc(
|
||||
GrpcChannel channel,
|
||||
Autogenerated.Dapr.DaprClient inner,
|
||||
HttpClient httpClient,
|
||||
Uri httpEndpoint,
|
||||
JsonSerializerOptions jsonSerializerOptions)
|
||||
{
|
||||
this.channel = channel;
|
||||
this.client = inner;
|
||||
this.httpClient = httpClient;
|
||||
this.httpEndpoint = httpEndpoint;
|
||||
|
|
@ -825,6 +830,15 @@ namespace Dapr.Client
|
|||
}
|
||||
#endregion
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
this.channel.Dispose();
|
||||
this.httpClient.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
private CallOptions CreateCallOptions(Metadata headers, CancellationToken cancellationToken)
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace Dapr.Client
|
|||
/// Initializes a new instance of the <see cref="DaprClientGrpc"/> class.
|
||||
/// </summary>
|
||||
internal StateTestClient()
|
||||
: base(new Autogenerated.Dapr.DaprClient(channel), new HttpClient(), new Uri("http://localhost"), null)
|
||||
: base(channel, new Autogenerated.Dapr.DaprClient(channel), new HttpClient(), new Uri("http://localhost"), null)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Dapr.Client.Test
|
|||
using Dapr.Client.Autogen.Test.Grpc.v1;
|
||||
using FluentAssertions;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -64,6 +66,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -87,6 +90,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -116,6 +120,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -145,6 +150,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -176,6 +182,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -207,6 +214,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -239,6 +247,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -279,6 +288,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -294,6 +304,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -320,6 +331,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
@ -340,6 +352,7 @@ namespace Dapr.Client.Test
|
|||
// Configure Client
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new DaprClientGrpc(
|
||||
GrpcChannel.ForAddress("http://localhost"),
|
||||
Mock.Of<global::Dapr.Client.Autogen.Grpc.v1.Dapr.DaprClient>(),
|
||||
httpClient,
|
||||
new Uri("https://test-endpoint:3501"),
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ namespace Dapr.Client
|
|||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
using Moq;
|
||||
|
||||
public class MockClient
|
||||
|
|
@ -17,7 +18,7 @@ namespace Dapr.Client
|
|||
public MockClient()
|
||||
{
|
||||
Mock = new Mock<Autogen.Grpc.v1.Dapr.DaprClient>(MockBehavior.Strict);
|
||||
DaprClient = new DaprClientGrpc(Mock.Object, new HttpClient(), new Uri("http://localhost:3500"), new JsonSerializerOptions());
|
||||
DaprClient = new DaprClientGrpc(GrpcChannel.ForAddress("http://localhost"), Mock.Object, new HttpClient(), new Uri("http://localhost:3500"), new JsonSerializerOptions());
|
||||
}
|
||||
|
||||
public Mock<Autogen.Grpc.v1.Dapr.DaprClient> Mock { get; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue