Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : add script routing functionality #2669

Merged
merged 21 commits into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
package inputed Invoker, to make script operate url safly
Signed-off-by: YarBor <yarbor.ww@gmail.com>
  • Loading branch information
YarBor committed May 11, 2024
commit 0fcf2243e7039accdb3bea61508ddf9f20596b97
56 changes: 56 additions & 0 deletions cluster/router/script/instance/instances_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package instance

import (
"context"
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/protocol"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reformat

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the problem is, I ran go fmt and it doesn't work, looks the same.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the problem is, I ran go fmt and it doesn't work, looks the same.

Go fmt will not change the order of the import, it will only format locks and spaces. You can use goimports instead,https://pkg.go.dev/golang.org/x/tools/cmd/goimports
Generally speaking, the standard import format is:
import (
go standard packages (sorted alphabetically)
(space)
Three-party packages (sorted alphabetically)
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我们 dubbogo 有自己的 import format 工具 https://github.com/dubbogo/tools/tree/master/cmd/imports-formatter

编译出二进制,在项目根目录下执行一次,就可以 format 整个工程的 import 顺序。比你们找的这个工具高级多了。

用好前人积累的工具。

"errors"
"strings"
Expand Down Expand Up @@ -55,3 +57,57 @@ func init() {
factory = make(map[string]ScriptInstances)
setInstances(`javascript`, newJsInstances())
}

// scriptInvokerPack for security
// if script change input Invoker's url during Route() call ,
// it will influence call Route() next time ,
// there are no operation to recover .
type scriptInvokerPack interface {
protocol.Invoker
}

type scriptInvokerPackImpl struct {
copiedURL *common.URL
invoker protocol.Invoker
isRan bool
}

func (f *scriptInvokerPackImpl) GetURL() *common.URL {
return f.copiedURL
}

func (f *scriptInvokerPackImpl) IsAvailable() bool {
if !f.isRan {
return true
} else {
return f.invoker.IsAvailable()
}
}

func (f *scriptInvokerPackImpl) Destroy() {
if !f.isRan {
panic("Destroy should not be called")
} else {
f.invoker.Destroy()
}
}

func (f *scriptInvokerPackImpl) Invoke(ctx context.Context, inv protocol.Invocation) protocol.Result {
if !f.isRan {
panic("Invoke should not be called")
} else {
return f.invoker.Invoke(ctx, inv)
}
}

func (f *scriptInvokerPackImpl) setRanMode() {
f.isRan = true
}

func newScriptInvokerImpl(invoker protocol.Invoker) *scriptInvokerPackImpl {
return &scriptInvokerPackImpl{
copiedURL: invoker.GetURL().Clone(),
invoker: invoker,
isRan: false,
}
}
12 changes: 10 additions & 2 deletions cluster/router/script/instance/js_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,26 @@ type jsInstance struct {

func (i *jsInstances) RunScript(_ string, invokers []protocol.Invoker, invocation protocol.Invocation) ([]protocol.Invoker, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改成 Run

pg := i.program.Load()
if pg == nil {
if pg == nil || len(invokers) == 0 {
return invokers, nil
}
matcher := i.insPool.Get().(*jsInstance)
matcher.initCallArgs(invokers, invocation)

packInvokers := make([]protocol.Invoker, 0, len(invokers))
for _, invoker := range invokers {
packInvokers = append(packInvokers, newScriptInvokerImpl(invoker))
}

matcher.initCallArgs(packInvokers, invocation)
matcher.initReplyVar()
scriptRes, err := matcher.runScript(i.program.Load())
if err != nil {
return nil, err
}

result := make([]protocol.Invoker, 0, len(scriptRes.(*goja.Object).Export().([]interface{})))
for _, res := range scriptRes.(*goja.Object).Export().([]interface{}) {
res.(*scriptInvokerPackImpl).setRanMode()
result = append(result, res.(protocol.Invoker))
}
return result, nil
Expand Down
50 changes: 26 additions & 24 deletions cluster/router/script/instance/js_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@

rt_link_external_libraries(runtime)

err := runtime.Set("invokers", test_invokers)

Check failure on line 131 in cluster/router/script/instance/js_instance_test.go

View workflow job for this annotation

GitHub Actions / lint (1.20)

ineffectual assignment to err (ineffassign)
err = runtime.Set("invocation", test_invocation)

Check failure on line 132 in cluster/router/script/instance/js_instance_test.go

View workflow job for this annotation

GitHub Actions / lint (1.20)

ineffectual assignment to err (ineffassign)
err = runtime.Set("context", test_context)
if err != nil {
panic(err)
Expand Down Expand Up @@ -496,6 +496,7 @@
}
wg.Wait()
}

func TestFuncWithCompileAndRunRepeatedly(t *testing.T) {
pg, err := goja.Compile("routeJs", jsScriptPrefix+`(
function route(invokers,invocation,context) {
Expand Down Expand Up @@ -532,35 +533,36 @@
}
}

func TestScriptWhitBrackets(t *testing.T) {
script := `__go_program_result =

(function route(invokers,invocation,context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
if ("127.0.0.1" === invokers[i].GetURL().Ip) {
if (invokers[i].GetURL().Port !== "20000"){
invokers[i].GetURL().Ip = "` + localIp + `"
invokers[i].GetURL().Port = "20004"
result.push(invokers[i]);
}
}
}
return result;
}(invokers, invocation, context));`
pg, err := goja.Compile("routeJs", jsScriptPrefix+script, true)
func TestFuncArgsReadOnly(t *testing.T) {
script := `
Object.freeze(invokers);
Object.freeze(invocation);
Object.freeze(context);
__result =
(function test(invokers, invocation, context) {
return (function route(invokers, invocation, context) {
var result = [];
for (var i = 0; i < invokers.length; i++) {
if ("10.30.0.218" === invokers[i].GetURL().Ip) {
if (invokers[i].GetURL().Port === "20000") {
result.push(invokers[i]);
}
}
}
return result;
}(invokers, invocation, context));
}(invokers, invocation, context));
`
rt := goja.New()
rt_init_args(rt)
_ = rt.Set(`__result`, nil)
pg, err := goja.Compile("", script, true)
if err != nil {
panic(err)
}
rt := goja.New()
rt_link_external_libraries(rt)
rt_init_args(rt)
re_init_res_recv(rt)
res, err := rt.RunProgram(pg)
if err != nil {
panic(err)
}
assert.Equal(t, 2, len(res.Export().([]interface{})))
assert.Equal(t, localIp, (*(res.Export().([]interface{})[0]).(*protocol.BaseInvoker)).GetURL().Ip)
assert.Equal(t, "20004", (*(res.Export().([]interface{})[0]).(*protocol.BaseInvoker)).GetURL().Port)
println(res)
}
Loading