GreetingService.swift 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  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 ServiceLifecycle
  18. import Synchronization
  19. /// Implements the "Hello World" gRPC service but modifies the greeting on a timer.
  20. ///
  21. /// The service conforms to the 'ServiceLifecycle.Service' and uses its 'run()' method
  22. /// to execute the run loop which updates the greeting.
  23. final class GreetingService {
  24. private let updateInterval: Duration
  25. private let currentGreetingIndex: Mutex<Int>
  26. private let greetings: [String] = [
  27. "Hello",
  28. "你好",
  29. "नमस्ते",
  30. "Hola",
  31. "Bonjour",
  32. "Olá",
  33. "Здравствуйте",
  34. "こんにちは",
  35. "Ciao",
  36. ]
  37. private func personalizedGreeting(forName name: String) -> String {
  38. let index = self.currentGreetingIndex.withLock { $0 }
  39. return "\(self.greetings[index]), \(name)!"
  40. }
  41. private func periodicallyUpdateGreeting() async throws {
  42. while !Task.isShuttingDownGracefully {
  43. try await Task.sleep(for: self.updateInterval)
  44. // Increment the greeting index.
  45. self.currentGreetingIndex.withLock { index in
  46. // '!' is fine; greetings is non-empty.
  47. index = self.greetings.indices.randomElement()!
  48. }
  49. }
  50. }
  51. init(updateInterval: Duration) {
  52. // '!' is fine; greetings is non-empty.
  53. let index = self.greetings.indices.randomElement()!
  54. self.currentGreetingIndex = Mutex(index)
  55. self.updateInterval = updateInterval
  56. }
  57. }
  58. extension GreetingService: Helloworld_Greeter.SimpleServiceProtocol {
  59. func sayHello(
  60. request: Helloworld_HelloRequest,
  61. context: ServerContext
  62. ) async throws -> Helloworld_HelloReply {
  63. return .with {
  64. $0.message = self.personalizedGreeting(forName: request.name)
  65. }
  66. }
  67. }
  68. extension GreetingService: Service {
  69. func run() async throws {
  70. try await self.periodicallyUpdateGreeting()
  71. }
  72. }