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.

132 lines
3.9 KiB

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