Merge branch 'EDGE-301' into EDGE-299
authorjaehoon.hyun <jaehoon.hyun@samsung.com>
Tue, 2 Apr 2019 06:57:16 +0000 (15:57 +0900)
committerjaehoon.hyun <jaehoon.hyun@samsung.com>
Tue, 2 Apr 2019 06:57:16 +0000 (15:57 +0900)
# Conflicts:
# src/scoringmgr/handlers.go
# src/scoringmgr/mock/mock_lib_add.go

1  2 
src/scoringmgr/handlers.go
src/scoringmgr/mock/mock_lib_add.go

@@@ -25,185 -13,171 +25,303 @@@ const 
  )
  
  type Handler struct {
 -      handlerName   string
 -      libPath       string
 -      devicesScore  map[string]float64
 -      intervalMs    int
 -      resourceCount int
 -      scoreValue    chan float64
 -      symbolPtr     unsafe.Pointer
 +  handlerName   string
 +  libPath       string
 +  functionName  string
 +  devicesScore  map[string]float64
 +  intervalMs    int
 +  resourceCount int
-   scoreValue    int
++  scoreValue    float64
 +  statusSignal  chan int
 +  endSignal     chan bool
 +  parents       *Handlers
 +
 +  //for dynamic loading
 +  symbol        uintptr
 +  dl            uintptr
 +
  }
  
  type Handlers struct {
-   table map[string]*Handler
+       table map[string]*Handler
  
 -      Ch                  chan interface{}
 -      IloadScoringLibrary func(string, int, chan float64)
 +  Ch    chan interface{}
-   
++
 +  IRunningScore func (uintptr) ()
-   IGetScore     func (string, string) float64
++  IGetScore     func (string, string, chan float64) float64
  }
  
+ var (
+       handlers *Handlers
+ )
  
- func Init() (handlers *Handlers){
+ const (
+       // ConstLocalTarget is for knowing local environments
+       ConstLocalTarget = "localhost"
  
-   handlers = new(Handlers)
-   handlers.table = make(map[string]*Handler)
+       // ConstPrefixHTTP is "http://"
+       ConstPrefixHTTP = "http://"
  
-   return
+       // ConstWellknownPort is wellknonw port
+       ConstWellknownPort = 56001
+ )
+ func Init() *Handlers {
+       handlers = new(Handlers)
+       handlers.table = make(map[string]*Handler)
+       return handlers
  }
  
  //TODO : async notify lib loading
- func PushLibPath(libPath string, doc *confdescription.Doc,  handlersCh chan<- interface{}) (err error){
+ func PushLibPath(libPath string, doc *confdescription.Doc, handlersCh chan<- interface{}) (err error) {
 +  ILog.Printf("input PushLibPath : %s", libPath)
+       handlersCh <- pair{libPath, doc}
+       return nil
+ }
  
-   handlersCh <- pair{libPath, doc}
-   return nil
+ // GetScore is getting score of device
+ func GetScore(target string, name string) (scoreValue float64, err error) {
+       if strings.Compare(target, getOutboundIP()) == 0 || strings.Compare(target, ConstLocalTarget) == 0 {
+               scoreValue, err = getScoreLocalEnv(name)
+       } else {
+               scoreValue, err = getScoreRemoteEnv(target, name)
+       }
+       DLog.Println("scoreValue", scoreValue)
+       return
  }
  
+ // Listening function
  func (handlers *Handlers) Listening() {
  
-   go func(){
+       go func() {
  
 -              ILog.Println("listening started")
 -              for {
 +    ILog.Println("listening started")
 +    for {
 +      
 +      select {
 +        case obj := <- handlers.Ch :
 +          ILog.Printf("input handlers.Ch from configuremgr")
 +          handlers.makeHandler(obj.(pair)).runScoring()
  
-       }
 -                      select {
 -                      case obj := <-handlers.Ch:
++      } //select end
++              } // for end
  
-     }
 -                              handlerObj := handlers.makeHandler(obj.(pair))
 -                              handlers.runScoring(handlerObj)
 -                      }
 -              }
++      }() //function call
  
-   }()
 -      }()
+ }
+ func (handlers *Handlers) runScoring(handlerObj *Handler) {
+       go handlers.IloadScoringLibrary(handlerObj.libPath, handlerObj.intervalMs, handlerObj.scoreValue)
+       return
  }
  
 +func (handlers *Handlers) RemoveLib(libName string) {
 +  handler := handlers.table[libName]
 +
 +  //for producer
 +  handler.endSignal <- LIB_STATUS_DONE
 +
 +  //for consumer
 +  handler.endSignal <- LIB_STATUS_DONE
 +
 +  //Close dynamic loader
 +  defer C.dlclose(unsafe.Pointer(handler.dl))
 +
 +  ILog.Println("RemoveLib end")
 +}
 +
  func (handlers *Handlers) makeHandler(pairObj pair) (handlerObj *Handler) {
 -      handlerObj = new(Handler)
 -      handlerObj.handlerName = getLibName(pairObj.libPath)
 -      handlerObj.libPath = pairObj.libPath
 -      handlerObj.intervalMs = pairObj.doc.ResourceType.IntervalTimeMs
 -      handlerObj.devicesScore = make(map[string]float64)
 -      handlers.table[handlerObj.handlerName] = handlerObj
 +  handlerObj = new(Handler)
-   handlerObj.handlerName  = pairObj.libPath
++  handlerObj.handlerName  = getLibName(pairObj.libPath)
 +  handlerObj.libPath      = pairObj.libPath
 +  handlerObj.intervalMs   = pairObj.doc.ResourceType.IntervalTimeMs
 +  handlerObj.functionName = pairObj.doc.ScoringMethod.FunctionName
 +  handlerObj.devicesScore = make(map[string]float64)
 +  handlerObj.statusSignal = make(chan int, 1024)
 +  handlerObj.endSignal    = make(chan bool, 1024)
 +  handlerObj.parents      = handlers
  
-   handlers.table[pairObj.libPath] = handlerObj
+       handlerObj.scoreValue = make(chan float64, 1)
  
-   return
++      handlers.table[handlerObj.handlerName] = handlerObj
++
+       return
  }
  
-     handler.parents.IRunningScore(handler.symbol)
- }
 +func (handler *Handler) runScoring() {
 +
 +  ILog.Println("Run scoring")
 +
 +  go func(){
 +
 +    for {
 +      select {
 +        case status := <- handler.statusSignal :
 +          handler.process(status)
 +        case <- handler.endSignal :
 +          ILog.Println("consumer signal go routine die")
 +          return
 +      }
 +    }
 +  }()
 +
 +  go func() {
 +    
 +    handler.statusSignal <- LIB_STATUS_INIT
 +
 +    for {
 +
 +      select {
 +        case <- handler.endSignal :
 +          ILog.Println("producer signal go routine die")
 +          return
 +        default:
 +          handler.statusSignal <- LIB_STATUS_RUN
 +          time.Sleep(time.Duration(1000) * time.Millisecond)
 +          ILog.Printf("status run sleep time : %d\n", handler.intervalMs)
 +      }
 +
 +    }
 +
 +  }()
 +
 +  return
 +}
 +
 +func (handler *Handler) process(status int) {
 +
 +  switch(status){
 +    case LIB_STATUS_INIT:
 +      ILog.Printf("init\n")
 +      handler.init()
 +      break
 +    case LIB_STATUS_RUN:
 +    ILog.Printf("run\n")
 +      handler.running()
 +      break
 +  }
 +
 +}
 +
 +
 +func (handler *Handler) init() {
 +
 +  sym := C.CString(handler.functionName)
 +  defer C.free(unsafe.Pointer(sym))
 +
 +  lib := C.CString(handler.libPath)
 +  defer C.free(unsafe.Pointer(lib))
 +
 +  dl, err := C.dlopen(lib , C.RTLD_LAZY)
 +  handler.dl = uintptr(dl)
 +
 +  if err != nil {
 +    ELog.Fatal("dlopen error occured")
 +  }
 +  
 +  symbolPtr, symbolErr := C.dlsym(dl, sym)
 +  if symbolErr != nil {
 +    ELog.Fatal("symbol error occured")
 +  }
 +
 +  handler.symbol = uintptr(symbolPtr)
 +
 +  ILog.Printf("functionName : %s\n", handler.functionName)
 +  ILog.Printf("libPath      : %s\n", handler.libPath)
 +  ILog.Printf("symbol       : %#08X\n", handler.symbol)
 +
 +
 +  return 
 +}
 +
 +func (handler *Handler) running() {
 -func getChan(name string) (score chan float64, err error) {
 -      handlerObj := handlers.table[name]
++    handler.scoreValue = handler.parents.IRunningScore(handler.symbol)
++}
++
+ func getLibName(libPath string) string {
+       name := strings.Split(libPath, "/")
+       lastIdx := len(name)
+       libName := strings.Split(name[lastIdx-1], ".")
+       return strings.TrimPrefix(libName[0], "lib")
+ }
 -      if handlerObj == nil {
 -              err = errors.New("Invalid Service Name")
 -              return
 -      }
++// func getScore(name string) (score float64, err error) {
++//    handlerObj := handlers.table[name]
 -      score = handlerObj.scoreValue
++//    if handlerObj == nil {
++//            err = errors.New("Invalid Service Name")
++//            return
++//    }
 -      return
 -}
++//    score = handlerObj.scoreValue
 -      scoreChan, err := getChan(name)
 -      if err != nil {
 -              return
 -      }
++//    return
++// }
+ func getScoreLocalEnv(name string) (scoreValue float64, err error) {
 -      select {
 -      case scoreValue = <-scoreChan:
 -              DLog.Println(scoreValue)
++      // scoreChan, err := getScore(name)
++      // if err != nil {
++      //      return
++      // }
++
++      // select {
++      // case scoreValue = <-scoreChan:
++      //      DLog.Println(scoreValue)
++      // }
++      // return
 -      return
++  handlerObj := handlers.table[name]
++
++      if handlerObj == nil {
++              err = errors.New("Invalid Service Name")
++              return
+       }
++      scoreValue = handlerObj.scoreValue
++  
++  return
+ }
+ func getScoreRemoteEnv(target string, name string) (scoreValue float64, err error) {
+       targetURL := ConstPrefixHTTP + target + ":" + strconv.Itoa(ConstWellknownPort) + "/" + name
+       respBytes, err := doGet(targetURL)
+       if checkError(err) == true {
+               return scoreValue, err
+       }
+       var responseMsg map[string]interface{}
+       err = json.Unmarshal(respBytes, &responseMsg)
+       if err == nil {
+               scoreValue = responseMsg["ScoreValue"].(float64)
+       }
+       return
+ }
+ func getOutboundIP() string {
+       conn, err := net.Dial("udp", "8.8.8.8:80")
+       if err != nil {
+               log.Fatal(err)
+       }
+       defer conn.Close()
+       localAddr := conn.LocalAddr().(*net.UDPAddr)
+       return localAddr.IP.String()
+ }
+ func checkError(err error) bool {
+       if err != nil {
+               log.Println(err.Error())
+               return true
+       }
+       return false
+ }
@@@ -7,15 -11,47 +7,14 @@@ wrap_add(void *f, int a, int b)
  }
  */
  import "C"
- import "unsafe"
  import (
 -      "unsafe"
 -
 -      scoringmgr "scoringmgr"
 -      "time"
 +  scoringmgr "scoringmgr"
  )
  
- func LoadScoringAddInterface(symbol uintptr) {
 -// LoadScoringAdd function
 -func LoadScoringAdd(libPath string, intervalMs int, scoreChan chan float64) {
 -
 -      sym := C.CString("add")
 -      defer C.free(unsafe.Pointer(sym))
 -
 -      lib := C.CString(libPath)
 -      defer C.free(unsafe.Pointer(lib))
 -
 -      handle, err := C.dlopen(lib, C.RTLD_LAZY)
 -      defer C.dlclose(handle)
++func LoadScoringAddInterface(symbol uintptr) float64{
  
-   scoringmgr.ILog.Println(C.wrap_add(unsafe.Pointer(symbol),2,3))
 -      if err != nil {
 -              scoringmgr.ELog.Fatal("dlopen error occured")
 -      }
++  ret := C.wrap_add(unsafe.Pointer(symbol),2,3)
++  scoringmgr.ILog.Println(ret)
  
-   return 
 -      symbolPtr, symbolErr := C.dlsym(handle, sym)
 -      if symbolErr != nil {
 -              scoringmgr.ELog.Fatal("symbol error occured")
 -      }
 -
 -      for {
 -              select {
 -              case scoreChan <- float64(C.wrap_add(symbolPtr, C.int(2), 3)):
 -                      scoringmgr.ILog.Println(C.wrap_add(symbolPtr, C.int(2), 3))
 -              default:
 -                      go func() {
 -                              <-scoreChan
 -                              scoreChan <- float64(C.wrap_add(symbolPtr, C.int(2), 3))
 -                      }()
 -              }
 -
 -              time.Sleep(time.Duration(intervalMs) * time.Millisecond)
 -      }
 -
 -      // return
--}
++  return float64(ret)
++)