mirror of
https://github.com/aceld/kis-flow.git
synced 2025-01-23 07:30:23 +08:00
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
package kis
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"runtime"
|
|
)
|
|
|
|
// FaaS Function as a Service
|
|
// type FaaS func(context.Context, *kisflow, ...interface{}) error
|
|
// 这是一个方法类型,会在注入时在方法内判断
|
|
type FaaS interface{}
|
|
|
|
type FaaSDesc struct {
|
|
FnName string
|
|
f interface{}
|
|
fName string
|
|
ArgsType []reflect.Type
|
|
ArgNum int
|
|
FuncType reflect.Type
|
|
FuncValue reflect.Value
|
|
FaasSerialize
|
|
}
|
|
|
|
var globalFaaSSerialize = &DefaultFaasSerialize{}
|
|
|
|
func NewFaaSDesc(fnName string, f FaaS) (*FaaSDesc, error) {
|
|
funcValue := reflect.ValueOf(f)
|
|
funcType := funcValue.Type()
|
|
|
|
if err := validateFuncType(funcType, funcValue); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
argsType := make([]reflect.Type, funcType.NumIn())
|
|
fullName := runtime.FuncForPC(funcValue.Pointer()).Name()
|
|
containsKisflowCtx := false
|
|
|
|
for i := 0; i < funcType.NumIn(); i++ {
|
|
paramType := funcType.In(i)
|
|
if isFlowType(paramType) {
|
|
containsKisflowCtx = true
|
|
}
|
|
argsType[i] = paramType
|
|
}
|
|
|
|
if !containsKisflowCtx {
|
|
return nil, errors.New("function parameters must have Kisflow context")
|
|
}
|
|
|
|
if funcType.NumOut() != 1 || funcType.Out(0) != reflect.TypeOf((*error)(nil)).Elem() {
|
|
return nil, errors.New("function must have exactly one return value of type error")
|
|
}
|
|
|
|
// Check if f implements FaasSerialize interface
|
|
var serializeImpl FaasSerialize
|
|
if ser, ok := f.(FaasSerialize); ok {
|
|
serializeImpl = ser
|
|
} else {
|
|
serializeImpl = globalFaaSSerialize // Use global default implementation
|
|
}
|
|
|
|
return &FaaSDesc{
|
|
FnName: fnName,
|
|
f: f,
|
|
fName: fullName,
|
|
ArgsType: argsType,
|
|
ArgNum: len(argsType),
|
|
FuncType: funcType,
|
|
FuncValue: funcValue,
|
|
FaasSerialize: serializeImpl,
|
|
}, nil
|
|
}
|
|
|
|
func validateFuncType(funcType reflect.Type, funcValue reflect.Value) error {
|
|
if funcType.Kind() != reflect.Func {
|
|
return fmt.Errorf("provided FaaS type is %s, not a function", funcType.Name())
|
|
}
|
|
return nil
|
|
}
|