github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/devicetwin/dtcontext/dtcontext.go (about)

     1  package dtcontext
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  	"sync"
     8  	"time"
     9  
    10  	"k8s.io/klog"
    11  
    12  	"github.com/kubeedge/beehive/pkg/core/model"
    13  	"github.com/kubeedge/kubeedge/edge/pkg/common/modules"
    14  	deviceconfig "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/config"
    15  	"github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dtcommon"
    16  	"github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dttype"
    17  )
    18  
    19  var (
    20  	//IsDetail deal detail lock
    21  	IsDetail = false
    22  )
    23  
    24  //DTContext context for devicetwin
    25  type DTContext struct {
    26  	GroupID        string
    27  	NodeName       string
    28  	CommChan       map[string]chan interface{}
    29  	ConfirmChan    chan interface{}
    30  	ConfirmMap     *sync.Map
    31  	ModulesHealth  *sync.Map
    32  	ModulesContext *context.Context
    33  	DeviceList     *sync.Map
    34  	DeviceMutex    *sync.Map
    35  	Mutex          *sync.RWMutex
    36  	// DBConn *dtclient.Conn
    37  	State string
    38  }
    39  
    40  //InitDTContext init dtcontext
    41  func InitDTContext() (*DTContext, error) {
    42  	return &DTContext{
    43  		GroupID:       "",
    44  		NodeName:      deviceconfig.Config.NodeName,
    45  		CommChan:      make(map[string]chan interface{}),
    46  		ConfirmChan:   make(chan interface{}, 1000),
    47  		ConfirmMap:    &sync.Map{},
    48  		ModulesHealth: &sync.Map{},
    49  		DeviceList:    &sync.Map{},
    50  		DeviceMutex:   &sync.Map{},
    51  		Mutex:         &sync.RWMutex{},
    52  		State:         dtcommon.Disconnected,
    53  	}, nil
    54  }
    55  
    56  //CommTo communicate
    57  func (dtc *DTContext) CommTo(dtmName string, content interface{}) error {
    58  	if v, exist := dtc.CommChan[dtmName]; exist {
    59  		v <- content
    60  		return nil
    61  	}
    62  	return errors.New("Not found chan to communicate")
    63  }
    64  
    65  //HeartBeat hearbeat to dtcontroller
    66  func (dtc *DTContext) HeartBeat(dtmName string, content interface{}) error {
    67  	if strings.Compare(content.(string), "ping") == 0 {
    68  		dtc.ModulesHealth.Store(dtmName, time.Now().Unix())
    69  		klog.Infof("%s is healthy %v", dtmName, time.Now().Unix())
    70  
    71  	} else if strings.Compare(content.(string), "stop") == 0 {
    72  		klog.Infof("%s stop", dtmName)
    73  		return errors.New("stop")
    74  	}
    75  	return nil
    76  }
    77  
    78  //GetMutex get mutex
    79  func (dtc *DTContext) GetMutex(deviceID string) (*sync.Mutex, bool) {
    80  	v, mutexExist := dtc.DeviceMutex.Load(deviceID)
    81  	if !mutexExist {
    82  		klog.Errorf("GetMutex device %s not exist", deviceID)
    83  		return nil, false
    84  	}
    85  	mutex, isMutex := v.(*sync.Mutex)
    86  	if isMutex {
    87  		return mutex, true
    88  	}
    89  	return nil, false
    90  }
    91  
    92  //Lock get the lock of the device
    93  func (dtc *DTContext) Lock(deviceID string) bool {
    94  	deviceMutex, ok := dtc.GetMutex(deviceID)
    95  	if ok {
    96  		dtc.Mutex.RLock()
    97  		deviceMutex.Lock()
    98  		return true
    99  	}
   100  	return false
   101  }
   102  
   103  //Unlock remove the lock of the device
   104  func (dtc *DTContext) Unlock(deviceID string) bool {
   105  	deviceMutex, ok := dtc.GetMutex(deviceID)
   106  	if ok {
   107  		deviceMutex.Unlock()
   108  		dtc.Mutex.RUnlock()
   109  		return true
   110  	}
   111  	return false
   112  }
   113  
   114  // LockAll get all lock
   115  func (dtc *DTContext) LockAll() {
   116  	dtc.Mutex.Lock()
   117  }
   118  
   119  // UnlockAll get all lock
   120  func (dtc *DTContext) UnlockAll() {
   121  	dtc.Mutex.Unlock()
   122  }
   123  
   124  //IsDeviceExist judge device is exist
   125  func (dtc *DTContext) IsDeviceExist(deviceID string) bool {
   126  	_, ok := dtc.DeviceList.Load(deviceID)
   127  	return ok
   128  }
   129  
   130  //GetDevice get device
   131  func (dtc *DTContext) GetDevice(deviceID string) (*dttype.Device, bool) {
   132  	d, ok := dtc.DeviceList.Load(deviceID)
   133  	if ok {
   134  		if device, isDevice := d.(*dttype.Device); isDevice {
   135  			return device, true
   136  		}
   137  		return nil, false
   138  	}
   139  	return nil, false
   140  }
   141  
   142  //Send send result
   143  func (dtc *DTContext) Send(identity string, action string, module string, msg *model.Message) error {
   144  	dtMsg := &dttype.DTMessage{
   145  		Action:   action,
   146  		Identity: identity,
   147  		Type:     module,
   148  		Msg:      msg}
   149  	return dtc.CommTo(module, dtMsg)
   150  }
   151  
   152  //BuildModelMessage build mode messages
   153  func (dtc *DTContext) BuildModelMessage(group string, parentID string, resource string, operation string, content interface{}) *model.Message {
   154  	msg := model.NewMessage(parentID)
   155  	msg.BuildRouter(modules.TwinGroup, group, resource, operation)
   156  	msg.Content = content
   157  	return msg
   158  }