@@ -50,17 +50,28 @@ const (
5050 errFmtDialFunction = "cannot gRPC dial target %q from status.endpoint of active FunctionRevision %q"
5151)
5252
53- // TODO(negz): Should any of these be configurable?
54- const (
55- // This configures a gRPC client to use round robin load balancing. This
56- // means that if the Function Deployment has more than one Pod, and the
57- // Function Service is headless, requests will be spread across each Pod.
58- // See https://github.com/grpc/grpc/blob/v1.58.0/doc/load-balancing.md#load-balancing-policies
59- lbRoundRobin = `{"loadBalancingConfig":[{"round_robin":{}}]}`
60-
61- dialFunctionTimeout = 10 * time .Second
62- runFunctionTimeout = 10 * time .Second
63- )
53+ // This configures a gRPC client to use round robin load balancing. This means
54+ // that if the Function Deployment has more than one Pod, and the Function
55+ // Service is headless, requests will be spread across each Pod.
56+ // See https://github.com/grpc/grpc/blob/v1.58.0/doc/load-balancing.md#load-balancing-policies
57+ //
58+ // It also configures the gRPC client to wait for the server to be ready before
59+ // sending RPCs. Notably this gives Functions time to start before we make a
60+ // request. See https://grpc.io/docs/guides/wait-for-ready/
61+ const svcConfig = `
62+ {
63+ "loadBalancingConfig": [
64+ {
65+ "round_robin":{}
66+ }
67+ ],
68+ "methodConfig": [
69+ {
70+ "name": [{}],
71+ "waitForReady": true
72+ }
73+ ]
74+ }`
6475
6576// A PackagedFunctionRunner runs a Function by making a gRPC call to a Function
6677// package's runtime. It creates a gRPC client connection for each Function. The
@@ -136,10 +147,6 @@ func (r *PackagedFunctionRunner) RunFunction(ctx context.Context, name string, r
136147 return nil , errors .Wrapf (err , errFmtGetClientConn , name )
137148 }
138149
139- // This context is used for actually making the request.
140- ctx , cancel := context .WithTimeout (ctx , runFunctionTimeout )
141- defer cancel ()
142-
143150 rsp , err := NewBetaFallBackFunctionRunnerServiceClient (conn ).RunFunction (ctx , req )
144151 return rsp , errors .Wrapf (err , errFmtRunFunction , name )
145152}
@@ -220,18 +227,14 @@ func (r *PackagedFunctionRunner) getClientConn(ctx context.Context, name string)
220227 delete (r .conns , name )
221228 }
222229
223- // This context is only used for setting up the connection.
224- ctx , cancel := context .WithTimeout (ctx , dialFunctionTimeout )
225- defer cancel ()
226-
227230 is := make ([]grpc.UnaryClientInterceptor , len (r .interceptors ))
228231 for i := range r .interceptors {
229232 is [i ] = r .interceptors [i ].CreateInterceptor (name , active .Spec .Package )
230233 }
231234
232- conn , err := grpc .DialContext ( ctx , active .Status .Endpoint , //nolint:staticcheck // Figure out how to replace deprecated grpc.DialContext with grpc.NewClient and still pass the dialFunctionTimeout.
235+ conn , err := grpc .NewClient ( active .Status .Endpoint ,
233236 grpc .WithTransportCredentials (r .creds ),
234- grpc .WithDefaultServiceConfig (lbRoundRobin ),
237+ grpc .WithDefaultServiceConfig (svcConfig ),
235238 grpc .WithChainUnaryInterceptor (is ... ))
236239 if err != nil {
237240 return nil , errors .Wrapf (err , errFmtDialFunction , active .Status .Endpoint , active .GetName ())
0 commit comments