test_bidi_1k_rpcs.swift 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright 2021, gRPC Authors All rights reserved.
  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. */
  16. import Dispatch
  17. import GRPC
  18. import NIO
  19. class BidiPingPongBenchmark: Benchmark {
  20. let rpcs: Int
  21. let requests: Int
  22. let request: Echo_EchoRequest
  23. private var group: EventLoopGroup!
  24. private var server: Server!
  25. private var client: ClientConnection!
  26. init(rpcs: Int, requests: Int, request: String) {
  27. self.rpcs = rpcs
  28. self.requests = requests
  29. self.request = .with { $0.text = request }
  30. }
  31. func setUp() throws {
  32. self.group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  33. self.server = try makeEchoServer(group: self.group).wait()
  34. self.client = makeClientConnection(
  35. group: self.group,
  36. port: self.server.channel.localAddress!.port!
  37. )
  38. }
  39. func tearDown() throws {
  40. try self.client.close().wait()
  41. try self.server.close().wait()
  42. try self.group.syncShutdownGracefully()
  43. }
  44. func run() throws -> Int {
  45. let echo = Echo_EchoNIOClient(channel: self.client)
  46. var statusCodeSum = 0
  47. // We'll use this semaphore to make sure we're ping-ponging request-response
  48. // pairs on the RPC. Doing so makes the number of allocations much more
  49. // stable.
  50. let waiter = DispatchSemaphore(value: 1)
  51. for _ in 0 ..< self.rpcs {
  52. let update = echo.update { _ in
  53. waiter.signal()
  54. }
  55. for _ in 0 ..< self.requests {
  56. waiter.wait()
  57. update.sendMessage(self.request, promise: nil)
  58. }
  59. waiter.wait()
  60. update.sendEnd(promise: nil)
  61. let status = try update.status.wait()
  62. statusCodeSum += status.code.rawValue
  63. waiter.signal()
  64. }
  65. return statusCodeSum
  66. }
  67. }
  68. func run(identifier: String) {
  69. measure(identifier: identifier + "_10_requests") {
  70. let benchmark = BidiPingPongBenchmark(rpcs: 1000, requests: 10, request: "")
  71. return try! benchmark.runOnce()
  72. }
  73. measure(identifier: identifier + "_1_request") {
  74. let benchmark = BidiPingPongBenchmark(rpcs: 1000, requests: 1, request: "")
  75. return try! benchmark.runOnce()
  76. }
  77. }