Upgrade to Pro — share decks privately, control downloads, hide ads and more …

gRPC with Kotlin Coroutines on Android

Mohit S
January 19, 2021

gRPC with Kotlin Coroutines on Android

Learn about how to use gRPC on Android.

Mohit S

January 19, 2021
Tweet

More Decks by Mohit S

Other Decks in Programming

Transcript

  1. gRPC with Kotlin Coroutines • Using gRPC on Android •

    Authentication • Retries & Hedging • Debugging tools
  2. • Unary RPC call • Server streaming • Client streaming

    • Bidirectional streaming RPC Calls
  3. gRPC service MyService { rpc subscribe( . . ) }

    Proto buffer file Protoc Service Class
  4. gRPC service MyService { rpc subscribe( . . ) }

    Proto buffer file Protoc Client Stub
  5. grpc/grpc-kotlin Code ! Issues Pull Requests gRPC-Kotlin/JVM - An RPC

    library and framework grpc-kotlin-stub v0.1.4 protoc-gen-grpc-kotlinstub v0.1.4 grpc-kotlin-stub-lite v0.1.4 Bazel Build passing Gradle Build passing A Kotlin/JVM implementation of gRPC: A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.
  6. Use Case • Tracks your route. • Get a place

    from location. • List Places around location.
  7. Use Case • Tracks your route. • Get a place

    from location. • List Places around location. • Chat with others at location. Shoreline Golf links 2940 N Shoreline Blvd Mountain View, CA 94043 Start typing
  8. protocolbuffers/protobuf Code ! Issues Pull Requests Protocol Buffers - Google’s

    data interchange format Protocol Buffers (a.k.a., protobuf) are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data. Gradle Build passing
  9. Unary RPC Call syntax = “proto3”; service Places { rpc

    GetPlace(Location) returns (Place) {}; } Unary RPC Call
  10. Unary RPC Call syntax = “proto3”; service Places { rpc

    GetPlace(Location) returns (Place) {}; } Define messages
  11. Unary RPC Call message Location { double latitude = 1;

    double longitude = 2; } } Keyword
  12. Unary RPC Call service Places { message Location double latitude

    = 1; double longitude = 2; } } Message name
  13. message Location { double latitude = 1; double longitude =

    2; } Unary RPC Call .proto Type C++ Java Go double double Double * f l oat64 int32 int32 int *int32 Int64 long int/long *int64 https://developers.google.com/protocol-bu f f ers/docs/overview#scalar
  14. Unary RPC Call syntax = “proto3”; service Places { rpc

    GetPlace(Location) returns (Place) {}; } Define Place
  15. Unary RPC Call message Place { string name = 1;

    Location location = 2; } Name & Location
  16. Unary RPC Call message Place { string name = 1;

    Location location = 2; 
 PlaceType placeType = 3; } Enum
  17. Unary RPC Call message Place { 
 PlaceType placeType =

    3; enum PlaceType { Landmark = 0; Driving_Range = 1; Golf_Course = 2; Restaurant = 3; Retail = 4; } Enum
  18. Unary RPC Call message Place { string name = 1;

    Location location = 2; 
 PlaceType placeType = 3; enum PlaceType { … } 
 int64 checkins = 4; int64 comments = 5; } Int Scaler Types
  19. Unary RPC Call syntax = “proto3”; service Places { rpc

    GetPlace(Location) returns (Place) {}; }
  20. Unary RPC Call syntax = “proto3”; service Places { rpc

    CheckIn(Location) returns () {}; } How do we return an empty?
  21. Unary RPC Call syntax = “proto3”; service Places { rpc

    CheckIn(Location) returns (google.protobuf.Empty) {}; } How do we return an empty?
  22. Use Case • Chat with others at location • Stream

    of messages Shoreline Golf links 2940 N Shoreline Blvd Mountain View, CA 94043 Start typing
  23. Bidirectional RPC Call service Places { rpc Chat(stream Comment) returns

    (stream Comment) {}; } Bidirectional RPC Call
  24. RPC Call Types service Places { rpc GetPlace(Location) returns (Place)

    {}; rpc ListPlaces(Area) returns (stream Place) {}; rpc CheckIn(Place) returns (google.protobuf.Empty) {}; rpc Chat(stream Comment) returns (stream Comment) {}; }
  25. Generating Builders Proto buffer file Protoc Message Builders class Message

    { static class Builder { Builder set(double value) Location build() } }
  26. Creating Messages message Location { double latitude = 1; double

    longitude = 2; } class Location { static class Builder { Builder setLatitude(double value) Builder setLongitude(double value) Location build() } }
  27. Creating Messages message Location { double latitude = 1; double

    longitude = 2; } Location.newBuilder() .setLatitude(40.9888341) .setLongitude(-73.8502007) .build()
  28. protocolbuffers/protobuf Code ! Issues Pull Requests Kotlin support request #3742

    ! Open issue opened on Oct 12, 2017 comment on opened on Oct 12, 2017 Please support convert to Kotlin 168
  29. Generating Service Proto buffer file Protoc Service class Service {

    fun rpcMethod1(): Flow<Message> 
 fun rpcMethod2(): Flow<Message> }
  30. Generated Client class CoroutineStub { } rpc GetPlace(Location) returns (Place)

    {}; suspend fun getPlace(request: Location): Place
  31. Generated Client class CoroutineStub { } rpc ListPlaces(Area) returns (stream

    Place) {}; fun listPlaces(request: Area): Flow<Place> Stream is map to Flow
  32. Generated Client class CoroutineStub { } rpc Chat(stream Comment) returns

    (stream Comment) {}; fun chat(requests: Flow<Comment>): Flow<Comment> Stream is map to Flow
  33. Generated Client class CoroutineStub { } suspend fun getPlace(request: Location):

    Place fun recordTrip(requests: Flow<Location>): TripSummary fun listPlaces(request: Area): Flow<Place> fun chat(requests: Flow<Comment>): Flow<Comment>
  34. Using Client val managedChannel = ManagedChannelBuilder .intercept(object : ClientInterceptor {

    fun interceptCall(method, callOptions, channel) { }) Intercept RPC Calls
  35. Server Streaming fun listPlaces(area: Area) { viewModelScope.launch { val places:

    Flow<Place> = client.listPlaces(area) places.collect { } } }
  36. Using Client class GrpcViewModel(val client: CoroutineStub): ViewModel() { fun getPlace(location:

    Location) fun listPlaces(area: Area): Flow<Place> fun chat(chat: Flow<Comment>) }
  37. withCallCredentials(object: CallCredentials { override fun applyRequestMetadata(applier: MetadataApplier) { Metadata headers

    = new Metadata(); headers.put(“auth_token","token"); applier.apply(headers); } } Auth
  38. Client App gRPC Client Lib Server Application Failure Make 


    gRPC Call Sends RPC Returns UNAVAILABLE
  39. Client App gRPC Client Lib Server Application Failure Make 


    gRPC Call Sends RPC Returns UNAVAILABLE Retried RPC
  40. Client App gRPC Client Lib Server Application Failure Make 


    gRPC Call Sends RPC Returns UNAVAILABLE Retried RPC Success Return OK Receive 
 data
  41. Enable Retry "retryPolicy": { "maxAttempts": 10, "initialBackoff": "5s", "maxBackoff": "1s",

    "backoffMultiplier": 2, "retryableStatusCodes": [ "UNAVAILABLE" ] }
  42. Resources • gRPC with Kotlin Coroutines 
 
 https: /

    / codingwithmohit.com/grpc/grpc-kotlin-coroutines/ • Unit Testing Delays, Errors & Retries with Kotlin Flows 
 
 https: / / codingwithmohit.com/coroutines/unit-testing-delays- 
 errors-retries-with-kotlin-flows/