gRPCのお勉強で、KotlinでgRPCチュートリアルをやってみて、わからなかったことを調べた
ソースコードをcloneしてきて、ビルドして起動してみる
$ git clone --depth 1 https://github.com/grpc/grpc-kotlin $ cd grpc-kotlin/examples $ ./gradlew installDist // サーバーの起動 $ ./server/build/install/server/bin/hello-world-server Server started, listening on 50051 // クライアントの起動 $ ./client/build/install/client/bin/hello-world-client Received: Hello world
ここまでは一瞬
protoファイルは理解しやすい
// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; }
protoファイルをビルドすると、gRPC クライアントクラスとサーバークラス、リクエストタイプとレスポンスタイプのクラスなどが自動生成される
リクエストを具体的にどうするかは、サーバークラスのHelloWorldServer.ktで実装する
internal class HelloWorldService : GreeterGrpcKt.GreeterCoroutineImplBase() { override suspend fun sayHello(request: HelloRequest) = helloReply { message = "Hello ${request.name}" } } }
気になった点として、HelloWorldServer.ktのawaitTerminationメソッドは
fun blockUntilShutdown() {
server.awaitTermination()
}
サーバーが終了するまで、または現在のスレッドが中断されるまで、現在のスレッドの待機状態を維持(ブロック)し続け、外部からのリクエストを受け付けられるようにするメソッドらしい
サーバーのシャットダウンプロセスが開始されると、このメソッドはブロックを解除し、アプリケーションは終了処理を行う
以下はクライアントクラスのHelloWorldClient.ktのコード
class HelloWorldClient(private val channel: ManagedChannel) : Closeable { private val stub: GreeterCoroutineStub = GreeterCoroutineStub(channel) suspend fun greet(name: String) { val request = helloRequest { this.name = name } val response = stub.sayHello(request) println("Received: ${response.message}") } override fun close() { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS) } }
GreeterCoroutineStub オブジェクトは、クライアントからサーバーへのRPCを行うためのスタブ
channelは、gRPCサーバーへの接続を提供するネットワークチャネル上の抽象化であるManagedChannelに渡され、接続の詳細(失敗時の再接続や接続プールなど)を処理する
suspend は、この関数がコルーチンであることを示している
コルーチンは、メインスレッドをブロックせずに非同期操作を管理し、長時間実行するタスクを実行するためのKotlinの機能
最後のchannel.shutdown().awaitTermination(5, TimeUnit.SECONDS)のshutdown メソッドは、チャネルを終了状態に移行させ、awaitTermination メソッドは、終了する際に開いているネットワーク接続やその他のリソースが適切にクリーンアップされるまで(この例では最大5秒間)現在のスレッドの実行をブロックしている