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

Is there any way to stop a running script with a timeout? #252

Closed
Dreamacro opened this issue Nov 14, 2019 · 8 comments
Closed

Is there any way to stop a running script with a timeout? #252

Dreamacro opened this issue Nov 14, 2019 · 8 comments

Comments

@Dreamacro
Copy link

In my use case, I receive a function from the user. And I passthrough params and execute it. But I need a way to stop the function running with a timeout (e.g. 2000ms).

can starlark-go provide a function like CallContext?

thread := &starlark.Thread{
    Name:  "example",
}

globals, _ := starlark.ExecFile(thread, "test.star", f, nil)

mainFn := globals["main"]
dict := starlark.StringDict{
    "param": starlark.String("test"),
}

m := starlarkstruct.FromStringDict(starlarkstruct.Default, dict)
arg := starlark.Tuple{m}

ctx, cancel := context.WithTimeout(context.background(), time.Second)
defer cancel()
starlark.CallContext(ctx, thread, mainFn, arg, nil)
@alandonovan
Copy link
Contributor

Currently there is no way to stop a function in the middle of Starlark execution, though it is a feature that has been requested before and may be feasible to implement without a major performance penalty. Is the function you wish to interrupt executing a Starlark loop, or is it calling into a built-in function that takes a long time? If the latter, then you can easily make that built-in function honor the cancellation of a context carried within the thread. For example:

thread := &starlark.Thread{Name:  "example"}
ctx, cancel := context.WithTimeout(context.background(), time.Second)
defer cancel()
thread.SetLocal("context", ctx)
starlark.ExecFile(...)

...

func slowBuiltin(thread *Thread, fn *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
    if (thread.Local("context").(context.Context).Err() != nil) { ... give up ... }
    ...
}

@Dreamacro
Copy link
Author

My use cases are more like a lightweight FaaS. The user defines a function that I can't control and I call it many times. So when it runs too long, I need to stop/kill it. Is there any difficulty that doesn't implement yet?

@alandonovan
Copy link
Contributor

alandonovan commented Nov 14, 2019

Oh, if you can't trust the user's function then you definitely should not run it in the same address space as your code, as it can trivially consume all available memory and there's nothing we can hope to do about that.

Let the operating system help you. Fork and exec a subprocess in a cgroup or setrlimit container that bounds the memory, CPU, and running time.

@maxmcd
Copy link

maxmcd commented Jan 28, 2020

@alandonovan do you think it would be a large effort to implement rough cpu/memory metering and limits? I understand if this isn't the goal of the project and that it wouldn't have a home in this codebase, but is there something about the implementation that would make this difficult?

@alandonovan
Copy link
Contributor

Yes, I think it's essentially infeasible. An implementation in C++ could in principle impose limits on memory usage, but it would be a major usability challenge.

Like I said before, let the operating system help you. It has mechanisms to bound both CPU and memory usage of child process.

@maxmcd
Copy link

maxmcd commented Jan 29, 2020

Yep, I'm working on something that takes advantage of those mechanisms to limit memory and cpu use with webassembly: https://github.com/embly/embly

With starlark it seemed like it might be possible to get away with an implementation that safely runs user code in the same address space, maybe not measuring the exact amount of memory used, but at least imposing some soft limits base on what is being parsed and executed. Understood though, thanks for the response.

@tv42
Copy link

tv42 commented Jul 24, 2020

Can this be marked a duplicate of #160 ?

adonovan added a commit that referenced this issue Jul 24, 2020
This change adds two related features:
(1) asynchronous cancellation of Starlark threads (Thread.Cancel), and
(2) recording and limiting of the number of abstract computation steps.

Fixes issue #252
Fixes issue #160

Change-Id: Ia2e594d742363f18e650a04a0e3745678182f0e7
alandonovan pushed a commit that referenced this issue Aug 21, 2020
This change adds two related features:
(1) asynchronous cancellation of Starlark threads (Thread.Cancel), and
(2) recording and limiting of the number of abstract computation steps.

Fixes issue #252
Fixes issue #160

Change-Id: Ia2e594d742363f18e650a04a0e3745678182f0e7
alandonovan pushed a commit that referenced this issue Aug 21, 2020
This change adds two related features:
(1) asynchronous cancellation of Starlark threads (Thread.Cancel), and
(2) recording and limiting of the number of abstract computation steps.

Fixes issue #252
Fixes issue #160
@alandonovan
Copy link
Contributor

alandonovan commented Aug 21, 2020

Fixed. See Thread.SetMaxExecutionSteps and Thread.Cancel.

martyspiewak pushed a commit to martyspiewak/starlark-go that referenced this issue Apr 29, 2022
…le#298)

This change adds two related features:
(1) asynchronous cancellation of Starlark threads (Thread.Cancel), and
(2) recording and limiting of the number of abstract computation steps.

Fixes issue google#252
Fixes issue google#160
martyspiewak pushed a commit to martyspiewak/starlark-go that referenced this issue Apr 29, 2022
…le#298)

This change adds two related features:
(1) asynchronous cancellation of Starlark threads (Thread.Cancel), and
(2) recording and limiting of the number of abstract computation steps.

Fixes issue google#252
Fixes issue google#160
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants