package scoringmgr
-
+/*
+#include <stdlib.h>
+#include <dlfcn.h>
+#cgo LDFLAGS: -ldl
+*/
+import "C"
import "unsafe"
import (
+
+ "time"
confdescription "configuremgr/description"
+
+)
+
+const (
+ LIB_STATUS_INIT = 1
+ LIB_STATUS_RUN = 2
+ LIB_STATUS_DONE = 3
)
type Handler struct {
handlerName string
libPath string
+ functionName string
devicesScore map[string]float64
intervalMs int
resourceCount int
scoreValue int
- symbolPtr unsafe.Pointer
+ statusSignal chan int
+ endSignal chan bool
+ parents *Handlers
+
+ //for dynamic loading
+ symbol uintptr
+ dl uintptr
}
type Handlers struct {
table map[string]*Handler
- Ch chan interface{}
- IloadScoringLibrary func (string, int) ()
- GetScore func (string) float64
+ Ch chan interface{}
+
+ IRunningScore func (uintptr) ()
+ IGetScore func (string, string) float64
}
select {
case obj := <- handlers.Ch :
ILog.Printf("input handlers.Ch from configuremgr")
- handlerObj := handlers.makeHandler(obj.(pair))
- handlers.runScoring(handlerObj)
+ handlers.makeHandler(obj.(pair)).runScoring()
+
}
}
}()
}
+func (handlers *Handlers) RemoveLib(libName string) {
+ handler := handlers.table[libName]
+
+ //for producer
+ handler.statusSignal <- LIB_STATUS_DONE
+
+ //for consumer
+ handler.statusSignal <- LIB_STATUS_DONE
+
+ //Close dynamic loader
+ defer C.dlclose(unsafe.Pointer(handler.dl))
+}
+
func (handlers *Handlers) makeHandler(pairObj pair) (handlerObj *Handler) {
handlerObj = new(Handler)
handlerObj.handlerName = 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
return
}
-func (handlers *Handlers) runScoring(handlerObj *Handler) {
- go handlers.IloadScoringLibrary(handlerObj.libPath, handlerObj.intervalMs)
+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() {
+ handler.parents.IRunningScore(handler.symbol)
}
\ No newline at end of file