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

Virtual endpoint timeout #1490

Merged
merged 5 commits into from
Feb 21, 2018
Merged
Show file tree
Hide file tree
Changes from 4 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: 6 additions & 0 deletions mw_js_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,14 @@ func (j *JSVM) Init(spec *APISpec) {

if config.Global.JSVMTimeout <= 0 {
j.Timeout = time.Duration(defaultJSVMTimeout) * time.Second
log.WithFields(logrus.Fields{
"prefix": "jsvm",
}).Debugf("Default JSVM timeout used: %v", j.Timeout)
} else {
j.Timeout = time.Duration(config.Global.JSVMTimeout) * time.Second
log.WithFields(logrus.Fields{
"prefix": "jsvm",
}).Debugf("Custom JSVM timeout: %v", j.Timeout)
}

j.Log = log // use the global logger by default
Expand Down
57 changes: 54 additions & 3 deletions mw_virtual_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@ import (
"strconv"
"time"

"github.com/robertkrimen/otto"
_ "github.com/robertkrimen/otto/underscore"

"github.com/TykTechnologies/tyk/apidef"
"github.com/TykTechnologies/tyk/config"
"github.com/TykTechnologies/tyk/user"

"github.com/Sirupsen/logrus"
)

// RequestObject is marshalled to JSON string and passed into JSON middleware
Expand Down Expand Up @@ -153,11 +158,57 @@ func (d *VirtualEndpoint) ServeHTTPForCache(w http.ResponseWriter, r *http.Reque
return nil
}

// Run the middleware
// vm := d.Spec.JSVM.VM.Copy()
Copy link
Member

Choose a reason for hiding this comment

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

Pls remove this debugging

Copy link
Author

Choose a reason for hiding this comment

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

Yup! Forgot to add to commit

// returnRaw, err := vm.Run(vmeta.ResponseFunctionName + `(` + string(requestAsJson) + `, ` + string(sessionAsJson) + `, ` + specAsJson + `);`)
// if err != nil {
// log.Error("Failed to run virtual endpoint JS code:", err)
// return nil
// }
// returnDataStr, _ := returnRaw.ToString()

// Run the middleware
vm := d.Spec.JSVM.VM.Copy()
returnRaw, err := vm.Run(vmeta.ResponseFunctionName + `(` + string(requestAsJson) + `, ` + string(sessionAsJson) + `, ` + specAsJson + `);`)
if err != nil {
log.Error("Failed to run virtual endpoint JS code:", err)
vm.Interrupt = make(chan func(), 1)
log.WithFields(logrus.Fields{
"prefix": "jsvm",
}).Debug("Running: ", vmeta.ResponseFunctionName)
// buffered, leaving no chance of a goroutine leak since the
// spawned goroutine will send 0 or 1 values.
ret := make(chan otto.Value, 1)
errRet := make(chan error, 1)
go func() {
defer func() {
// the VM executes the panic func that gets it
// to stop, so we must recover here to not crash
// the whole Go program.
recover()
}()
returnRaw, err := vm.Run(vmeta.ResponseFunctionName + `(` + string(requestAsJson) + `, ` + string(sessionAsJson) + `, ` + specAsJson + `);`)
ret <- returnRaw
errRet <- err
}()
var returnRaw otto.Value
t := time.NewTimer(d.Spec.JSVM.Timeout)
select {
case returnRaw = <-ret:
if err := <-errRet; err != nil {
log.WithFields(logrus.Fields{
"prefix": "jsvm",
}).Error("Failed to run JS middleware: ", err)
return nil
}
t.Stop()
case <-t.C:
t.Stop()
log.WithFields(logrus.Fields{
"prefix": "jsvm",
}).Error("JS middleware timed out after ", d.Spec.JSVM.Timeout)
vm.Interrupt <- func() {
// only way to stop the VM is to send it a func
// that panics.
panic("stop")
}
return nil
}
returnDataStr, _ := returnRaw.ToString()
Expand Down