github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/edgehub/process.go (about) 1 package edgehub 2 3 import ( 4 "fmt" 5 "time" 6 7 "k8s.io/klog" 8 9 beehiveContext "github.com/kubeedge/beehive/pkg/core/context" 10 "github.com/kubeedge/beehive/pkg/core/model" 11 connect "github.com/kubeedge/kubeedge/edge/pkg/common/cloudconnection" 12 "github.com/kubeedge/kubeedge/edge/pkg/common/message" 13 "github.com/kubeedge/kubeedge/edge/pkg/common/modules" 14 "github.com/kubeedge/kubeedge/edge/pkg/edgehub/clients" 15 "github.com/kubeedge/kubeedge/edge/pkg/edgehub/config" 16 ) 17 18 const ( 19 waitConnectionPeriod = time.Minute 20 authEventType = "auth_info_event" 21 ) 22 23 var groupMap = map[string]string{ 24 "resource": modules.MetaGroup, 25 "twin": modules.TwinGroup, 26 "func": modules.MetaGroup, 27 "user": modules.BusGroup, 28 } 29 30 func (eh *EdgeHub) initial() (err error) { 31 32 cloudHubClient, err := clients.GetClient() 33 if err != nil { 34 return err 35 } 36 37 eh.chClient = cloudHubClient 38 39 return nil 40 } 41 42 func (eh *EdgeHub) addKeepChannel(msgID string) chan model.Message { 43 eh.keeperLock.Lock() 44 defer eh.keeperLock.Unlock() 45 46 tempChannel := make(chan model.Message) 47 eh.syncKeeper[msgID] = tempChannel 48 49 return tempChannel 50 } 51 52 func (eh *EdgeHub) deleteKeepChannel(msgID string) { 53 eh.keeperLock.Lock() 54 defer eh.keeperLock.Unlock() 55 56 delete(eh.syncKeeper, msgID) 57 } 58 59 func (eh *EdgeHub) isSyncResponse(msgID string) bool { 60 eh.keeperLock.RLock() 61 defer eh.keeperLock.RUnlock() 62 63 _, exist := eh.syncKeeper[msgID] 64 return exist 65 } 66 67 func (eh *EdgeHub) sendToKeepChannel(message model.Message) error { 68 eh.keeperLock.RLock() 69 defer eh.keeperLock.RUnlock() 70 channel, exist := eh.syncKeeper[message.GetParentID()] 71 if !exist { 72 klog.Errorf("failed to get sync keeper channel, messageID:%+v", message) 73 return fmt.Errorf("failed to get sync keeper channel, messageID:%+v", message) 74 } 75 // send response into synckeep channel 76 select { 77 case channel <- message: 78 default: 79 klog.Errorf("failed to send message to sync keep channel") 80 return fmt.Errorf("failed to send message to sync keep channel") 81 } 82 return nil 83 } 84 85 func (eh *EdgeHub) dispatch(message model.Message) error { 86 // TODO: dispatch message by the message type 87 md, ok := groupMap[message.GetGroup()] 88 if !ok { 89 klog.Warningf("msg_group not found") 90 return fmt.Errorf("msg_group not found") 91 } 92 93 isResponse := eh.isSyncResponse(message.GetParentID()) 94 if !isResponse { 95 beehiveContext.SendToGroup(md, message) 96 return nil 97 } 98 return eh.sendToKeepChannel(message) 99 } 100 101 func (eh *EdgeHub) routeToEdge() { 102 for { 103 select { 104 case <-beehiveContext.Done(): 105 klog.Warning("EdgeHub RouteToEdge stop") 106 return 107 default: 108 109 } 110 message, err := eh.chClient.Receive() 111 if err != nil { 112 klog.Errorf("websocket read error: %v", err) 113 eh.reconnectChan <- struct{}{} 114 return 115 } 116 117 klog.Infof("received msg from cloud-hub:%+v", message) 118 err = eh.dispatch(message) 119 if err != nil { 120 klog.Errorf("failed to dispatch message, discard: %v", err) 121 } 122 } 123 } 124 125 func (eh *EdgeHub) sendToCloud(message model.Message) error { 126 eh.keeperLock.Lock() 127 err := eh.chClient.Send(message) 128 eh.keeperLock.Unlock() 129 if err != nil { 130 klog.Errorf("failed to send message: %v", err) 131 return fmt.Errorf("failed to send message, error: %v", err) 132 } 133 134 syncKeep := func(message model.Message) { 135 tempChannel := eh.addKeepChannel(message.GetID()) 136 sendTimer := time.NewTimer(time.Duration(config.Config.Heartbeat) * time.Second) 137 select { 138 case response := <-tempChannel: 139 sendTimer.Stop() 140 beehiveContext.SendResp(response) 141 eh.deleteKeepChannel(response.GetParentID()) 142 case <-sendTimer.C: 143 klog.Warningf("timeout to receive response for message: %+v", message) 144 eh.deleteKeepChannel(message.GetID()) 145 } 146 } 147 148 if message.IsSync() { 149 go syncKeep(message) 150 } 151 152 return nil 153 } 154 155 func (eh *EdgeHub) routeToCloud() { 156 for { 157 select { 158 case <-beehiveContext.Done(): 159 klog.Warning("EdgeHub RouteToCloud stop") 160 return 161 default: 162 } 163 message, err := beehiveContext.Receive(ModuleNameEdgeHub) 164 if err != nil { 165 klog.Errorf("failed to receive message from edge: %v", err) 166 time.Sleep(time.Second) 167 continue 168 } 169 170 // post message to cloud hub 171 err = eh.sendToCloud(message) 172 if err != nil { 173 klog.Errorf("failed to send message to cloud: %v", err) 174 eh.reconnectChan <- struct{}{} 175 return 176 } 177 } 178 } 179 180 func (eh *EdgeHub) keepalive() { 181 for { 182 select { 183 case <-beehiveContext.Done(): 184 klog.Warning("EdgeHub KeepAlive stop") 185 return 186 default: 187 188 } 189 msg := model.NewMessage(""). 190 BuildRouter(ModuleNameEdgeHub, "resource", "node", "keepalive"). 191 FillBody("ping") 192 193 // post message to cloud hub 194 err := eh.sendToCloud(*msg) 195 if err != nil { 196 klog.Errorf("websocket write error: %v", err) 197 eh.reconnectChan <- struct{}{} 198 return 199 } 200 201 time.Sleep(time.Duration(config.Config.Heartbeat) * time.Second) 202 } 203 } 204 205 func (eh *EdgeHub) pubConnectInfo(isConnected bool) { 206 // var info model.Message 207 content := connect.CloudConnected 208 if !isConnected { 209 content = connect.CloudDisconnected 210 } 211 212 for _, group := range groupMap { 213 message := model.NewMessage("").BuildRouter(message.SourceNodeConnection, group, 214 message.ResourceTypeNodeConnection, message.OperationNodeConnection).FillBody(content) 215 beehiveContext.SendToGroup(group, *message) 216 } 217 }