mirror of https://github.com/grpc/grpc-dotnet.git
Compare commits
2 Commits
master
...
v2.49.0-pr
Author | SHA1 | Date |
---|---|---|
|
a57f1e506b | |
|
09641160f9 |
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
|
||||
<!-- package version of grpc-dotnet -->
|
||||
<GrpcDotnetVersion>2.49.0-dev</GrpcDotnetVersion>
|
||||
<GrpcDotnetVersion>2.49.0-pre1</GrpcDotnetVersion>
|
||||
|
||||
<!-- assembly version of grpc-dotnet -->
|
||||
<GrpcDotnetAssemblyVersion>2.0.0.0</GrpcDotnetAssemblyVersion>
|
||||
|
|
|
@ -41,6 +41,6 @@ namespace Grpc.Core
|
|||
/// <summary>
|
||||
/// Current version of gRPC C#
|
||||
/// </summary>
|
||||
public const string CurrentVersion = "2.49.0-dev";
|
||||
public const string CurrentVersion = "2.49.0-pre1";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#if SUPPORT_LOAD_BALANCING
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Grpc.Core;
|
||||
|
||||
namespace Grpc.Net.Client.Balancer.Internal
|
||||
|
@ -28,6 +29,7 @@ namespace Grpc.Net.Client.Balancer.Internal
|
|||
|
||||
public ErrorPicker(Status status)
|
||||
{
|
||||
Debug.Assert(status.StatusCode != StatusCode.OK, "Error status code must not be OK.");
|
||||
_status = status;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace Grpc.Net.Client.Balancer.Internal
|
|||
internal sealed class ConnectContext
|
||||
{
|
||||
private readonly CancellationTokenSource _cts;
|
||||
private readonly CancellationToken _token;
|
||||
private bool _disposed;
|
||||
|
||||
// This flag allows the transport to determine why the cancellation token was canceled.
|
||||
|
@ -53,11 +54,14 @@ namespace Grpc.Net.Client.Balancer.Internal
|
|||
// - Connection timeout, e.g. SocketsHttpHandler.ConnectTimeout was exceeded.
|
||||
public bool IsConnectCanceled { get; private set; }
|
||||
|
||||
public CancellationToken CancellationToken => _cts.Token;
|
||||
public CancellationToken CancellationToken => _token;
|
||||
|
||||
public ConnectContext(TimeSpan connectTimeout)
|
||||
{
|
||||
_cts = new CancellationTokenSource(connectTimeout);
|
||||
|
||||
// Take a copy of the token to avoid ObjectDisposedException when accessing _cts.Token after CTS is disposed.
|
||||
_token = _cts.Token;
|
||||
}
|
||||
|
||||
public void CancelConnect()
|
||||
|
|
|
@ -313,7 +313,7 @@ namespace Grpc.Net.Client.Balancer
|
|||
{
|
||||
SubchannelLog.ConnectError(_logger, Id, ex);
|
||||
|
||||
UpdateConnectivityState(ConnectivityState.TransientFailure, "Error connecting to subchannel.");
|
||||
UpdateConnectivityState(ConnectivityState.TransientFailure, new Status(StatusCode.Unavailable, "Error connecting to subchannel.", ex));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -144,6 +144,43 @@ namespace Grpc.Net.Client.Tests.Balancer
|
|||
Assert.AreEqual(StatusCode.DataLoss, ex.StatusCode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PickAsync_ErrorConnectingToSubchannel_ThrowsError()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
services.AddNUnitLogger();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
|
||||
|
||||
var resolver = new TestResolver(loggerFactory);
|
||||
resolver.UpdateAddresses(new List<BalancerAddress>
|
||||
{
|
||||
new BalancerAddress("localhost", 80)
|
||||
});
|
||||
|
||||
var transportFactory = new TestSubchannelTransportFactory((s, c) =>
|
||||
{
|
||||
return Task.FromException<ConnectivityState>(new Exception("Test error!"));
|
||||
});
|
||||
var clientChannel = CreateConnectionManager(loggerFactory, resolver, transportFactory);
|
||||
clientChannel.ConfigureBalancer(c => new PickFirstBalancer(c, loggerFactory));
|
||||
|
||||
// Act
|
||||
_ = clientChannel.ConnectAsync(waitForReady: false, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var pickTask = clientChannel.PickAsync(
|
||||
new PickContext { Request = new HttpRequestMessage() },
|
||||
waitForReady: false,
|
||||
CancellationToken.None).AsTask();
|
||||
|
||||
// Assert
|
||||
var ex = await ExceptionAssert.ThrowsAsync<RpcException>(() => pickTask).DefaultTimeout();
|
||||
Assert.AreEqual(StatusCode.Unavailable, ex.StatusCode);
|
||||
Assert.AreEqual("Error connecting to subchannel.", ex.Status.Detail);
|
||||
Assert.AreEqual("Test error!", ex.Status.DebugException?.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PickAsync_RetryWithDrop_ThrowsError()
|
||||
{
|
||||
|
|
|
@ -626,6 +626,7 @@ namespace Grpc.Net.Client.Tests
|
|||
var currentConnectivityState = ConnectivityState.TransientFailure;
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddNUnitLogger();
|
||||
services.AddSingleton<ResolverFactory, ChannelTestResolverFactory>();
|
||||
services.AddSingleton<ISubchannelTransportFactory>(new TestSubchannelTransportFactory(async (s, c) =>
|
||||
{
|
||||
|
|
|
@ -81,7 +81,8 @@ namespace Grpc.Net.Client.Tests.Infrastructure.Balancer
|
|||
var newState = await (_onTryConnect?.Invoke(context.CancellationToken) ?? Task.FromResult(ConnectivityState.Ready));
|
||||
|
||||
CurrentAddress = Subchannel._addresses[0];
|
||||
Subchannel.UpdateConnectivityState(newState, Status.DefaultSuccess);
|
||||
var newStatus = newState == ConnectivityState.TransientFailure ? new Status(StatusCode.Internal, "") : Status.DefaultSuccess;
|
||||
Subchannel.UpdateConnectivityState(newState, newStatus);
|
||||
|
||||
_connectTcs.TrySetResult(null);
|
||||
|
||||
|
|
Loading…
Reference in New Issue