Optimized jsenv wf handler

This commit is contained in:
Peter Grlica
2022-02-17 15:00:16 +01:00
parent 0faaba5f7c
commit 78237d3b5b
7 changed files with 49 additions and 39 deletions
+22 -6
View File
@@ -36,7 +36,6 @@ type (
hasScope bool
Scope interface{}
scopeAny interface{}
scopeString string
scopeStream io.Reader
hasSource bool
@@ -46,12 +45,13 @@ type (
jsenvExecuteResults struct {
ResultString string
ResultInt int64
ResultBool bool
ResultAny interface{}
}
)
func (a jsenvExecuteArgs) GetScope() (bool, interface{}, string, io.Reader) {
return a.hasScope, a.scopeAny, a.scopeString, a.scopeStream
func (a jsenvExecuteArgs) GetScope() (bool, interface{}, io.Reader) {
return a.hasScope, a.scopeAny, a.scopeStream
}
// Execute function Process arbitrary data in jsenv
@@ -72,7 +72,7 @@ func (h jsenvHandler) Execute() *atypes.Function {
Parameters: []*atypes.Param{
{
Name: "scope",
Types: []string{"Any", "String", "Reader"}, Required: true,
Types: []string{"Any", "Reader"}, Required: true,
},
{
Name: "source",
@@ -92,6 +92,11 @@ func (h jsenvHandler) Execute() *atypes.Function {
Types: []string{"Integer"},
},
{
Name: "resultBool",
Types: []string{"Boolean"},
},
{
Name: "resultAny",
Types: []string{"Any"},
@@ -116,8 +121,6 @@ func (h jsenvHandler) Execute() *atypes.Function {
switch aux.Type() {
case h.reg.Type("Any").Type():
args.scopeAny = aux.Get().(interface{})
case h.reg.Type("String").Type():
args.scopeString = aux.Get().(string)
case h.reg.Type("Reader").Type():
args.scopeStream = aux.Get().(io.Reader)
}
@@ -156,6 +159,19 @@ func (h jsenvHandler) Execute() *atypes.Function {
}
}
{
// converting results.ResultBool (bool) to Boolean
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Boolean").Cast(results.ResultBool); err != nil {
return
} else if err = expr.Assign(out, "resultBool", tval); err != nil {
return
}
}
{
// converting results.ResultAny (interface{}) to Any
var (
+17 -25
View File
@@ -10,7 +10,8 @@ import (
type (
jsenvHandler struct {
reg queueHandlerRegistry
reg jsenvHandlerRegistry
vm jsenv.Vm
}
)
@@ -19,10 +20,21 @@ func JsenvHandler(reg queueHandlerRegistry) *jsenvHandler {
reg: reg,
}
h.preloadVm()
h.register()
return h
}
func (h *jsenvHandler) preloadVm() {
// call jsenv, feed it function and expect a result
tr := jsenv.NewTransformer(jsenv.LoaderJS, jsenv.TargetNoop)
h.vm = jsenv.New(tr)
// register a request body reader
h.vm.Register("readRequestBody", ReadRequestBody)
}
func (h jsenvHandler) execute(ctx context.Context, args *jsenvExecuteArgs) (res *jsenvExecuteResults, err error) {
res = &jsenvExecuteResults{}
@@ -36,29 +48,14 @@ func (h jsenvHandler) execute(ctx context.Context, args *jsenvExecuteArgs) (res
return
}
var vv interface{}
switch a := args.Scope.(type) {
case *expr.KVV:
vv = a.Get()
case *expr.String:
vv = a.Get()
default:
vv = a
}
// call jsenv, feed it function and expect a result
tr := jsenv.NewTransformer(jsenv.LoaderJS, jsenv.TargetNoop)
vm := jsenv.New(tr)
fn, err := vm.RegisterFunction(args.Source)
fn, err := h.vm.RegisterFunction(args.Source)
if err != nil {
err = fmt.Errorf("could not register jsenv function: %s", err)
return
}
out, err := fn.Exec(vm.New(vv))
out, err := fn.Exec(h.vm.New(expr.UntypedValue(args.Scope)))
if err != nil {
err = fmt.Errorf("could not exec jsenv function: %s", err)
@@ -66,19 +63,14 @@ func (h jsenvHandler) execute(ctx context.Context, args *jsenvExecuteArgs) (res
}
switch vv := out.(type) {
// this one should go out once the ResultAny
// is mainly used
case uint64:
res.ResultInt = int64(vv)
case int64:
res.ResultInt = int64(vv)
// this one should go out once the ResultAny
// is mainly used
case string:
res.ResultString = string(vv)
case bool:
res.ResultBool = vv
default:
res.ResultAny = vv
}
+3 -2
View File
@@ -10,8 +10,7 @@ functions:
required: true
types:
- { wf: Any }
- { wf: String, suffix: String }
- { wf: Reader, suffix: Stream }
- { wf: Reader, suffix: Stream }
source:
required: true
types:
@@ -21,5 +20,7 @@ functions:
wf: String
resultInt:
wf: Integer
resultBool:
wf: Boolean
resultAny:
wf: Any
+2 -2
View File
@@ -7,12 +7,12 @@ import (
)
type (
fn struct {
Fn struct {
f goja.Callable
}
)
func (f fn) Exec(i ...goja.Value) (interface{}, error) {
func (f Fn) Exec(i ...goja.Value) (interface{}, error) {
ret, err := f.f(goja.Undefined(), i...)
if err != nil {
+2 -3
View File
@@ -45,8 +45,7 @@ func (ss Vm) Fetch(key string) goja.Value {
// RegisterFunction registers the function to the vm and returns the
// function that can be used in go
func (ss Vm) RegisterFunction(s string, wrapperFn ...func() string) (f *fn, err error) {
func (ss Vm) RegisterFunction(s string, wrapperFn ...func() string) (f *Fn, err error) {
if len(wrapperFn) > 0 {
for _, wfn := range wrapperFn {
s = fmt.Sprintf(wfn(), s)
@@ -78,7 +77,7 @@ func (ss Vm) RegisterFunction(s string, wrapperFn ...func() string) (f *fn, err
return
}
return &fn{
return &Fn{
f: fnn,
}, nil
}
+1 -1
View File
@@ -39,7 +39,7 @@ func Test_registerFunction(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
var (
f *fn
f *Fn
err error
req = require.New(t)
+2
View File
@@ -51,6 +51,7 @@ var (
testApp *app.CortezaApp
r chi.Router
// defStore store.Storer
eventBus = eventbus.New()
)
@@ -68,6 +69,7 @@ func InitTestApp() {
return err
}
// defStore = app.Store
eventbus.Set(eventBus)
return nil
})