github.com/matrixorigin/matrixone@v0.7.0/pkg/dnservice/store_heartbeat.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package dnservice 16 17 import ( 18 "context" 19 "time" 20 21 logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 22 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 23 "go.uber.org/zap" 24 ) 25 26 func (s *store) heartbeatTask(ctx context.Context) { 27 if s.cfg.HAKeeper.HeatbeatInterval.Duration == 0 { 28 panic("invalid heartbeat interval") 29 } 30 defer func() { 31 s.rt.Logger().Info("dn heartbeat task stopped") 32 }() 33 34 ticker := time.NewTicker(s.cfg.HAKeeper.HeatbeatInterval.Duration) 35 defer ticker.Stop() 36 37 for { 38 select { 39 case <-ctx.Done(): 40 return 41 case <-ticker.C: 42 s.heartbeat(ctx) 43 // see pkg/logservice/service_commands.go#130 44 select { 45 case <-ctx.Done(): 46 return 47 default: 48 } 49 } 50 } 51 } 52 53 func (s *store) heartbeat(ctx context.Context) { 54 ctx2, cancel := context.WithTimeout(ctx, s.cfg.HAKeeper.HeatbeatTimeout.Duration) 55 defer cancel() 56 57 hb := logservicepb.DNStoreHeartbeat{ 58 UUID: s.cfg.UUID, 59 ServiceAddress: s.cfg.ServiceAddress, 60 Shards: s.getDNShardInfo(), 61 TaskServiceCreated: s.taskServiceCreated(), 62 LogtailServerAddress: s.cfg.LogtailServer.ListenAddress, 63 } 64 cb, err := s.hakeeperClient.SendDNHeartbeat(ctx2, hb) 65 if err != nil { 66 s.rt.Logger().Error("failed to send dn heartbeat", zap.Error(err)) 67 return 68 } 69 s.handleCommands(cb.Commands) 70 } 71 72 func (s *store) handleCommands(cmds []logservicepb.ScheduleCommand) { 73 for _, cmd := range cmds { 74 if cmd.ServiceType != logservicepb.DNService { 75 s.rt.Logger().Fatal("received invalid command", zap.String("command", cmd.LogString())) 76 } 77 s.rt.Logger().Debug("applying schedule command:", zap.String("command", cmd.LogString())) 78 if cmd.ConfigChange != nil { 79 switch cmd.ConfigChange.ChangeType { 80 case logservicepb.AddReplica, logservicepb.StartReplica: 81 s.handleAddReplica(cmd) 82 case logservicepb.RemoveReplica, logservicepb.StopReplica: 83 s.handleRemoveReplica(cmd) 84 } 85 } else if cmd.GetShutdownStore() != nil { 86 s.handleShutdownStore(cmd) 87 } else if cmd.CreateTaskService != nil { 88 s.createTaskService(cmd.CreateTaskService) 89 } 90 } 91 } 92 93 func (s *store) handleAddReplica(cmd logservicepb.ScheduleCommand) { 94 shardID := cmd.ConfigChange.Replica.ShardID 95 logShardID := cmd.ConfigChange.Replica.LogShardID 96 replicaID := cmd.ConfigChange.Replica.ReplicaID 97 address := s.cfg.ServiceAddress 98 if err := s.createReplica(metadata.DNShard{ 99 DNShardRecord: metadata.DNShardRecord{ 100 ShardID: shardID, 101 LogShardID: logShardID, 102 }, 103 ReplicaID: replicaID, 104 Address: address, 105 }); err != nil { 106 s.rt.Logger().Error("failed to add replica", zap.Error(err)) 107 } 108 } 109 110 func (s *store) handleRemoveReplica(cmd logservicepb.ScheduleCommand) { 111 shardID := cmd.ConfigChange.Replica.ShardID 112 if err := s.removeReplica(shardID); err != nil { 113 s.rt.Logger().Error("failed to remove replica", zap.Error(err)) 114 } 115 } 116 117 func (s *store) handleShutdownStore(_ logservicepb.ScheduleCommand) { 118 if err := s.Close(); err != nil { 119 s.rt.Logger().Error("failed to shutdown store", zap.Error(err)) 120 } 121 }