topology.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (c) 2012 The gocql Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gocql
  5. import (
  6. "sync"
  7. "sync/atomic"
  8. )
  9. type Node interface {
  10. Pick(qry *Query) *Conn
  11. Close()
  12. }
  13. type RoundRobin struct {
  14. pool []Node
  15. pos uint32
  16. mu sync.RWMutex
  17. }
  18. func NewRoundRobin() *RoundRobin {
  19. return &RoundRobin{}
  20. }
  21. func (r *RoundRobin) AddNode(node Node) {
  22. r.mu.Lock()
  23. r.pool = append(r.pool, node)
  24. r.mu.Unlock()
  25. }
  26. func (r *RoundRobin) RemoveNode(node Node) {
  27. r.mu.Lock()
  28. n := len(r.pool)
  29. for i := 0; i < n; i++ {
  30. if r.pool[i] == node {
  31. r.pool[i], r.pool[n-1] = r.pool[n-1], r.pool[i]
  32. r.pool = r.pool[:n-1]
  33. break
  34. }
  35. }
  36. r.mu.Unlock()
  37. }
  38. func (r *RoundRobin) Size() int {
  39. r.mu.RLock()
  40. n := len(r.pool)
  41. r.mu.RUnlock()
  42. return n
  43. }
  44. func (r *RoundRobin) Pick(qry *Query) *Conn {
  45. pos := atomic.AddUint32(&r.pos, 1)
  46. var node Node
  47. r.mu.RLock()
  48. if len(r.pool) > 0 {
  49. node = r.pool[pos%uint32(len(r.pool))]
  50. }
  51. r.mu.RUnlock()
  52. if node == nil {
  53. return nil
  54. }
  55. return node.Pick(qry)
  56. }
  57. func (r *RoundRobin) Close() {
  58. r.mu.Lock()
  59. for i := 0; i < len(r.pool); i++ {
  60. r.pool[i].Close()
  61. }
  62. r.pool = nil
  63. r.mu.Unlock()
  64. }