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

Added js module: new JavaScript API supporting V8 #91

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

snej
Copy link
Contributor

@snej snej commented Jun 13, 2023

Part of couchbase/sync_gateway#5980 -- I just moved the js module here, and the v8go package dependency.

Copy link
Contributor

@torcolvin torcolvin left a comment

Choose a reason for hiding this comment

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

A bunch of pedantic nitpicks, but shouldn't

js_map_fn.go, js_runner.go, js_server.go

be obsolete with this commit + corresponding SG commit?

"fmt"
"strconv"

"github.com/pkg/errors"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"github.com/pkg/errors"
"errors"

Now that these are present in go 1.20

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/otto_vm.go Outdated
return nil, fmt.Errorf("the js.VM has been closed")
}
if vm.curRunner != nil {
panic("illegal access to v8VM: already has a v8Runner")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
panic("illegal access to v8VM: already has a v8Runner")
panic("illegal access to ottoVM: already has a ottoRunner")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/otto_vm.go Outdated
panic("illegal access to v8VM: already has a v8Runner")
}
if !vm.services.hasService(service) {
return nil, fmt.Errorf("unknown js.Service instance passed to VM")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, fmt.Errorf("unknown js.Service instance passed to VM")
return nil, fmt.Errorf("unknown js.Service instance passed to VM %v", service)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/v8_runner.go Outdated
"strings"
"time"

"github.com/pkg/errors"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"github.com/pkg/errors"

Since this is included go 1.20 now

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/v8_runner.go Outdated
// Create a V8 Context and run the setup script in it:
ctx := v8.NewContext(vm.iso, template.Global())
if _, err := vm.setupScript.Run(ctx); err != nil {
return nil, errors.Wrap(err, "Unexpected error in JavaScript initialization code")
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need ctx.Close() here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup!

js/v8_utils.go Outdated
Comment on lines 118 to 120
// if httpErr, ok := err.(*base.HTTPError); ok {
// errStr = fmt.Sprintf("[%d] %s", httpErr.Status, httpErr.Message)
// } else {
Copy link
Contributor

Choose a reason for hiding this comment

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

delete this code? or keep it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

deleted.

js/v8_vm.go Outdated
"sync"
"time"

"github.com/pkg/errors"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"github.com/pkg/errors"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/v8_vm.go Outdated
func (vm *v8VM) getTemplate(service *Service) (V8Template, error) {
var tmpl V8Template
if !vm.services.hasService(service) {
return nil, fmt.Errorf("unknown js.Service instance passed to VM")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, fmt.Errorf("unknown js.Service instance passed to VM")
return nil, fmt.Errorf("unknown js.Service instance passed to VM %v", service)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

js/v8_vm.go Outdated
var err error
vm.setupScript, err = vm.iso.CompileUnboundScript(kSetupLoggingJS+kUnderscoreJS, "setupScript.js", v8.CompileOptions{})
if err != nil {
return nil, errors.Wrapf(err, "Couldn't compile setup script")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return nil, errors.Wrapf(err, "Couldn't compile setup script")
return nil, fmt.Errorf("Couldn't compile setup script: %w")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok


func TestPoolsConcurrently(t *testing.T) {
maxProcs := runtime.GOMAXPROCS(0)
log.Printf("FYI, GOMAXPROCS = %d", maxProcs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
log.Printf("FYI, GOMAXPROCS = %d", maxProcs)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok

Copy link
Contributor

@torcolvin torcolvin left a comment

Choose a reason for hiding this comment

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

The second set of changes I'd like to make are:

  1. is to make the code panic-less, even though usually this amounts to programmer error if there's a problem that would case a panic. The reason for this is that we could bring down a SG process with multiple databases, where only would fail in a single database, even if it doesn't start up, or fails to update sync function
  2. pass contexts into the functions where possible, since we are using them more and more for logging. Instead of using context.Background() replace with context.TODO(). Some of these contexts are inside the js code only, but some of these functions I think call back into sync gateway where the context logging could be helpful to us.

snej added 2 commits June 20, 2023 14:43
- VM and VMPool now have an associated Context, which must be given when
  creating one. (VMs created by VMPool inherit its Context.)
- VM and VMPool now have a Context() method.
- Runner.Context() now returns the VM's Context by default, but calling
  Runner.SetContext() overrides it until the Runner is returned.
- Removed Runner.ContextOrDefault(); use Context() instead.
- The `ctx` parameter to Service.Run() may be nil, in which case the default
  Context (the VM's) is used.
- Tests use a new testCtx() function that's similar to the one in SG.base.
  It creates a Context derived from context.TODO that cancels when the test
  exits.

Some renaming to avoid confusion:
- Renamed v8Runner.ctx to v8ctx.
- Renamed baseRunner.goContext to ctx.
- Renamed other variables of type *v8.Context to v8ctx.
@snej
Copy link
Contributor Author

snej commented Jun 21, 2023

I've implemented change 2, adding Contexts, in commit c770934. See the commit log for details.

The addlicense check is failing; it needs to be disabled for js/underscore-umd-min.js and js/underscore-umd.js .

- panics in illegal situations replaced by logError() and returning,
  with an error if possible.
- V8Runner.NewInt() and NewString() now return an error because the V8 call
  returns an error, although I believe it can only fail in the unlikely case
  that V8 runs out of memory.
@snej
Copy link
Contributor Author

snej commented Jun 21, 2023

Change 1 (no panics) now implemented in 5ee3866. This required a few change in sync_gateway, which I've also pushed.

* add v8 tests

* Ignore underscore files

* use quotes
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

Successfully merging this pull request may close these issues.

2 participants