balancer_conn_wrappers.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. select {
  164. case <-ccb.resolverUpdateCh:
  165. default:
  166. }
  167. ccb.resolverUpdateCh <- &resolverUpdate{
  168. addrs: addrs,
  169. err: err,
  170. }
  171. }
  172. func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  173. if len(addrs) <= 0 {
  174. return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
  175. }
  176. ccb.mu.Lock()
  177. defer ccb.mu.Unlock()
  178. if ccb.subConns == nil {
  179. return nil, fmt.Errorf("grpc: ClientConn balancer wrapper was closed")
  180. }
  181. ac, err := ccb.cc.newAddrConn(addrs, opts)
  182. if err != nil {
  183. return nil, err
  184. }
  185. acbw := &acBalancerWrapper{ac: ac}
  186. acbw.ac.mu.Lock()
  187. ac.acbw = acbw
  188. acbw.ac.mu.Unlock()
  189. ccb.subConns[acbw] = struct{}{}
  190. return acbw, nil
  191. }
  192. func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
  193. acbw, ok := sc.(*acBalancerWrapper)
  194. if !ok {
  195. return
  196. }
  197. ccb.mu.Lock()
  198. defer ccb.mu.Unlock()
  199. if ccb.subConns == nil {
  200. return
  201. }
  202. delete(ccb.subConns, acbw)
  203. ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
  204. }
  205. func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balancer.Picker) {
  206. ccb.mu.Lock()
  207. defer ccb.mu.Unlock()
  208. if ccb.subConns == nil {
  209. return
  210. }
  211. // Update picker before updating state. Even though the ordering here does
  212. // not matter, it can lead to multiple calls of Pick in the common start-up
  213. // case where we wait for ready and then perform an RPC. If the picker is
  214. // updated later, we could call the "connecting" picker when the state is
  215. // updated, and then call the "ready" picker after the picker gets updated.
  216. ccb.cc.blockingpicker.updatePicker(p)
  217. ccb.cc.csMgr.updateState(s)
  218. }
  219. func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOption) {
  220. ccb.cc.resolveNow(o)
  221. }
  222. func (ccb *ccBalancerWrapper) Target() string {
  223. return ccb.cc.target
  224. }
  225. // acBalancerWrapper is a wrapper on top of ac for balancers.
  226. // It implements balancer.SubConn interface.
  227. type acBalancerWrapper struct {
  228. mu sync.Mutex
  229. ac *addrConn
  230. }
  231. func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
  232. acbw.mu.Lock()
  233. defer acbw.mu.Unlock()
  234. if len(addrs) <= 0 {
  235. acbw.ac.tearDown(errConnDrain)
  236. return
  237. }
  238. if !acbw.ac.tryUpdateAddrs(addrs) {
  239. cc := acbw.ac.cc
  240. opts := acbw.ac.scopts
  241. acbw.ac.mu.Lock()
  242. // Set old ac.acbw to nil so the Shutdown state update will be ignored
  243. // by balancer.
  244. //
  245. // TODO(bar) the state transition could be wrong when tearDown() old ac
  246. // and creating new ac, fix the transition.
  247. acbw.ac.acbw = nil
  248. acbw.ac.mu.Unlock()
  249. acState := acbw.ac.getState()
  250. acbw.ac.tearDown(errConnDrain)
  251. if acState == connectivity.Shutdown {
  252. return
  253. }
  254. ac, err := cc.newAddrConn(addrs, opts)
  255. if err != nil {
  256. grpclog.Warningf("acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err)
  257. return
  258. }
  259. acbw.ac = ac
  260. ac.mu.Lock()
  261. ac.acbw = acbw
  262. ac.mu.Unlock()
  263. if acState != connectivity.Idle {
  264. ac.connect()
  265. }
  266. }
  267. }
  268. func (acbw *acBalancerWrapper) Connect() {
  269. acbw.mu.Lock()
  270. defer acbw.mu.Unlock()
  271. acbw.ac.connect()
  272. }
  273. func (acbw *acBalancerWrapper) getAddrConn() *addrConn {
  274. acbw.mu.Lock()
  275. defer acbw.mu.Unlock()
  276. return acbw.ac
  277. }