StatsService.swift 3.7 KB

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