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

[fix] ignore cache for immediate script #52

Merged
merged 6 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 3 additions & 3 deletions exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (

// execStarlarkFile executes a Starlark file with the given filename and source, and returns the global environment and any error encountered.
// If the cache is enabled, it will try to load the compiled program from the cache first, and save the compiled program to the cache after compilation.
func (m *Machine) execStarlarkFile(filename string, src interface{}) (starlark.StringDict, error) {
func (m *Machine) execStarlarkFile(filename string, src interface{}, allowCache bool) (starlark.StringDict, error) {
// restore the arguments for starlark.ExecFileOptions
opts := m.getFileOptions()
thread := m.thread
predeclared := m.predeclared
hasCache := m.progCache != nil

// if cache is not enabled, just execute the original source
if !hasCache {
// if cache is not enabled or not allowed, just execute the original source
if !hasCache || !allowCache {
return starlark.ExecFileOptions(opts, thread, filename, src, predeclared)
}

Expand Down
6 changes: 6 additions & 0 deletions machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,13 @@ func (m *Machine) AddLazyloadModules(mods ModuleLoaderMap) {
m.lazyloadMods.Merge(mods)
}

var (
// NoopPrintFunc is a no-op print function for the Starlark runtime environment, it does nothing.
NoopPrintFunc PrintFunc = func(thread *starlark.Thread, msg string) {}
)

// SetPrintFunc sets the print function of the Starlark runtime environment.
// To disable printing, you can set it to NoopPrintFunc. Setting it to nil will invoke the default `fmt.Fprintln(os.Stderr, msg)` instead.
func (m *Machine) SetPrintFunc(printFunc PrintFunc) {
m.mu.Lock()
defer m.mu.Unlock()
Expand Down
64 changes: 64 additions & 0 deletions machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,39 @@ func TestMachine_SetScriptCache(t *testing.T) {
t.Errorf("expected same error, got different --- err1: %v, err2: %v, err3: %v", err1, err2, err3)
}
}

// ignore cache 1: run script will use default name "direct.star", disable cache to avoid conflict
{
m := starlet.NewDefault()
m.SetScriptCacheEnabled(true)
res, err := m.RunScript([]byte(script1), nil)
checkRes(501, err, res, 10)

res, err = m.RunScript([]byte(script2), nil)
checkRes(502, err, res, 20)

m.SetScriptCacheEnabled(false)
res, err = m.RunScript([]byte(script2), nil)
checkRes(503, err, res, 20)
}

// ignore cache 2: empty script name will set as "eval.star", disable cache to avoid conflict
{
m := starlet.NewDefault()
m.SetScriptCacheEnabled(true)
m.SetScript("", []byte(script1), nil)
res, err := m.Run()
checkRes(601, err, res, 10)

m.SetScript("", []byte(script2), nil)
res, err = m.Run()
checkRes(602, err, res, 20)

m.SetScriptCacheEnabled(false)
m.SetScript("", []byte(script2), nil)
res, err = m.Run()
checkRes(603, err, res, 20)
}
}

func TestMachine_GetStarlarkPredeclared(t *testing.T) {
Expand Down Expand Up @@ -623,3 +656,34 @@ func TestMachine_GetStarlarkThread(t *testing.T) {
t.Errorf("expected not nil, got nil")
}
}

func Test_SetPrintFunc(t *testing.T) {
m := starlet.NewDefault()
// set print function
printFunc, cmpFunc := getPrintCompareFunc(t)
m.SetPrintFunc(printFunc)
// set code
code := `print("Aloha, Honua!")`
m.SetScript("aloha.star", []byte(code), nil)
// run
_, err := m.Run()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// compare
cmpFunc("Aloha, Honua!\n")

// set print function to nil
m.SetPrintFunc(nil)
m.SetScript("aloha.star", []byte(`print("Aloha, Honua! Nil")`), nil)
if _, err = m.Run(); err != nil {
t.Errorf("unexpected error: %v", err)
}

// set print function to noop
m.SetPrintFunc(starlet.NoopPrintFunc)
m.SetScript("aloha.star", []byte(`print("Aloha, Honua! Noop")`), nil)
if _, err = m.Run(); err != nil {
t.Errorf("unexpected error: %v", err)
}
}
17 changes: 9 additions & 8 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (m *Machine) Run() (StringAnyMap, error) {
m.mu.Lock()
defer m.mu.Unlock()

return m.runInternal(context.Background(), nil)
return m.runInternal(context.Background(), nil, true)
}

// RunScript executes a script with additional variables, which take precedence over global variables and modules, returns the result.
Expand All @@ -70,7 +70,7 @@ func (m *Machine) RunScript(content []byte, extras StringAnyMap) (StringAnyMap,
m.scriptName = "direct.star"
m.scriptContent = content
m.scriptFS = nil
return m.runInternal(context.Background(), extras)
return m.runInternal(context.Background(), extras, false)
}

// RunFile executes a script from a file with additional variables, which take precedence over global variables and modules, returns the result.
Expand All @@ -81,7 +81,7 @@ func (m *Machine) RunFile(name string, fileSys fs.FS, extras StringAnyMap) (Stri
m.scriptName = name
m.scriptContent = nil
m.scriptFS = fileSys
return m.runInternal(context.Background(), extras)
return m.runInternal(context.Background(), extras, true)
}

// RunWithTimeout executes a preset script with a timeout and additional variables, which take precedence over global variables and modules, returns the result.
Expand All @@ -91,18 +91,18 @@ func (m *Machine) RunWithTimeout(timeout time.Duration, extras StringAnyMap) (St

ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
return m.runInternal(ctx, extras)
return m.runInternal(ctx, extras, true)
}

// RunWithContext executes a preset script within a specified context and additional variables, which take precedence over global variables and modules, returns the result.
func (m *Machine) RunWithContext(ctx context.Context, extras StringAnyMap) (StringAnyMap, error) {
m.mu.Lock()
defer m.mu.Unlock()

return m.runInternal(ctx, extras)
return m.runInternal(ctx, extras, true)
}

func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap) (out StringAnyMap, err error) {
func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap, allowCache bool) (out StringAnyMap, err error) {
defer func() {
if r := recover(); r != nil {
err = errorStarlarkPanic("exec", r)
Expand All @@ -116,8 +116,9 @@ func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap) (out Str
)
if m.scriptContent != nil {
if scriptName == "" {
// for default name
// for default name, and disable cache to avoid conflict
scriptName = "eval.star"
allowCache = false
}
source = m.scriptContent
} else if m.scriptFS != nil {
Expand Down Expand Up @@ -168,7 +169,7 @@ func (m *Machine) runInternal(ctx context.Context, extras StringAnyMap) (out Str

// run with everything prepared
m.runTimes++
res, err := m.execStarlarkFile(scriptName, source)
res, err := m.execStarlarkFile(scriptName, source, allowCache)
done <- struct{}{}

// merge result as predeclared for next run
Expand Down
Loading