Merge pull request #6794 from jtattermusch/csharp_misc_fixes

C# assorted GA improvements (docs and polish)
pull/6754/head
Jan Tattermusch 9 years ago
commit dda1aed92a
  1. 6
      src/csharp/Grpc.Core.Tests/ChannelTest.cs
  2. 4
      src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
  3. 4
      src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
  4. 4
      src/csharp/Grpc.Core/AsyncUnaryCall.cs
  5. 8
      src/csharp/Grpc.Core/CallOptions.cs
  6. 25
      src/csharp/Grpc.Core/Channel.cs
  7. 2
      src/csharp/Grpc.Core/ChannelState.cs
  8. 6
      src/csharp/Grpc.Core/Server.cs
  9. 26
      src/csharp/Grpc.Examples/MathGrpc.cs
  10. 6
      src/proto/math/math.proto

@ -71,7 +71,7 @@ namespace Grpc.Core.Tests
public void WaitForStateChangedAsync_InvalidArgument() public void WaitForStateChangedAsync_InvalidArgument()
{ {
var channel = new Channel("localhost", ChannelCredentials.Insecure); var channel = new Channel("localhost", ChannelCredentials.Insecure);
Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.FatalFailure)); Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.Shutdown));
channel.ShutdownAsync().Wait(); channel.ShutdownAsync().Wait();
} }
@ -102,11 +102,11 @@ namespace Grpc.Core.Tests
} }
[Test] [Test]
public async Task StateIsFatalFailureAfterShutdown() public async Task StateIsShutdownAfterShutdown()
{ {
var channel = new Channel("localhost", ChannelCredentials.Insecure); var channel = new Channel("localhost", ChannelCredentials.Insecure);
await channel.ShutdownAsync(); await channel.ShutdownAsync();
Assert.AreEqual(ChannelState.FatalFailure, channel.State); Assert.AreEqual(ChannelState.Shutdown, channel.State);
} }
[Test] [Test]

@ -117,6 +117,10 @@ namespace Grpc.Core
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call. /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually. /// As a result, all resources being used by the call should be released eventually.
/// </summary> /// </summary>
/// <remarks>
/// Normally, there is no need for you to dispose the call unless you want to utilize the
/// "Cancel" semantics of invoking <c>Dispose</c>.
/// </remarks>
public void Dispose() public void Dispose()
{ {
disposeAction.Invoke(); disposeAction.Invoke();

@ -103,6 +103,10 @@ namespace Grpc.Core
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call. /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually. /// As a result, all resources being used by the call should be released eventually.
/// </summary> /// </summary>
/// <remarks>
/// Normally, there is no need for you to dispose the call unless you want to utilize the
/// "Cancel" semantics of invoking <c>Dispose</c>.
/// </remarks>
public void Dispose() public void Dispose()
{ {
disposeAction.Invoke(); disposeAction.Invoke();

@ -112,6 +112,10 @@ namespace Grpc.Core
/// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call. /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
/// As a result, all resources being used by the call should be released eventually. /// As a result, all resources being used by the call should be released eventually.
/// </summary> /// </summary>
/// <remarks>
/// Normally, there is no need for you to dispose the call unless you want to utilize the
/// "Cancel" semantics of invoking <c>Dispose</c>.
/// </remarks>
public void Dispose() public void Dispose()
{ {
disposeAction.Invoke(); disposeAction.Invoke();

@ -88,7 +88,13 @@ namespace Grpc.Core
} }
/// <summary> /// <summary>
/// Token that can be used for cancelling the call. /// Token that can be used for cancelling the call on the client side.
/// Cancelling the token will request cancellation
/// of the remote call. Best effort will be made to deliver the cancellation
/// notification to the server and interaction of the call with the server side
/// will be terminated. Unless the call finishes before the cancellation could
/// happen (there is an inherent race),
/// the call will finish with <c>StatusCode.Cancelled</c> status.
/// </summary> /// </summary>
public CancellationToken CancellationToken public CancellationToken CancellationToken
{ {

@ -104,7 +104,7 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Gets current connectivity state of this channel. /// Gets current connectivity state of this channel.
/// After channel is has been shutdown, <c>ChannelState.FatalFailure</c> will be returned. /// After channel is has been shutdown, <c>ChannelState.Shutdown</c> will be returned.
/// </summary> /// </summary>
public ChannelState State public ChannelState State
{ {
@ -121,8 +121,8 @@ namespace Grpc.Core
/// </summary> /// </summary>
public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null)
{ {
GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure, GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown,
"FatalFailure 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<object>();
var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
var handler = new BatchCompletionDelegate((success, ctx) => var handler = new BatchCompletionDelegate((success, ctx) =>
@ -172,7 +172,7 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Allows explicitly requesting channel to connect without starting an RPC. /// Allows explicitly requesting channel to connect without starting an RPC.
/// Returned task completes once state Ready was seen. If the deadline is reached, /// Returned task completes once state Ready was seen. If the deadline is reached,
/// or channel enters the FatalFailure state, the task is cancelled. /// or channel enters the Shutdown state, the task is cancelled.
/// There is no need to call this explicitly unless your use case requires that. /// There is no need to call this explicitly unless your use case requires that.
/// Starting an RPC on a new channel will request connection implicitly. /// Starting an RPC on a new channel will request connection implicitly.
/// </summary> /// </summary>
@ -182,9 +182,9 @@ namespace Grpc.Core
var currentState = GetConnectivityState(true); var currentState = GetConnectivityState(true);
while (currentState != ChannelState.Ready) while (currentState != ChannelState.Ready)
{ {
if (currentState == ChannelState.FatalFailure) if (currentState == ChannelState.Shutdown)
{ {
throw new OperationCanceledException("Channel has reached FatalFailure state."); throw new OperationCanceledException("Channel has reached Shutdown state.");
} }
await WaitForStateChangedAsync(currentState, deadline).ConfigureAwait(false); await WaitForStateChangedAsync(currentState, deadline).ConfigureAwait(false);
currentState = GetConnectivityState(false); currentState = GetConnectivityState(false);
@ -192,9 +192,16 @@ namespace Grpc.Core
} }
/// <summary> /// <summary>
/// Waits until there are no more active calls for this channel and then cleans up /// Shuts down the channel cleanly. It is strongly recommended to shutdown
/// resources used by this channel. /// all previously created channels before exiting from the process.
/// </summary> /// </summary>
/// <remarks>
/// This method doesn't wait for all calls on this channel to finish (nor does
/// it explicitly cancel all outstanding calls). It is user's responsibility to make sure
/// all the calls on this channel have finished (successfully or with an error)
/// before shutting down the channel to ensure channel shutdown won't impact
/// the outcome of those remote calls.
/// </remarks>
public async Task ShutdownAsync() public async Task ShutdownAsync()
{ {
lock (myLock) lock (myLock)
@ -264,7 +271,7 @@ namespace Grpc.Core
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
return ChannelState.FatalFailure; return ChannelState.Shutdown;
} }
} }

@ -64,6 +64,6 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Channel has seen a failure that it cannot recover from /// Channel has seen a failure that it cannot recover from
/// </summary> /// </summary>
FatalFailure Shutdown
} }
} }

@ -152,6 +152,9 @@ namespace Grpc.Core
/// cleans up used resources. The returned task finishes when shutdown procedure /// cleans up used resources. The returned task finishes when shutdown procedure
/// is complete. /// is complete.
/// </summary> /// </summary>
/// <remarks>
/// It is strongly recommended to shutdown all previously created servers before exiting from the process.
/// </remarks>
public async Task ShutdownAsync() public async Task ShutdownAsync()
{ {
lock (myLock) lock (myLock)
@ -173,6 +176,9 @@ namespace Grpc.Core
/// Requests server shutdown while cancelling all the in-progress calls. /// Requests server shutdown while cancelling all the in-progress calls.
/// The returned task finishes when shutdown procedure is complete. /// The returned task finishes when shutdown procedure is complete.
/// </summary> /// </summary>
/// <remarks>
/// It is strongly recommended to shutdown all previously created servers before exiting from the process.
/// </remarks>
public async Task KillAsync() public async Task KillAsync()
{ {
lock (myLock) lock (myLock)

@ -85,8 +85,8 @@ namespace Math {
public abstract class MathBase public abstract class MathBase
{ {
/// <summary> /// <summary>
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
/// remainder. /// and remainder.
/// </summary> /// </summary>
public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
{ {
@ -105,7 +105,7 @@ namespace Math {
} }
/// <summary> /// <summary>
/// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib /// Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib
/// generates up to limit numbers; otherwise it continues until the call is /// generates up to limit numbers; otherwise it continues until the call is
/// canceled. Unlike Fib above, Fib has no final FibReply. /// canceled. Unlike Fib above, Fib has no final FibReply.
/// </summary> /// </summary>
@ -144,32 +144,32 @@ namespace Math {
} }
/// <summary> /// <summary>
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
/// remainder. /// and remainder.
/// </summary> /// </summary>
public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
return Div(request, new CallOptions(headers, deadline, cancellationToken)); return Div(request, new CallOptions(headers, deadline, cancellationToken));
} }
/// <summary> /// <summary>
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
/// remainder. /// and remainder.
/// </summary> /// </summary>
public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options) public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
{ {
return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request); return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
} }
/// <summary> /// <summary>
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
/// remainder. /// and remainder.
/// </summary> /// </summary>
public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
return DivAsync(request, new CallOptions(headers, deadline, cancellationToken)); return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
} }
/// <summary> /// <summary>
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
/// remainder. /// and remainder.
/// </summary> /// </summary>
public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options) public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
{ {
@ -196,7 +196,7 @@ namespace Math {
return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options); return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
} }
/// <summary> /// <summary>
/// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib /// Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib
/// generates up to limit numbers; otherwise it continues until the call is /// generates up to limit numbers; otherwise it continues until the call is
/// canceled. Unlike Fib above, Fib has no final FibReply. /// canceled. Unlike Fib above, Fib has no final FibReply.
/// </summary> /// </summary>
@ -205,7 +205,7 @@ namespace Math {
return Fib(request, new CallOptions(headers, deadline, cancellationToken)); return Fib(request, new CallOptions(headers, deadline, cancellationToken));
} }
/// <summary> /// <summary>
/// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib /// Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib
/// generates up to limit numbers; otherwise it continues until the call is /// generates up to limit numbers; otherwise it continues until the call is
/// canceled. Unlike Fib above, Fib has no final FibReply. /// canceled. Unlike Fib above, Fib has no final FibReply.
/// </summary> /// </summary>

@ -55,8 +55,8 @@ message FibReply {
} }
service Math { service Math {
// Div divides args.dividend by args.divisor and returns the quotient and // Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
// remainder. // and remainder.
rpc Div (DivArgs) returns (DivReply) { rpc Div (DivArgs) returns (DivReply) {
} }
@ -67,7 +67,7 @@ service Math {
rpc DivMany (stream DivArgs) returns (stream DivReply) { rpc DivMany (stream DivArgs) returns (stream DivReply) {
} }
// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib // Fib generates numbers in the Fibonacci sequence. If FibArgs.limit > 0, Fib
// generates up to limit numbers; otherwise it continues until the call is // generates up to limit numbers; otherwise it continues until the call is
// canceled. Unlike Fib above, Fib has no final FibReply. // canceled. Unlike Fib above, Fib has no final FibReply.
rpc Fib (FibArgs) returns (stream Num) { rpc Fib (FibArgs) returns (stream Num) {

Loading…
Cancel
Save