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.

122 lines
3.3 KiB

7 years ago
  1. package weed_server
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/chrislusf/seaweedfs/weed/glog"
  6. "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
  7. "github.com/chrislusf/seaweedfs/weed/security"
  8. "github.com/chrislusf/seaweedfs/weed/util"
  9. "golang.org/x/net/context"
  10. )
  11. func (vs *VolumeServer) GetMaster() string {
  12. return vs.currentMaster
  13. }
  14. func (vs *VolumeServer) heartbeat() {
  15. glog.V(0).Infof("Volume server start with masters: %v", vs.MasterNodes)
  16. vs.store.SetDataCenter(vs.dataCenter)
  17. vs.store.SetRack(vs.rack)
  18. var err error
  19. var newLeader string
  20. for {
  21. for _, master := range vs.MasterNodes {
  22. if newLeader != "" {
  23. master = newLeader
  24. }
  25. masterGrpcAddress, parseErr := util.ParseServerToGrpcAddress(master, 0)
  26. if parseErr != nil {
  27. glog.V(0).Infof("failed to parse master grpc %v", masterGrpcAddress)
  28. continue
  29. }
  30. newLeader, err = vs.doHeartbeat(master, masterGrpcAddress, time.Duration(vs.pulseSeconds)*time.Second)
  31. if err != nil {
  32. glog.V(0).Infof("heartbeat error: %v", err)
  33. time.Sleep(time.Duration(vs.pulseSeconds) * time.Second)
  34. }
  35. }
  36. }
  37. }
  38. func (vs *VolumeServer) doHeartbeat(masterNode, masterGrpcAddress string, sleepInterval time.Duration) (newLeader string, err error) {
  39. grpcConection, err := util.GrpcDial(masterGrpcAddress)
  40. if err != nil {
  41. return "", fmt.Errorf("fail to dial %s : %v", masterNode, err)
  42. }
  43. defer grpcConection.Close()
  44. client := master_pb.NewSeaweedClient(grpcConection)
  45. stream, err := client.SendHeartbeat(context.Background())
  46. if err != nil {
  47. glog.V(0).Infof("SendHeartbeat to %s: %v", masterNode, err)
  48. return "", err
  49. }
  50. glog.V(0).Infof("Heartbeat to: %v", masterNode)
  51. vs.currentMaster = masterNode
  52. vs.store.Client = stream
  53. defer func() { vs.store.Client = nil }()
  54. doneChan := make(chan error, 1)
  55. go func() {
  56. for {
  57. in, err := stream.Recv()
  58. if err != nil {
  59. doneChan <- err
  60. return
  61. }
  62. if in.GetVolumeSizeLimit() != 0 {
  63. vs.store.VolumeSizeLimit = in.GetVolumeSizeLimit()
  64. }
  65. if in.GetSecretKey() != "" {
  66. vs.guard.SecretKey = security.Secret(in.GetSecretKey())
  67. }
  68. if in.GetLeader() != "" && masterNode != in.GetLeader() {
  69. glog.V(0).Infof("Volume Server found a new master newLeader: %v instead of %v", in.GetLeader(), masterNode)
  70. newLeader = in.GetLeader()
  71. doneChan <- nil
  72. return
  73. }
  74. }
  75. }()
  76. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  77. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  78. return "", err
  79. }
  80. tickChan := time.Tick(sleepInterval)
  81. for {
  82. select {
  83. case vid := <-vs.store.NewVolumeIdChan:
  84. deltaBeat := &master_pb.Heartbeat{
  85. NewVids: []uint32{uint32(vid)},
  86. }
  87. if err = stream.Send(deltaBeat); err != nil {
  88. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  89. return "", err
  90. }
  91. case vid := <-vs.store.DeletedVolumeIdChan:
  92. deltaBeat := &master_pb.Heartbeat{
  93. DeletedVids: []uint32{uint32(vid)},
  94. }
  95. if err = stream.Send(deltaBeat); err != nil {
  96. glog.V(0).Infof("Volume Server Failed to update to master %s: %v", masterNode, err)
  97. return "", err
  98. }
  99. case <-tickChan:
  100. if err = stream.Send(vs.store.CollectHeartbeat()); err != nil {
  101. glog.V(0).Infof("Volume Server Failed to talk with master %s: %v", masterNode, err)
  102. return "", err
  103. }
  104. case err = <-doneChan:
  105. return
  106. }
  107. }
  108. }