ServerRunners.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #region Copyright notice and license
  2. // Copyright 2015 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.Diagnostics;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Text.RegularExpressions;
  22. using System.Threading;
  23. using System.Threading.Tasks;
  24. using Google.Protobuf;
  25. using Grpc.Core;
  26. using Grpc.Core.Logging;
  27. using Grpc.Core.Utils;
  28. using NUnit.Framework;
  29. using Grpc.Testing;
  30. namespace Grpc.IntegrationTesting
  31. {
  32. /// <summary>
  33. /// Helper methods to start server runners for performance testing.
  34. /// </summary>
  35. public class ServerRunners
  36. {
  37. static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<ServerRunners>();
  38. /// <summary>
  39. /// Creates a started server runner.
  40. /// </summary>
  41. public static IServerRunner CreateStarted(ServerConfig config)
  42. {
  43. Logger.Debug("ServerConfig: {0}", config);
  44. var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure;
  45. if (config.AsyncServerThreads != 0)
  46. {
  47. Logger.Warning("ServerConfig.AsyncServerThreads is not supported for C#. Ignoring the value");
  48. }
  49. if (config.CoreLimit != 0)
  50. {
  51. Logger.Warning("ServerConfig.CoreLimit is not supported for C#. Ignoring the value");
  52. }
  53. if (config.CoreList.Count > 0)
  54. {
  55. Logger.Warning("ServerConfig.CoreList is not supported for C#. Ignoring the value");
  56. }
  57. ServerServiceDefinition service = null;
  58. if (config.ServerType == ServerType.AsyncServer)
  59. {
  60. GrpcPreconditions.CheckArgument(config.PayloadConfig == null,
  61. "ServerConfig.PayloadConfig shouldn't be set for BenchmarkService based server.");
  62. service = BenchmarkService.BindService(new BenchmarkServiceImpl());
  63. }
  64. else if (config.ServerType == ServerType.AsyncGenericServer)
  65. {
  66. var genericService = new GenericServiceImpl(config.PayloadConfig.BytebufParams.RespSize);
  67. service = GenericService.BindHandler(genericService.StreamingCall);
  68. }
  69. else
  70. {
  71. throw new ArgumentException("Unsupported ServerType");
  72. }
  73. var server = new Server
  74. {
  75. Services = { service },
  76. Ports = { new ServerPort("[::]", config.Port, credentials) }
  77. };
  78. server.Start();
  79. return new ServerRunnerImpl(server);
  80. }
  81. private class GenericServiceImpl
  82. {
  83. readonly byte[] response;
  84. public GenericServiceImpl(int responseSize)
  85. {
  86. this.response = new byte[responseSize];
  87. }
  88. /// <summary>
  89. /// Generic streaming call handler.
  90. /// </summary>
  91. public async Task StreamingCall(IAsyncStreamReader<byte[]> requestStream, IServerStreamWriter<byte[]> responseStream, ServerCallContext context)
  92. {
  93. await requestStream.ForEachAsync(async request =>
  94. {
  95. await responseStream.WriteAsync(response);
  96. });
  97. }
  98. }
  99. }
  100. /// <summary>
  101. /// Server runner.
  102. /// </summary>
  103. public class ServerRunnerImpl : IServerRunner
  104. {
  105. readonly Server server;
  106. readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
  107. public ServerRunnerImpl(Server server)
  108. {
  109. this.server = GrpcPreconditions.CheckNotNull(server);
  110. }
  111. public int BoundPort
  112. {
  113. get
  114. {
  115. return server.Ports.Single().BoundPort;
  116. }
  117. }
  118. /// <summary>
  119. /// Gets server stats.
  120. /// </summary>
  121. /// <returns>The stats.</returns>
  122. public ServerStats GetStats(bool reset)
  123. {
  124. var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
  125. GrpcEnvironment.Logger.Info("[ServerRunner.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, (seconds since last reset {3})",
  126. GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), secondsElapsed);
  127. // TODO: populate user time and system time
  128. return new ServerStats
  129. {
  130. TimeElapsed = secondsElapsed,
  131. TimeUser = 0,
  132. TimeSystem = 0
  133. };
  134. }
  135. /// <summary>
  136. /// Asynchronously stops the server.
  137. /// </summary>
  138. /// <returns>Task that finishes when server has shutdown.</returns>
  139. public Task StopAsync()
  140. {
  141. return server.ShutdownAsync();
  142. }
  143. }
  144. }