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 }