1
votes

I have a server-side streaming RPC hosted on Google Cloud Run.

With the following proto definition:

syntax = "proto3";

package test.v1;

service MyService {
    // Subscribe to a stream of events.
    rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse) {}
}

message SubscribeRequest {
}

message SubscribeResponse {
}

Using BloomRPC/grpcurl, when I stop the method I get a stream.Context().Done() event which I can use to gracefully stop certain tasks. Here is an example of the Suscribe method:

func (s *myService) Subscribe(req *pb.SubscribeRequest, stream pb.Instruments_SubscribeServer) error {
    
    // Create a channel for this client.
    ch := make(chan *pb.SubscribeResponse)
    
    // Add the channel object 'ch' to a Global list of channels where we have a 'broadcaster' sending
    // messages to all connected clients.
    // TODO: pass to broadcaster client list.
    
    for {
        select {
        case <-stream.Context().Done():
            close(ch)
            fmt.Println("Removed client from global list of channels")
            return nil
        case res := <-ch:
            _ = stream.Send(res)
        }
    }
}

On the client side, when I test the service locally (i.e. running a local gRPC server in Golang), using BloomRPC/grpcurl I get a message on the stream.Context().Done() channel whenever I stop the BloomRPC/grpcurl connection. This is the expected behaviour.

However, running the exact same code on Cloud Run in the same way (via BloomRPC/grpcurl), I don't get a stream.Context().Done() message - any reason why this would be different on Google Cloud Run? Looking at the Cloud Run logs, a call to the Subscribe method essentially 'hangs' until the request reaches its timeout.

1

1 Answers