MathServiceImpl.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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;
  17. using System.Collections.Generic;
  18. using System.Threading;
  19. using System.Threading.Tasks;
  20. using Grpc.Core;
  21. using Grpc.Core.Utils;
  22. namespace Math
  23. {
  24. /// <summary>
  25. /// Implementation of MathService server
  26. /// </summary>
  27. public class MathServiceImpl : Math.MathBase
  28. {
  29. public override Task<DivReply> Div(DivArgs request, ServerCallContext context)
  30. {
  31. return Task.FromResult(DivInternal(request));
  32. }
  33. public override async Task Fib(FibArgs request, IServerStreamWriter<Num> responseStream, ServerCallContext context)
  34. {
  35. var limit = request.Limit > 0 ? request.Limit : long.MaxValue;
  36. var fibEnumerator = FibInternal(limit).GetEnumerator();
  37. // Keep streaming the sequence until the call is cancelled.
  38. // Use CancellationToken from ServerCallContext to detect the cancellation.
  39. while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext())
  40. {
  41. await responseStream.WriteAsync(fibEnumerator.Current);
  42. await Task.Delay(100);
  43. }
  44. }
  45. public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
  46. {
  47. long sum = 0;
  48. await requestStream.ForEachAsync(async num =>
  49. {
  50. sum += num.Num_;
  51. });
  52. return new Num { Num_ = sum };
  53. }
  54. public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
  55. {
  56. await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
  57. }
  58. static DivReply DivInternal(DivArgs args)
  59. {
  60. if (args.Divisor == 0)
  61. {
  62. // One can finish the RPC with non-ok status by throwing RpcException instance.
  63. // Alternatively, resulting status can be set using ServerCallContext.Status
  64. throw new RpcException(new Status(StatusCode.InvalidArgument, "Division by zero"));
  65. }
  66. long quotient = args.Dividend / args.Divisor;
  67. long remainder = args.Dividend % args.Divisor;
  68. return new DivReply { Quotient = quotient, Remainder = remainder };
  69. }
  70. static IEnumerable<Num> FibInternal(long n)
  71. {
  72. long a = 1;
  73. yield return new Num { Num_ = a };
  74. long b = 1;
  75. for (long i = 0; i < n - 1; i++)
  76. {
  77. long temp = a;
  78. a = b;
  79. b = temp + b;
  80. yield return new Num { Num_ = a };
  81. }
  82. }
  83. }
  84. }