ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
137 stars 58 forks source link

[gRPC] Support caller object in the service to receive client message instead of stream #6699

Open daneshk opened 2 months ago

daneshk commented 2 months ago

Description: This requirement recently came for the gRPC bidirectional streaming use case where we need to send the request from the server side and get the response from the client agent. The only option we could think of is to implement a bidirectional streaming use case and keep the caller and streaming objects to initiate the call later. but in Ballerina isolated feature doesn't allow to keep stream objects in-memory map.

It is useful to change the caller object to introduce a new receive() method to get the messages from the client side. once we support it, service implementation for the bidirectional stream[1] can also be written as below,

@grpc:Descriptor {
    value: GRPC_BIDIRECTIONAL_STREAMING_DESC
}
service "Chat" on new grpc:Listener(9090) {

    remote function chat(ChatStringCaller caller) {
        // Reads and processes each message from the client.
        do {
            ChatMessage? chatMsg = check caller->receiveChatMessage();
            while chatMsg !is () {
                check caller->sendString(string `${chatMsg.name}: ${chatMsg.message}`);
                chatMsg = check caller->receiveChatMessage();
            }
            // Once the client sends a notification to indicate the end of the stream,
            // '()' is returned.
            check caller->complete();
        } on fail error err {
            log:printError("The connection is closed with an error.", 'error = err);
        }
    }
}
  1. https://ballerina.io/learn/by-example/grpc-service-bidirectional-streaming

This is the similar approach followed by the golang.