| /* |
| * |
| * Copyright 2020 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| package rls |
| |
| import ( |
| "context" |
| "time" |
| |
| "google.golang.org/grpc" |
| rlspb "google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1" |
| ) |
| |
| // For gRPC services using RLS, the value of target_type in the |
| // RouteLookupServiceRequest will be set to this. |
| const grpcTargetType = "grpc" |
| |
| // rlsClient is a simple wrapper around a RouteLookupService client which |
| // provides non-blocking semantics on top of a blocking unary RPC call. |
| // |
| // The RLS LB policy creates a new rlsClient object with the following values: |
| // * a grpc.ClientConn to the RLS server using appropriate credentials from the |
| // parent channel |
| // * dialTarget corresponding to the original user dial target, e.g. |
| // "firestore.googleapis.com". |
| // |
| // The RLS LB policy uses an adaptive throttler to perform client side |
| // throttling and asks this client to make an RPC call only after checking with |
| // the throttler. |
| type rlsClient struct { |
| stub rlspb.RouteLookupServiceClient |
| // origDialTarget is the original dial target of the user and sent in each |
| // RouteLookup RPC made to the RLS server. |
| origDialTarget string |
| // rpcTimeout specifies the timeout for the RouteLookup RPC call. The LB |
| // policy receives this value in its service config. |
| rpcTimeout time.Duration |
| } |
| |
| func newRLSClient(cc *grpc.ClientConn, dialTarget string, rpcTimeout time.Duration) *rlsClient { |
| return &rlsClient{ |
| stub: rlspb.NewRouteLookupServiceClient(cc), |
| origDialTarget: dialTarget, |
| rpcTimeout: rpcTimeout, |
| } |
| } |
| |
| type lookupCallback func(targets []string, headerData string, err error) |
| |
| // lookup starts a RouteLookup RPC in a separate goroutine and returns the |
| // results (and error, if any) in the provided callback. |
| func (c *rlsClient) lookup(path string, keyMap map[string]string, cb lookupCallback) { |
| go func() { |
| ctx, cancel := context.WithTimeout(context.Background(), c.rpcTimeout) |
| resp, err := c.stub.RouteLookup(ctx, &rlspb.RouteLookupRequest{ |
| Server: c.origDialTarget, |
| Path: path, |
| TargetType: grpcTargetType, |
| KeyMap: keyMap, |
| }) |
| cb(resp.GetTargets(), resp.GetHeaderData(), err) |
| cancel() |
| }() |
| } |