|
|
@ -130,15 +130,8 @@ namespace Grpc.Core |
|
|
|
// cached handler for watch connectivity state |
|
|
|
// cached handler for watch connectivity state |
|
|
|
static readonly BatchCompletionDelegate WatchConnectivityStateHandler = (success, ctx, state) => |
|
|
|
static readonly BatchCompletionDelegate WatchConnectivityStateHandler = (success, ctx, state) => |
|
|
|
{ |
|
|
|
{ |
|
|
|
var tcs = (TaskCompletionSource<object>) state; |
|
|
|
var tcs = (TaskCompletionSource<bool>) state; |
|
|
|
if (success) |
|
|
|
tcs.SetResult(success); |
|
|
|
{ |
|
|
|
|
|
|
|
tcs.SetResult(null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
tcs.SetCanceled(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// <summary> |
|
|
@ -146,11 +139,24 @@ namespace Grpc.Core |
|
|
|
/// given lastObservedState. |
|
|
|
/// given lastObservedState. |
|
|
|
/// If deadline is reached or and error occurs, returned task is cancelled. |
|
|
|
/// If deadline is reached or and error occurs, returned task is cancelled. |
|
|
|
/// </summary> |
|
|
|
/// </summary> |
|
|
|
public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) |
|
|
|
public async Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var result = await WaitForStateChangedInternalAsync(lastObservedState, deadline).ConfigureAwait(false); |
|
|
|
|
|
|
|
if (!result) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
throw new TaskCanceledException("Reached deadline."); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> |
|
|
|
|
|
|
|
/// Returned tasks completes once channel state has become different from |
|
|
|
|
|
|
|
/// given lastObservedState (<c>true</c> is returned) or if the wait has timed out (<c>false</c> is returned). |
|
|
|
|
|
|
|
/// </summary> |
|
|
|
|
|
|
|
internal Task<bool> WaitForStateChangedInternalAsync(ChannelState lastObservedState, DateTime? deadline = null) |
|
|
|
{ |
|
|
|
{ |
|
|
|
GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown, |
|
|
|
GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown, |
|
|
|
"Shutdown is a terminal state. No further state changes can occur."); |
|
|
|
"Shutdown is a terminal state. No further state changes can occur."); |
|
|
|
var tcs = new TaskCompletionSource<object>(); |
|
|
|
var tcs = new TaskCompletionSource<bool>(); |
|
|
|
var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; |
|
|
|
var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; |
|
|
|
lock (myLock) |
|
|
|
lock (myLock) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -320,14 +326,8 @@ namespace Grpc.Core |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try |
|
|
|
// ignore the result |
|
|
|
{ |
|
|
|
await WaitForStateChangedInternalAsync(lastState, DateTime.UtcNow.AddSeconds(1)).ConfigureAwait(false); |
|
|
|
await WaitForStateChangedAsync(lastState, DateTime.UtcNow.AddSeconds(1)).ConfigureAwait(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (TaskCanceledException) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// ignore timeout |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
lastState = State; |
|
|
|
lastState = State; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|