(s balancer.ClientConnState, newConfig *lbConfig)
| 83 | } |
| 84 | |
| 85 | func (b *bal) updateChildren(s balancer.ClientConnState, newConfig *lbConfig) error { |
| 86 | endpointsSplit := hierarchy.Group(s.ResolverState.Endpoints) |
| 87 | |
| 88 | // Remove sub-balancers that are not in the new list from the aggregator and |
| 89 | // balancergroup. |
| 90 | for name := range b.children { |
| 91 | if _, ok := newConfig.Children[name]; !ok { |
| 92 | b.stateAggregator.remove(name) |
| 93 | b.bg.Remove(name) |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | var retErr error |
| 98 | for childName, childCfg := range newConfig.Children { |
| 99 | lbCfg := childCfg.ChildPolicy.Config |
| 100 | if _, ok := b.children[childName]; !ok { |
| 101 | // Add new sub-balancers to the aggregator and balancergroup. |
| 102 | b.stateAggregator.add(childName) |
| 103 | b.bg.Add(childName, balancer.Get(childCfg.ChildPolicy.Name)) |
| 104 | } else { |
| 105 | // If the child policy type has changed for existing sub-balancers, |
| 106 | // parse the new config and send down the config update to the |
| 107 | // balancergroup, which will take care of gracefully switching the |
| 108 | // child over to the new policy. |
| 109 | // |
| 110 | // If we run into errors here, we need to ensure that RPCs to this |
| 111 | // child fail, while RPCs to other children with good configs |
| 112 | // continue to succeed. |
| 113 | newPolicyName, oldPolicyName := childCfg.ChildPolicy.Name, b.children[childName].ChildPolicy.Name |
| 114 | if newPolicyName != oldPolicyName { |
| 115 | var err error |
| 116 | var cfgJSON []byte |
| 117 | cfgJSON, err = childCfg.ChildPolicy.MarshalJSON() |
| 118 | if err != nil { |
| 119 | retErr = fmt.Errorf("failed to JSON marshal load balancing policy for child %q: %v", childName, err) |
| 120 | b.setErrorPickerForChild(childName, retErr) |
| 121 | continue |
| 122 | } |
| 123 | // This overwrites lbCfg to be in the format expected by the |
| 124 | // gracefulswitch balancer. So, when this config is pushed to |
| 125 | // the child (below), it will result in a graceful switch to the |
| 126 | // new child policy. |
| 127 | lbCfg, err = balancergroup.ParseConfig(cfgJSON) |
| 128 | if err != nil { |
| 129 | retErr = fmt.Errorf("failed to parse load balancing policy for child %q: %v", childName, err) |
| 130 | b.setErrorPickerForChild(childName, retErr) |
| 131 | continue |
| 132 | } |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | if err := b.bg.UpdateClientConnState(childName, balancer.ClientConnState{ |
| 137 | ResolverState: resolver.State{ |
| 138 | Endpoints: endpointsSplit[childName], |
| 139 | ServiceConfig: s.ResolverState.ServiceConfig, |
| 140 | Attributes: s.ResolverState.Attributes, |
| 141 | }, |
| 142 | BalancerConfig: lbCfg, |
no test coverage detected