You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

329 lines
8.2 KiB

  1. /*
  2. *
  3. * Copyright 2017 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package grpc
  19. import (
  20. "fmt"
  21. "sync"
  22. "google.golang.org/grpc/balancer"
  23. "google.golang.org/grpc/connectivity"
  24. "google.golang.org/grpc/grpclog"
  25. "google.golang.org/grpc/resolver"
  26. )
  27. // scStateUpdate contains the subConn and the new state it changed to.
  28. type scStateUpdate struct {
  29. sc balancer.SubConn
  30. state connectivity.State
  31. }
  32. // scStateUpdateBuffer is an unbounded channel for scStateChangeTuple.
  33. // TODO make a general purpose buffer that uses interface{}.
  34. type scStateUpdateBuffer struct {
  35. c chan *scStateUpdate
  36. mu sync.Mutex
  37. backlog []*scStateUpdate
  38. }
  39. func newSCStateUpdateBuffer() *scStateUpdateBuffer {
  40. return &scStateUpdateBuffer{
  41. c: make(chan *scStateUpdate, 1),
  42. }
  43. }
  44. func (b *scStateUpdateBuffer) put(t *scStateUpdate) {
  45. b.mu.Lock()
  46. defer b.mu.Unlock()
  47. if len(b.backlog) == 0 {
  48. select {
  49. case b.c <- t:
  50. return
  51. default:
  52. }
  53. }
  54. b.backlog = append(b.backlog, t)
  55. }
  56. func (b *scStateUpdateBuffer) load() {
  57. b.mu.Lock()
  58. defer b.mu.Unlock()
  59. if len(b.backlog) > 0 {
  60. select {
  61. case b.c <- b.backlog[0]:
  62. b.backlog[0] = nil
  63. b.backlog = b.backlog[1:]
  64. default:
  65. }
  66. }
  67. }
  68. // get returns the channel that the scStateUpdate will be sent to.
  69. //
  70. // Upon receiving, the caller should call load to send another
  71. // scStateChangeTuple onto the channel if there is any.
  72. func (b *scStateUpdateBuffer) get() <-chan *scStateUpdate {
  73. return b.c
  74. }
  75. // resolverUpdate contains the new resolved addresses or error if there's
  76. // any.
  77. type resolverUpdate struct {
  78. addrs []resolver.Address
  79. err error
  80. }
  81. // ccBalancerWrapper is a wrapper on top of cc for balancers.
  82. // It implements balancer.ClientConn interface.
  83. type ccBalancerWrapper struct {
  84. cc *ClientConn
  85. balancer balancer.Balancer
  86. stateChangeQueue *scStateUpdateBuffer
  87. resolverUpdateCh chan *resolverUpdate
  88. done chan struct{}
  89. mu sync.Mutex
  90. subConns map[*acBalancerWrapper]struct{}
  91. }
  92. func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper {
  93. ccb := &ccBalancerWrapper{
  94. cc: cc,
  95. stateChangeQueue: newSCStateUpdateBuffer(),
  96. resolverUpdateCh: make(chan *resolverUpdate, 1),
  97. done: make(chan struct{}),
  98. subConns: make(map[*acBalancerWrapper]struct{}),
  99. }
  100. go ccb.watcher()
  101. ccb.balancer = b.Build(ccb, bopts)
  102. return ccb
  103. }
  104. // watcher balancer functions sequentially, so the balancer can be implemented
  105. // lock-free.
  106. func (ccb *ccBalancerWrapper) watcher() {
  107. for {
  108. select {
  109. case t := <-ccb.stateChangeQueue.get():
  110. ccb.stateChangeQueue.load()
  111. select {
  112. case <-ccb.done:
  113. ccb.balancer.Close()
  114. return
  115. default:
  116. }
  117. ccb.balancer.HandleSubConnStateChange(t.sc, t.state)
  118. case t := <-ccb.resolverUpdateCh:
  119. select {
  120. case <-ccb.done:
  121. ccb.balancer.Close()
  122. return
  123. default:
  124. }
  125. ccb.balancer.HandleResolvedAddrs(t.addrs, t.err)
  126. case <-ccb.done:
  127. }
  128. select {
  129. case <-ccb.done:
  130. ccb.balancer.Close()
  131. ccb.mu.Lock()
  132. scs := ccb.subConns
  133. ccb.subConns = nil
  134. ccb.mu.Unlock()
  135. for acbw := range scs {
  136. ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
  137. }
  138. return
  139. default:
  140. }
  141. }
  142. }
  143. func (ccb *ccBalancerWrapper) close() {
  144. close(ccb.done)
  145. }
  146. func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
  147. // When updating addresses for a SubConn, if the address in use is not in
  148. // the new addresses, the old ac will be tearDown() and a new ac will be
  149. // created. tearDown() generates a state change with Shutdown state, we
  150. // don't want the balancer to receive this state change. So before
  151. // tearDown() on the old ac, ac.acbw (acWrapper) will be set to nil, and
  152. // this function will be called with (nil, Shutdown). We don't need to call
  153. // balancer method in this case.
  154. if sc == nil {
  155. return
  156. }
  157. ccb.stateChangeQueue.put(&scStateUpdate{
  158. sc: sc,
  159. state: s,
  160. })
  161. }
  162. func (ccb *ccBalancerWrapper) handleResolvedAddrs(addrs []resolver.Address, err error) {
  163. if ccb.cc.curBalancerName != grpclbName {
  164. var containsGRPCLB bool
  165. for _, a := range addrs {
  166. if a.Type == resolver.GRPCLB {
  167. containsGRPCLB = true
  168. break
  169. }
  170. }
  171. if containsGRPCLB {
  172. // The current balancer is not grpclb, but addresses contain grpclb
  173. // address. This means we failed to switch to grpclb, most likely
  174. // because grpclb is not registered. Filter out all grpclb addresses
  175. // from addrs before sending to balancer.
  176. tempAddrs := make([]resolver.Address, 0, len(addrs))
  177. for _, a := range addrs {
  178. if a.Type != resolver.GRPCLB {
  179. tempAddrs = append(tempAddrs, a)
  180. }
  181. }
  182. addrs = tempAddrs
  183. }
  184. }
  185. select {
  186. case <-ccb.resolverUpdateCh:
  187. default:
  188. }
  189. ccb.resolverUpdateCh <- &resolverUpdate{
  190. addrs: addrs,
  191. err: err,
  192. }
  193. }
  194. func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  195. if len(addrs) <= 0 {
  196. return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
  197. }
  198. ccb.mu.Lock()
  199. defer ccb.mu.Unlock()
  200. if ccb.subConns == nil {
  201. return nil, fmt.Errorf("grpc: ClientConn balancer wrapper was closed")
  202. }
  203. ac, err := ccb.cc.newAddrConn(addrs, opts)
  204. if err != nil {
  205. return nil, err
  206. }
  207. acbw := &acBalancerWrapper{ac: ac}
  208. acbw.ac.mu.Lock()
  209. ac.acbw = acbw
  210. acbw.ac.mu.Unlock()
  211. ccb.subConns[acbw] = struct{}{}
  212. return acbw, nil
  213. }
  214. func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
  215. acbw, ok := sc.(*acBalancerWrapper)
  216. if !ok {
  217. return
  218. }
  219. ccb.mu.Lock()
  220. defer ccb.mu.Unlock()
  221. if ccb.subConns == nil {
  222. return
  223. }
  224. delete(ccb.subConns, acbw)
  225. ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
  226. }
  227. func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balancer.Picker) {
  228. ccb.mu.Lock()
  229. defer ccb.mu.Unlock()
  230. if ccb.subConns == nil {
  231. return
  232. }
  233. // Update picker before updating state. Even though the ordering here does
  234. // not matter, it can lead to multiple calls of Pick in the common start-up
  235. // case where we wait for ready and then perform an RPC. If the picker is
  236. // updated later, we could call the "connecting" picker when the state is
  237. // updated, and then call the "ready" picker after the picker gets updated.
  238. ccb.cc.blockingpicker.updatePicker(p)
  239. ccb.cc.csMgr.updateState(s)
  240. }
  241. func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOption) {
  242. ccb.cc.resolveNow(o)
  243. }
  244. func (ccb *ccBalancerWrapper) Target() string {
  245. return ccb.cc.target
  246. }
  247. // acBalancerWrapper is a wrapper on top of ac for balancers.
  248. // It implements balancer.SubConn interface.
  249. type acBalancerWrapper struct {
  250. mu sync.Mutex
  251. ac *addrConn
  252. }
  253. func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
  254. acbw.mu.Lock()
  255. defer acbw.mu.Unlock()
  256. if len(addrs) <= 0 {
  257. acbw.ac.tearDown(errConnDrain)
  258. return
  259. }
  260. if !acbw.ac.tryUpdateAddrs(addrs) {
  261. cc := acbw.ac.cc
  262. opts := acbw.ac.scopts
  263. acbw.ac.mu.Lock()
  264. // Set old ac.acbw to nil so the Shutdown state update will be ignored
  265. // by balancer.
  266. //
  267. // TODO(bar) the state transition could be wrong when tearDown() old ac
  268. // and creating new ac, fix the transition.
  269. acbw.ac.acbw = nil
  270. acbw.ac.mu.Unlock()
  271. acState := acbw.ac.getState()
  272. acbw.ac.tearDown(errConnDrain)
  273. if acState == connectivity.Shutdown {
  274. return
  275. }
  276. ac, err := cc.newAddrConn(addrs, opts)
  277. if err != nil {
  278. grpclog.Warningf("acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err)
  279. return
  280. }
  281. acbw.ac = ac
  282. ac.mu.Lock()
  283. ac.acbw = acbw
  284. ac.mu.Unlock()
  285. if acState != connectivity.Idle {
  286. ac.connect()
  287. }
  288. }
  289. }
  290. func (acbw *acBalancerWrapper) Connect() {
  291. acbw.mu.Lock()
  292. defer acbw.mu.Unlock()
  293. acbw.ac.connect()
  294. }
  295. func (acbw *acBalancerWrapper) getAddrConn() *addrConn {
  296. acbw.mu.Lock()
  297. defer acbw.mu.Unlock()
  298. return acbw.ac
  299. }