-
-
Notifications
You must be signed in to change notification settings - Fork 221
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
promise: run callbacks on resolution #118
Conversation
@robfig
So I guess a call to Looking at the JavaScript Promise API, the current Go |
Thanks for the guidance. |
Referring to rusty_v8, I guess we would want to expose Explicit or Auto microtask execution on the Isolate too? |
This would support ES Modules, since v8's interface returns a promise if a module contains top-level await or imports.
Codecov Report
@@ Coverage Diff @@
## master #118 +/- ##
==========================================
+ Coverage 96.63% 96.80% +0.16%
==========================================
Files 12 12
Lines 416 438 +22
==========================================
+ Hits 402 424 +22
Misses 9 9
Partials 5 5
Continue to review full report at Codecov.
|
Well, it looks like the default microtasks policy is Auto, so I'm not sure why it doesn't "just work" Anyway, I added methods mirroring the C++ interface, and one call to process microtasks got all the tests passing. The only weirdness is that I have to add PerformMicrotasksCheckpoint to Context instead of Isolate because it requires the relevant context to register and deregister. I didn't see a way around that, but that didn't seem like such a big problem. |
As an aside, I have no idea why some functions are marked as extern and others are not in v8go.cc/h |
From the description "microtasks are invoked when the script call depth decrements to zero" I'd assume that nothing will happen if it is already at zero when registering a promise callback. So even
Since this behavior is probably non-obvious to v8go users, maybe add a note about the call to the comments of those methods?
Good question, as far as I know |
Makes sense, thanks. Added a note. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @robfig This is looking really good. Thank you.
If we can just address the panic
and increase the code coverage then this is all good to merge.
ptr = C.PromiseThen2(p.ptr, C.int(cbID1), C.int(cbID2)) | ||
|
||
default: | ||
panic("1 or 2 callbacks required") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would like to avoid panic
within this library and also just ignore Callbacks if the length in > 2. Can we just return p
and make it a noop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I think we really don't see eye to eye on this design question, since I feel adverse to this. IMO this goes against the typical design ethos & common practice.. that is, ignoring unexpected input and carrying on. But it's your library, and in this case the chance of mistakes by the caller seems low. Updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer not panic solution as this is a library to be used by other app. Good not to panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to panic, hence the code :)
I would refer you again to examples in the standard library:
https://pkg.go.dev/strings#Repeat
There are no fewer than 3 functions in the strings
package that are documented to panic when given an invalid input. It would be frustrating for callers if they had to handle an error return unnecessarily. It's ok for the standard library to panic but not for v8go
? The argument that panics are not allowed in public interfaces at all must not be telling the whole story.
Searching for more information on the topic, I agree with the point of view presented here by Axel:
https://groups.google.com/g/golang-nuts/c/5S324hgLdfI/m/XpWmVQGJCAAJ
Personally I've been using Go since 1.0 (... 10 years now?) and I've seen a lot of libraries. I do not believe the nil checks and error returns used in v8go are common practice at all. Can you point to popular packages that do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok; I think we are all in agreement now. Sorry for the back-and-forth @robfig can you revert your last commit? ie. place back the panic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, happy to do it. Updated.
Last note - a lot of the errors returned in v8go are as a result of nil checks. In the standard library, it doesn't even perform nil checks, relying on the code to panic on nil as a side effect.
For example, it looks to me like io.WriteString(w Writer, s string)
will panic if either of the arguments are nil.
https://golang.org/src/io/io.go?s=13817:13895#L307
I know there is a practice (which I've seen in Java in particular) to aggressively check arguments for nil on entry to every function. I haven't really seen that done in Go, and I can't say that I've missed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it seem the conclusion is: panic is OK when arguments to the API are invalid, but for results of running JavaScript, there will still be err
returned? So if JavaScript code throws a top-level exception, there will still be err
and not panic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, that seems like the right approach; JS exceptions would still return error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. So will you then change the API now? Like template.Set
currently returns err
. It seems it should not anymore and just panic?
Hey @robfig are you able to address the test coverage? |
Added a test case |
This would support ES Modules, since v8's interface returns a promise
when running a module to handle top-level await and imports.
The test does not currently pass:
--- FAIL: TestPromiseRejected (0.01s)
promise_test.go:81: expected Then to be called immediately on already-resolved promise, but was not