MathServiceImpl.cs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #region Copyright notice and license
  2. // Copyright 2015-2016 gRPC authors.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. #endregion
  16. using System.Collections.Generic;
  17. using System.Threading.Tasks;
  18. using Grpc.Core;
  19. using Grpc.Core.Utils;
  20. namespace Math
  21. {
  22. /// <summary>
  23. /// Implementation of MathService server
  24. /// </summary>
  25. public class MathServiceImpl : Math.MathBase
  26. {
  27. public override Task<DivReply> Div(DivArgs request, ServerCallContext context)
  28. {
  29. return Task.FromResult(DivInternal(request));
  30. }
  31. public override async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
  32. {
  33. var limit = request.Limit > 0 ? request.Limit : long.MaxValue;
  34. var fibEnumerator = FibInternal(limit).GetEnumerator();
  35. // Keep streaming the sequence until the call is cancelled.
  36. // Use CancellationToken from ServerCallContext to detect the cancellation.
  37. while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext())
  38. {
  39. await responseStream.WriteAsync(fibEnumerator.Current);
  40. await Task.Delay(100);
  41. }
  42. }
  43. public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
  44. {
  45. long sum = 0;
  46. await requestStream.ForEachAsync(num =>
  47. {
  48. sum += num.Num_;
  49. return TaskUtils.CompletedTask;
  50. });
  51. return new Num { Num_ = sum };
  52. }
  53. public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
  54. {
  55. await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
  56. }
  57. static DivReply DivInternal(DivArgs args)
  58. {
  59. if (args.Divisor == 0)
  60. {
  61. // One can finish the RPC with non-ok status by throwing RpcException instance.
  62. // Alternatively, resulting status can be set using ServerCallContext.Status
  63. throw new RpcException(new Status(StatusCode.InvalidArgument, "Division by zero"));
  64. }
  65. long quotient = args.Dividend / args.Divisor;
  66. long remainder = args.Dividend % args.Divisor;
  67. return new DivReply { Quotient = quotient, Remainder = remainder };
  68. }
  69. static IEnumerable<Num> FibInternal(long n)
  70. {
  71. long a = 1;
  72. yield return new Num { Num_ = a };
  73. long b = 1;
  74. for (long i = 0; i < n - 1; i++)
  75. {
  76. long temp = a;
  77. a = b;
  78. b = temp + b;
  79. yield return new Num { Num_ = a };
  80. }
  81. }
  82. }
  83. }