aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@google.com>2017-05-08 16:30:12 +0200
committerGravatar Jan Tattermusch <jtattermusch@google.com>2017-05-08 17:06:15 +0200
commit8a507811ff14502131474eb3bf799c14419579a6 (patch)
tree7f8a690f00a339a9f4f67fccb0e9fa3365b9b525 /src/csharp/Grpc.Core
parent712ea0ac870e3f2a313277978ac3e9d3fdeeca11 (diff)
C# workaround for unavailable on idle channels
Diffstat (limited to 'src/csharp/Grpc.Core')
-rw-r--r--src/csharp/Grpc.Core/Channel.cs41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 4f29c35b32..51ae11fbde 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -59,6 +59,8 @@ namespace Grpc.Core
readonly ChannelSafeHandle handle;
readonly Dictionary<string, ChannelOption> options;
+ readonly Task connectivityWatcherTask;
+
bool shutdownRequested;
/// <summary>
@@ -99,6 +101,9 @@ namespace Grpc.Core
this.handle = ChannelSafeHandle.CreateInsecure(target, nativeChannelArgs);
}
}
+ // TODO(jtattermusch): Workaround for https://github.com/GoogleCloudPlatform/google-cloud-dotnet/issues/822.
+ // Remove once retries are supported in C core
+ this.connectivityWatcherTask = RunConnectivityWatcherAsync();
GrpcEnvironment.RegisterChannel(this);
}
@@ -244,7 +249,7 @@ namespace Grpc.Core
handle.Dispose();
- await GrpcEnvironment.ReleaseAsync().ConfigureAwait(false);
+ await Task.WhenAll(GrpcEnvironment.ReleaseAsync(), connectivityWatcherTask).ConfigureAwait(false);
}
internal ChannelSafeHandle Handle
@@ -299,6 +304,40 @@ namespace Grpc.Core
}
}
+ /// <summary>
+ /// Constantly Watches channel connectivity status to work around https://github.com/GoogleCloudPlatform/google-cloud-dotnet/issues/822
+ /// </summary>
+ private async Task RunConnectivityWatcherAsync()
+ {
+ try
+ {
+ var lastState = State;
+ while (lastState != ChannelState.Shutdown)
+ {
+ lock (myLock)
+ {
+ if (shutdownRequested)
+ {
+ break;
+ }
+ }
+
+ try
+ {
+ await WaitForStateChangedAsync(lastState, DateTime.UtcNow.AddSeconds(1)).ConfigureAwait(false);
+ }
+ catch (TaskCanceledException)
+ {
+ // ignore timeout
+ }
+ lastState = State;
+ }
+ }
+ catch (ObjectDisposedException) {
+ // during shutdown, channel is going to be disposed.
+ }
+ }
+
private static void EnsureUserAgentChannelOption(Dictionary<string, ChannelOption> options)
{
var key = ChannelOptions.PrimaryUserAgentString;