StatsService.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright 2025, 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 GRPCCore
  17. import Synchronization
  18. final class DebugCallbackStats: Sendable {
  19. let tcpListenersBound: Atomic<Int>
  20. let tcpConnectionsAccepted: Atomic<Int>
  21. let tcpConnectionsCreated: Atomic<Int>
  22. let http2StreamsAccepted: Atomic<Int>
  23. let http2StreamsCreated: Atomic<Int>
  24. init() {
  25. self.tcpListenersBound = Atomic(0)
  26. self.tcpConnectionsAccepted = Atomic(0)
  27. self.tcpConnectionsCreated = Atomic(0)
  28. self.http2StreamsAccepted = Atomic(0)
  29. self.http2StreamsCreated = Atomic(0)
  30. }
  31. var serverStats: GetStatsResponse.Server {
  32. GetStatsResponse.Server(
  33. tcpListenersBound: self.tcpListenersBound.load(ordering: .sequentiallyConsistent),
  34. tcpConnectionsAccepted: self.tcpConnectionsAccepted.load(ordering: .sequentiallyConsistent),
  35. http2StreamsAccepted: self.http2StreamsAccepted.load(ordering: .sequentiallyConsistent)
  36. )
  37. }
  38. var clientStats: GetStatsResponse.Client {
  39. GetStatsResponse.Client(
  40. tcpConnectionsCreated: self.tcpConnectionsCreated.load(ordering: .sequentiallyConsistent),
  41. http2StreamsCreated: self.http2StreamsCreated.load(ordering: .sequentiallyConsistent)
  42. )
  43. }
  44. }
  45. struct StatsService {
  46. private let stats: DebugCallbackStats
  47. init(stats: DebugCallbackStats) {
  48. self.stats = stats
  49. }
  50. func getStats() async throws -> GetStatsResponse {
  51. GetStatsResponse(server: self.stats.serverStats, client: self.stats.clientStats)
  52. }
  53. }
  54. extension StatsService: RegistrableRPCService {
  55. func registerMethods<Transport: ServerTransport>(with router: inout RPCRouter<Transport>) {
  56. router.registerHandler(
  57. forMethod: .getStats,
  58. deserializer: JSONCoder<GetStatsRequest>(),
  59. serializer: JSONCoder<GetStatsResponse>()
  60. ) { request, context in
  61. _ = try await ServerRequest(stream: request)
  62. let response = try await self.getStats()
  63. return StreamingServerResponse {
  64. try await $0.write(response)
  65. return [:]
  66. }
  67. }
  68. }
  69. }
  70. struct StatsClient<Transport: ClientTransport> {
  71. private let underlying: GRPCClient<Transport>
  72. init(wrapping underlying: GRPCClient<Transport>) {
  73. self.underlying = underlying
  74. }
  75. func getStats() async throws -> GetStatsResponse {
  76. try await self.underlying.unary(
  77. request: ClientRequest(message: GetStatsRequest()),
  78. descriptor: .getStats,
  79. serializer: JSONCoder<GetStatsRequest>(),
  80. deserializer: JSONCoder<GetStatsResponse>(),
  81. options: .defaults
  82. ) {
  83. try $0.message
  84. }
  85. }
  86. }
  87. extension MethodDescriptor {
  88. static let getStats = Self(fullyQualifiedService: "StatsService", method: "GetStats")
  89. }
  90. struct GetStatsRequest: Codable, Hashable {}
  91. struct GetStatsResponse: Codable, Hashable {
  92. struct Server: Codable, Hashable {
  93. var tcpListenersBound: Int
  94. var tcpConnectionsAccepted: Int
  95. var http2StreamsAccepted: Int
  96. }
  97. struct Client: Codable, Hashable {
  98. var tcpConnectionsCreated: Int
  99. var http2StreamsCreated: Int
  100. }
  101. var server: Server
  102. var client: Client
  103. }