nodemgmt.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package networkdb
  2. import (
  3. "fmt"
  4. "github.com/hashicorp/memberlist"
  5. "github.com/sirupsen/logrus"
  6. )
  7. type nodeState int
  8. const (
  9. nodeNotFound nodeState = -1
  10. nodeActiveState nodeState = 0
  11. nodeLeftState nodeState = 1
  12. nodeFailedState nodeState = 2
  13. )
  14. var nodeStateName = map[nodeState]string{
  15. -1: "NodeNotFound",
  16. 0: "NodeActive",
  17. 1: "NodeLeft",
  18. 2: "NodeFailed",
  19. }
  20. // findNode search the node into the 3 node lists and returns the node pointer and the list
  21. // where it got found
  22. func (nDB *NetworkDB) findNode(nodeName string) (*node, nodeState, map[string]*node) {
  23. for i, nodes := range []map[string]*node{
  24. nDB.nodes,
  25. nDB.leftNodes,
  26. nDB.failedNodes,
  27. } {
  28. if n, ok := nodes[nodeName]; ok {
  29. return n, nodeState(i), nodes
  30. }
  31. }
  32. return nil, nodeNotFound, nil
  33. }
  34. // changeNodeState changes the state of the node specified, returns true if the node was moved,
  35. // false if there was no need to change the node state. Error will be returned if the node does not
  36. // exists
  37. func (nDB *NetworkDB) changeNodeState(nodeName string, newState nodeState) (bool, error) {
  38. n, currState, m := nDB.findNode(nodeName)
  39. if n == nil {
  40. return false, fmt.Errorf("node %s not found", nodeName)
  41. }
  42. switch newState {
  43. case nodeActiveState:
  44. if currState == nodeActiveState {
  45. return false, nil
  46. }
  47. delete(m, nodeName)
  48. // reset the node reap time
  49. n.reapTime = 0
  50. nDB.nodes[nodeName] = n
  51. case nodeLeftState:
  52. if currState == nodeLeftState {
  53. return false, nil
  54. }
  55. delete(m, nodeName)
  56. nDB.leftNodes[nodeName] = n
  57. case nodeFailedState:
  58. if currState == nodeFailedState {
  59. return false, nil
  60. }
  61. delete(m, nodeName)
  62. nDB.failedNodes[nodeName] = n
  63. }
  64. logrus.Infof("Node %s change state %s --> %s", nodeName, nodeStateName[currState], nodeStateName[newState])
  65. if newState == nodeLeftState || newState == nodeFailedState {
  66. // set the node reap time, if not already set
  67. // It is possible that a node passes from failed to left and the reaptime was already set so keep that value
  68. if n.reapTime == 0 {
  69. n.reapTime = nodeReapInterval
  70. }
  71. // The node leave or fails, delete all the entries created by it.
  72. // If the node was temporary down, deleting the entries will guarantee that the CREATE events will be accepted
  73. // If the node instead left because was going down, then it makes sense to just delete all its state
  74. nDB.deleteNodeFromNetworks(n.Name)
  75. nDB.deleteNodeTableEntries(n.Name)
  76. }
  77. return true, nil
  78. }
  79. func (nDB *NetworkDB) purgeReincarnation(mn *memberlist.Node) bool {
  80. for name, node := range nDB.nodes {
  81. if node.Addr.Equal(mn.Addr) && node.Port == mn.Port && mn.Name != name {
  82. logrus.Infof("Node %s/%s, is the new incarnation of the active node %s/%s", mn.Name, mn.Addr, name, node.Addr)
  83. nDB.changeNodeState(name, nodeLeftState)
  84. return true
  85. }
  86. }
  87. for name, node := range nDB.failedNodes {
  88. if node.Addr.Equal(mn.Addr) && node.Port == mn.Port && mn.Name != name {
  89. logrus.Infof("Node %s/%s, is the new incarnation of the failed node %s/%s", mn.Name, mn.Addr, name, node.Addr)
  90. nDB.changeNodeState(name, nodeLeftState)
  91. return true
  92. }
  93. }
  94. for name, node := range nDB.leftNodes {
  95. if node.Addr.Equal(mn.Addr) && node.Port == mn.Port && mn.Name != name {
  96. logrus.Infof("Node %s/%s, is the new incarnation of the shutdown node %s/%s", mn.Name, mn.Addr, name, node.Addr)
  97. nDB.changeNodeState(name, nodeLeftState)
  98. return true
  99. }
  100. }
  101. return false
  102. }