| /* |
| * |
| * Copyright 2016 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 grpc |
| |
| import ( |
| "google.golang.org/grpc/balancer" |
| "google.golang.org/grpc/resolver" |
| ) |
| |
| // The parent ClientConn should re-resolve when grpclb loses connection to the |
| // remote balancer. When the ClientConn inside grpclb gets a TransientFailure, |
| // it calls lbManualResolver.ResolveNow(), which calls parent ClientConn's |
| // ResolveNow, and eventually results in re-resolve happening in parent |
| // ClientConn's resolver (DNS for example). |
| // |
| // parent |
| // ClientConn |
| // +-----------------------------------------------------------------+ |
| // | parent +---------------------------------+ | |
| // | DNS ClientConn | grpclb | | |
| // | resolver balancerWrapper | | | |
| // | + + | grpclb grpclb | | |
| // | | | | ManualResolver ClientConn | | |
| // | | | | + + | | |
| // | | | | | | Transient | | |
| // | | | | | | Failure | | |
| // | | | | | <--------- | | | |
| // | | | <--------------- | ResolveNow | | | |
| // | | <--------- | ResolveNow | | | | | |
| // | | ResolveNow | | | | | | |
| // | | | | | | | | |
| // | + + | + + | | |
| // | +---------------------------------+ | |
| // +-----------------------------------------------------------------+ |
| |
| // lbManualResolver is used by the ClientConn inside grpclb. It's a manual |
| // resolver with a special ResolveNow() function. |
| // |
| // When ResolveNow() is called, it calls ResolveNow() on the parent ClientConn, |
| // so when grpclb client lose contact with remote balancers, the parent |
| // ClientConn's resolver will re-resolve. |
| type lbManualResolver struct { |
| scheme string |
| ccr resolver.ClientConn |
| |
| ccb balancer.ClientConn |
| } |
| |
| func (r *lbManualResolver) Build(_ resolver.Target, cc resolver.ClientConn, _ resolver.BuildOption) (resolver.Resolver, error) { |
| r.ccr = cc |
| return r, nil |
| } |
| |
| func (r *lbManualResolver) Scheme() string { |
| return r.scheme |
| } |
| |
| // ResolveNow calls resolveNow on the parent ClientConn. |
| func (r *lbManualResolver) ResolveNow(o resolver.ResolveNowOption) { |
| r.ccb.ResolveNow(o) |
| } |
| |
| // Close is a noop for Resolver. |
| func (*lbManualResolver) Close() {} |
| |
| // NewAddress calls cc.NewAddress. |
| func (r *lbManualResolver) NewAddress(addrs []resolver.Address) { |
| r.ccr.NewAddress(addrs) |
| } |
| |
| // NewServiceConfig calls cc.NewServiceConfig. |
| func (r *lbManualResolver) NewServiceConfig(sc string) { |
| r.ccr.NewServiceConfig(sc) |
| } |