kis-flow/kis/pool.go

245 lines
6.5 KiB
Go
Raw Normal View History

2024-01-04 16:36:36 +08:00
package kis
import (
"context"
"errors"
"fmt"
2024-03-19 19:16:03 +08:00
"reflect"
2024-01-04 16:36:36 +08:00
"sync"
2024-04-16 14:58:00 +08:00
"github.com/aceld/kis-flow/common"
"github.com/aceld/kis-flow/log"
2024-01-04 16:36:36 +08:00
)
var _poolOnce sync.Once
2024-04-15 17:50:02 +08:00
// KisPool manages all Function and Flow configurations
type KisPool struct {
fnRouter funcRouter // All Function management routes
fnLock sync.RWMutex // fnRouter lock
2024-01-04 16:36:36 +08:00
2024-04-15 17:50:02 +08:00
flowRouter flowRouter // All flow objects
flowLock sync.RWMutex // flowRouter lock
2024-01-09 17:30:58 +08:00
2024-04-15 17:50:02 +08:00
cInitRouter connInitRouter // All Connector initialization routes
ciLock sync.RWMutex // cInitRouter lock
2024-01-09 17:30:58 +08:00
2024-04-15 17:50:02 +08:00
cTree connTree // All Connector management routes
cLock sync.RWMutex // cTree lock
2024-01-04 16:36:36 +08:00
}
2024-04-15 17:50:02 +08:00
// Singleton
var _pool *KisPool
2024-01-04 16:36:36 +08:00
2024-04-15 17:50:02 +08:00
// Pool Singleton constructor
func Pool() *KisPool {
2024-01-04 16:36:36 +08:00
_poolOnce.Do(func() {
2024-04-15 17:50:02 +08:00
// Create KisPool object
_pool = &KisPool{}
2024-01-04 16:36:36 +08:00
2024-04-15 17:50:02 +08:00
// Initialize fnRouter
2024-01-04 16:36:36 +08:00
_pool.fnRouter = make(funcRouter)
2024-04-15 17:50:02 +08:00
// Initialize flowRouter
2024-01-04 16:36:36 +08:00
_pool.flowRouter = make(flowRouter)
2024-01-09 17:30:58 +08:00
2024-04-15 17:50:02 +08:00
// Initialize connTree
2024-01-09 17:30:58 +08:00
_pool.cTree = make(connTree)
_pool.cInitRouter = make(connInitRouter)
2024-01-04 16:36:36 +08:00
})
return _pool
}
2024-04-15 17:50:02 +08:00
func (pool *KisPool) AddFlow(name string, flow Flow) {
pool.flowLock.Lock() // Write lock
2024-01-04 16:36:36 +08:00
defer pool.flowLock.Unlock()
if _, ok := pool.flowRouter[name]; !ok {
pool.flowRouter[name] = flow
} else {
errString := fmt.Sprintf("Pool AddFlow Repeat FlowName=%s\n", name)
panic(errString)
}
2024-04-15 11:17:47 +08:00
log.Logger().InfoF("Add FlowRouter FlowName=%s", name)
2024-01-04 16:36:36 +08:00
}
2024-04-15 17:50:02 +08:00
func (pool *KisPool) GetFlow(name string) Flow {
pool.flowLock.RLock() // Read lock
2024-01-04 16:36:36 +08:00
defer pool.flowLock.RUnlock()
if flow, ok := pool.flowRouter[name]; ok {
return flow
} else {
return nil
}
}
2024-04-15 17:50:02 +08:00
// FaaS registers Function computation business logic, indexed and registered by Function Name
func (pool *KisPool) FaaS(fnName string, f FaaS) {
2024-03-19 19:16:03 +08:00
2024-04-15 17:50:02 +08:00
// When registering the FaaS computation logic callback, create a FaaSDesc description object
2024-03-19 19:16:03 +08:00
faaSDesc, err := NewFaaSDesc(fnName, f)
if err != nil {
panic(err)
}
2024-04-15 17:50:02 +08:00
pool.fnLock.Lock() // Write lock
2024-01-04 16:36:36 +08:00
defer pool.fnLock.Unlock()
if _, ok := pool.fnRouter[fnName]; !ok {
2024-04-15 17:50:02 +08:00
// Register the FaaSDesc description object to fnRouter
2024-03-19 19:16:03 +08:00
pool.fnRouter[fnName] = faaSDesc
2024-01-04 16:36:36 +08:00
} else {
errString := fmt.Sprintf("KisPoll FaaS Repeat FuncName=%s", fnName)
panic(errString)
}
2024-04-15 11:17:47 +08:00
log.Logger().InfoF("Add KisPool FuncName=%s", fnName)
2024-01-04 16:36:36 +08:00
}
2024-04-15 17:50:02 +08:00
// CallFunction schedules Function
func (pool *KisPool) CallFunction(ctx context.Context, fnName string, flow Flow) error {
pool.fnLock.RLock() // Read lock
defer pool.fnLock.RUnlock()
2024-03-19 19:16:03 +08:00
if funcDesc, ok := pool.fnRouter[fnName]; ok {
2024-04-15 17:50:02 +08:00
// Parameters list for the scheduled Function
2024-03-19 19:16:03 +08:00
params := make([]reflect.Value, 0, funcDesc.ArgNum)
for _, argType := range funcDesc.ArgsType {
2024-04-15 17:50:02 +08:00
// If it is a Flow type parameter, pass in the value of flow
2024-03-19 19:16:03 +08:00
if isFlowType(argType) {
params = append(params, reflect.ValueOf(flow))
continue
}
2024-04-15 17:50:02 +08:00
// If it is a Context type parameter, pass in the value of ctx
2024-03-19 19:16:03 +08:00
if isContextType(argType) {
params = append(params, reflect.ValueOf(ctx))
continue
}
2024-04-15 17:50:02 +08:00
// If it is a Slice type parameter, pass in the value of flow.Input()
if isSliceType(argType) {
2024-04-15 17:50:02 +08:00
// Deserialize the raw data in flow.Input() to data of type argType
value, err := funcDesc.Serialize.UnMarshal(flow.Input(), argType)
2024-03-19 19:16:03 +08:00
if err != nil {
2024-04-15 11:17:47 +08:00
log.Logger().ErrorFX(ctx, "funcDesc.Serialize.DecodeParam err=%v", err)
2024-03-20 11:50:08 +08:00
} else {
params = append(params, value)
continue
2024-03-19 19:16:03 +08:00
}
2024-03-19 19:16:03 +08:00
}
2024-04-15 17:50:02 +08:00
// If the passed parameter is neither a Flow type, nor a Context type, nor a Slice type, it defaults to zero value
2024-03-19 19:16:03 +08:00
params = append(params, reflect.Zero(argType))
}
2024-04-15 17:50:02 +08:00
// Call the computation logic of the current Function
2024-03-19 19:16:03 +08:00
retValues := funcDesc.FuncValue.Call(params)
2024-04-15 17:50:02 +08:00
// Extract the first return value, if it is nil, return nil
2024-03-19 19:16:03 +08:00
ret := retValues[0].Interface()
if ret == nil {
return nil
}
2024-04-15 17:50:02 +08:00
// If the return value is of type error, return error
2024-03-19 19:16:03 +08:00
return retValues[0].Interface().(error)
2024-01-04 16:36:36 +08:00
}
2024-04-15 11:17:47 +08:00
log.Logger().ErrorFX(ctx, "FuncName: %s Can not find in KisPool, Not Added.\n", fnName)
2024-01-04 16:36:36 +08:00
return errors.New("FuncName: " + fnName + " Can not find in NsPool, Not Added.")
}
2024-01-09 17:30:58 +08:00
2024-04-15 17:50:02 +08:00
// CaaSInit registers Connector initialization business
func (pool *KisPool) CaaSInit(cname string, c ConnInit) {
pool.ciLock.Lock() // Write lock
2024-01-09 17:30:58 +08:00
defer pool.ciLock.Unlock()
if _, ok := pool.cInitRouter[cname]; !ok {
pool.cInitRouter[cname] = c
} else {
errString := fmt.Sprintf("KisPool Reg CaaSInit Repeat CName=%s\n", cname)
panic(errString)
}
2024-04-15 11:17:47 +08:00
log.Logger().InfoF("Add KisPool CaaSInit CName=%s", cname)
2024-01-09 17:30:58 +08:00
}
2024-04-15 17:50:02 +08:00
// CallConnInit schedules ConnInit
func (pool *KisPool) CallConnInit(conn Connector) error {
pool.ciLock.RLock() // Read lock
2024-01-09 17:30:58 +08:00
defer pool.ciLock.RUnlock()
init, ok := pool.cInitRouter[conn.GetName()]
if !ok {
panic(errors.New(fmt.Sprintf("init connector cname = %s not reg..", conn.GetName())))
}
return init(conn)
}
2024-04-15 17:50:02 +08:00
// CaaS registers Connector Call business
func (pool *KisPool) CaaS(cname string, fname string, mode common.KisMode, c CaaS) {
pool.cLock.Lock() // Write lock
2024-01-09 17:30:58 +08:00
defer pool.cLock.Unlock()
if _, ok := pool.cTree[cname]; !ok {
2024-04-15 17:50:02 +08:00
//cid First registration, does not exist, create a second-level tree NsConnSL
2024-01-09 17:30:58 +08:00
pool.cTree[cname] = make(connSL)
2024-04-15 17:50:02 +08:00
// Initialize various FunctionMode
2024-01-09 17:30:58 +08:00
pool.cTree[cname][common.S] = make(connFuncRouter)
pool.cTree[cname][common.L] = make(connFuncRouter)
}
if _, ok := pool.cTree[cname][mode][fname]; !ok {
pool.cTree[cname][mode][fname] = c
} else {
errString := fmt.Sprintf("CaaS Repeat CName=%s, FName=%s, Mode =%s\n", cname, fname, mode)
panic(errString)
}
2024-04-15 11:17:47 +08:00
log.Logger().InfoF("Add KisPool CaaS CName=%s, FName=%s, Mode =%s", cname, fname, mode)
2024-01-09 17:30:58 +08:00
}
2024-04-15 17:50:02 +08:00
// CallConnector schedules Connector
func (pool *KisPool) CallConnector(ctx context.Context, flow Flow, conn Connector, args interface{}) (interface{}, error) {
pool.cLock.RLock() // Read lock
2024-04-01 13:51:17 +08:00
defer pool.cLock.RUnlock()
2024-01-09 17:30:58 +08:00
fn := flow.GetThisFunction()
fnConf := fn.GetConfig()
mode := common.KisMode(fnConf.FMode)
if callback, ok := pool.cTree[conn.GetName()][mode][fnConf.FName]; ok {
return callback(ctx, conn, fn, flow, args)
}
2024-04-15 11:17:47 +08:00
log.Logger().ErrorFX(ctx, "CName:%s FName:%s mode:%s Can not find in KisPool, Not Added.\n", conn.GetName(), fnConf.FName, mode)
2024-01-09 17:30:58 +08:00
return nil, errors.New(fmt.Sprintf("CName:%s FName:%s mode:%s Can not find in KisPool, Not Added.", conn.GetName(), fnConf.FName, mode))
2024-01-09 17:30:58 +08:00
}
2024-01-12 17:27:43 +08:00
2024-04-15 17:50:02 +08:00
// GetFlows retrieves all Flows
func (pool *KisPool) GetFlows() []Flow {
pool.flowLock.RLock() // Read lock
2024-01-12 17:27:43 +08:00
defer pool.flowLock.RUnlock()
var flows []Flow
for _, flow := range pool.flowRouter {
flows = append(flows, flow)
}
return flows
}