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 a way to stop a running script? #1356

Closed
ipapp opened this Issue Sep 17, 2016 · 7 comments

Comments

3 participants
@ipapp
Copy link

ipapp commented Sep 17, 2016

In our embedded home automation product we use a Lua based application framework. Now we are considering using JavaScript instead. We did some tests with Duktape, which is architecturally quite similar to Lua.
As the apps running on our platform may come from 3rd parties, we need to make sure that the scripts will no go wild and consume 100% of CPU, forever.
We solved that by making the apps callback based, i.e. the surrounding framework is calling Lua callbacks as a reaction to events. If the callback execution takes longer than allowed, the framework will force stop the script execution.
Is there a similar feature in JerryScript?
Thanks,
Istvan.

@zherczeg

This comment has been minimized.

Copy link
Contributor

zherczeg commented Sep 18, 2016

Not yet. But adding a time limit check to the main interpreter loop should be easy. It would throw an error, and if the time limit function is consistent (e.g. every time after the time out returns true), it could throw a series of errors until we go back to the first level. Perhaps a counter could also be added that the timeout is not checked for every executed instruction. Do you wish to do it?

@akosthekiss

This comment has been minimized.

Copy link
Contributor

akosthekiss commented Sep 18, 2016

How does the Lua engine solve the issue? Does it have a time limit for a script execution? Or are you running a timer asynchronously and kill the Lua job/task if it runs out of time? (Note: the JerryScript engine has no built-in time concept. It does have date-time support for the Date JS builtin, but that's not necessarily precise and not necessarily there as it can be disabled at configuration time.)

@ipapp

This comment has been minimized.

Copy link
Author

ipapp commented Sep 20, 2016

We implemented it using the Lua error handling mechanism. In one native thread we started a timer and then started the script execution (i.e. we were calling a Lua function from native framework). The timer was cancelled after returning from script (Lua interpreter) to our native framework. If on time, everything is fine. But if the timer runs out, the timer function kicks in, and from native framework it call lua_error to raise an error within the interpreter. I guess the Lua interpreter check for that error flag now and then. This results the script execution to be finished with an error.

A precondition is to have a function like lua_error that is safe to be called asynchronously on a lua_state. A stop or break function might be more appropriate for it.

A good aspect of Lua's approach is that even the current Lua function in interrupted, the interpreter itself is still alive, therefore we could do some housekeeping (or letting other Lua scripts run).

Considering that JerryScript is targeting embedded platforms, my opinion is that you must provide some mechanism to build fail-safe products. On the other hand, it might be sufficient to add a basic support via stop or break functions, and let the the surrounding framework to do the heavy lifting (to deal with time, etc.).

@zherczeg

This comment has been minimized.

Copy link
Contributor

zherczeg commented Sep 20, 2016

I am not sure I fully understand it. JavaScript has a built-in error handling mechanism: you can "throw" errors. These errors can be captured by try-catch blocks. We have no "asynchronous" mechanism to access a state. However you can do the following in the interpreter main loop:

if (timeout())
{
   abort with error
}

This will be caught by a try-catch block, but if timeout() always returns true after the timeout is reached, there will be a chain reaction and each catch block raises another error. At the end the scripts terminates with the error.

An optimization could be adding a countdown register, and check timeout() if the countdown register is 0 to reduce the timeout checking overhead.

if (--countdown == 0)
{
  if (timeout())
  {
     abort with error
  }
  countdown = reset_number;
}

The timeout function could also be replaced by a global variable, which can be set by an asynchronous mechanism.

@ipapp

This comment has been minimized.

Copy link
Author

ipapp commented Sep 20, 2016

I am sure it can be done by altering the source code of the engine, although I was hoping for a way to do it properly at engine API level.
So to summarize: I would like to see a way to interrupt a running script via an API call, and still have the engine live.

@zherczeg

This comment has been minimized.

Copy link
Contributor

zherczeg commented Sep 22, 2016

Yes, I agree that the implementation should be available in API level. And we have two options for that: providing a callback or calling a terminator. Perhaps the latter is cleaner. Since we have to implement it, and it will be a compile time enabled feature, we need to modify the source code of the engine. Throwing errors is normal, so the engine will live.

@zherczeg

This comment has been minimized.

Copy link
Contributor

zherczeg commented Jan 31, 2017

Closing due to inactivity. Please reopen if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.