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  }