1
0
mirror of https://github.com/robertkrimen/otto synced 2025-10-26 20:28:49 +08:00

Add ability to interrupt the runtime

This fixes #12, #35
This commit is contained in:
Robert Krimen
2014-02-01 15:49:17 -08:00
parent 8cd34bce0a
commit 096cd7e450
3 changed files with 120 additions and 1 deletions

54
otto.go
View File

@@ -104,6 +104,55 @@ More information about RE2: https://code.google.com/p/re2/
JavaScript considers a vertical tab (\000B <VT>) to be part of the whitespace class (\s), while RE2 does not.
Halting Problem
If you want to stop long running executions (like third-party code), you can use the interrupt channel to do this:
package main
import (
"errors"
"fmt"
Otto "github.com/robertkrimen/otto"
"os"
Time "time"
)
var Halt = errors.New("Halt")
func main() {
runUnsafe(`var abc = [];`)
runUnsafe(`
while (true) {
// Loop forever
}`)
}
func runUnsafe(unsafe string) {
start := Time.Now()
defer func() {
duration := Time.Since(start)
if caught := recover(); caught != nil {
if caught == Halt {
fmt.Fprintf(os.Stderr, "Some code took to long! Stopping after: %v\n", duration)
return
}
panic(caught) // Something else happened, repanic!
}
fmt.Fprintf(os.Stderr, "Ran code successfully: %v\n", duration)
}()
otto := Otto.New()
otto.Interrupt = make(chan func())
go func() {
Time.Sleep(2 * Time.Second) // Stop after two seconds
otto.Interrupt <- func() {
panic(Halt)
}
}()
otto.Run(unsafe) // Here be dragons (risky code)
otto.Interrupt = nil
}
*/
package otto
@@ -115,7 +164,10 @@ import (
// Otto is the representation of the JavaScript runtime. Each instance of Otto has a self-contained namespace.
type Otto struct {
runtime *_runtime
// Interrupt is a channel for interrupting the runtime. You can use this to halt a long running execution, for example.
// See "Halting Problem" for more information.
Interrupt chan func()
runtime *_runtime
}
// New will allocate a new JavaScript runtime