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>
|
<PropertyGroup>
|
||||||
|
|
||||||
<!-- package version of grpc-dotnet -->
|
<!-- package version of grpc-dotnet -->
|
||||||
<GrpcDotnetVersion>2.49.0-dev</GrpcDotnetVersion>
|
<GrpcDotnetVersion>2.49.0-pre1</GrpcDotnetVersion>
|
||||||
|
|
||||||
<!-- assembly version of grpc-dotnet -->
|
<!-- assembly version of grpc-dotnet -->
|
||||||
<GrpcDotnetAssemblyVersion>2.0.0.0</GrpcDotnetAssemblyVersion>
|
<GrpcDotnetAssemblyVersion>2.0.0.0</GrpcDotnetAssemblyVersion>
|
||||||
|
|
|
@ -41,6 +41,6 @@ namespace Grpc.Core
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current version of gRPC C#
|
/// Current version of gRPC C#
|
||||||
/// </summary>
|
/// </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
|
#if SUPPORT_LOAD_BALANCING
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using Grpc.Core;
|
using Grpc.Core;
|
||||||
|
|
||||||
namespace Grpc.Net.Client.Balancer.Internal
|
namespace Grpc.Net.Client.Balancer.Internal
|
||||||
|
@ -28,6 +29,7 @@ namespace Grpc.Net.Client.Balancer.Internal
|
||||||
|
|
||||||
public ErrorPicker(Status status)
|
public ErrorPicker(Status status)
|
||||||
{
|
{
|
||||||
|
Debug.Assert(status.StatusCode != StatusCode.OK, "Error status code must not be OK.");
|
||||||
_status = status;
|
_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace Grpc.Net.Client.Balancer.Internal
|
||||||
internal sealed class ConnectContext
|
internal sealed class ConnectContext
|
||||||
{
|
{
|
||||||
private readonly CancellationTokenSource _cts;
|
private readonly CancellationTokenSource _cts;
|
||||||
|
private readonly CancellationToken _token;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
// This flag allows the transport to determine why the cancellation token was canceled.
|
// 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.
|
// - Connection timeout, e.g. SocketsHttpHandler.ConnectTimeout was exceeded.
|
||||||
public bool IsConnectCanceled { get; private set; }
|
public bool IsConnectCanceled { get; private set; }
|
||||||
|
|
||||||
public CancellationToken CancellationToken => _cts.Token;
|
public CancellationToken CancellationToken => _token;
|
||||||
|
|
||||||
public ConnectContext(TimeSpan connectTimeout)
|
public ConnectContext(TimeSpan connectTimeout)
|
||||||
{
|
{
|
||||||
_cts = new CancellationTokenSource(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()
|
public void CancelConnect()
|
||||||
|
|
|
@ -313,7 +313,7 @@ namespace Grpc.Net.Client.Balancer
|
||||||
{
|
{
|
||||||
SubchannelLog.ConnectError(_logger, Id, ex);
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -144,6 +144,43 @@ namespace Grpc.Net.Client.Tests.Balancer
|
||||||
Assert.AreEqual(StatusCode.DataLoss, ex.StatusCode);
|
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]
|
[Test]
|
||||||
public async Task PickAsync_RetryWithDrop_ThrowsError()
|
public async Task PickAsync_RetryWithDrop_ThrowsError()
|
||||||
{
|
{
|
||||||
|
|
|
@ -626,6 +626,7 @@ namespace Grpc.Net.Client.Tests
|
||||||
var currentConnectivityState = ConnectivityState.TransientFailure;
|
var currentConnectivityState = ConnectivityState.TransientFailure;
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
services.AddNUnitLogger();
|
||||||
services.AddSingleton<ResolverFactory, ChannelTestResolverFactory>();
|
services.AddSingleton<ResolverFactory, ChannelTestResolverFactory>();
|
||||||
services.AddSingleton<ISubchannelTransportFactory>(new TestSubchannelTransportFactory(async (s, c) =>
|
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));
|
var newState = await (_onTryConnect?.Invoke(context.CancellationToken) ?? Task.FromResult(ConnectivityState.Ready));
|
||||||
|
|
||||||
CurrentAddress = Subchannel._addresses[0];
|
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);
|
_connectTcs.TrySetResult(null);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue