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

Enable async bind for Go #932

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

sheepsteak
Copy link

@sheepsteak sheepsteak commented Apr 22, 2023

At the moment it's not possible to do async work in the function passed to Bind in Go. I've attempted to change this to bring it more in line with how it works for C and C# in that the consumer has to call Return with a status and a result.

I'm not sure if changing the existing Bind and making a breaking change is the best way of doing this. Perhaps I should make this a new function called BindAsync or something? Anyway, let me know what you think and I can make any changes.

I've enabled the bind callback to return a chan. This keeps backward compatibility but allows the use of goroutines that can send a BindCallbackResult through it to signal they are finished.

I've updated the bind.go example with an example of using this as requested in #929 too.

webview.go Outdated
StatusSuccess = 0

// Binding call failed
StatusError = 1
Copy link
Author

Choose a reason for hiding this comment

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

-1 was used previously but other bindings seemed to be using 1 to state an error.

// f must be a function
// f must return either value and error or just error
// f must be a function that accepts an id string as the first argument, and
// then any other arguments that you want to pass from the JavaScript function.
Bind(name string, f interface{}) error
Copy link
Author

Choose a reason for hiding this comment

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

I really wanted to change this to something like f func(id string, params ...interface{}) but I'm not sure if that's any better to use.

webview.go Outdated
return errors.New("function may only return a value or a value+error")

if v.Type().NumIn() > 0 && v.Type().In(0).Kind() != reflect.String {
return errors.New("first argument must be a string for the request id")
Copy link
Author

Choose a reason for hiding this comment

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

At least this will give a warning about id string needing to be first argument.

@SteffenL
Copy link
Collaborator

SteffenL commented Apr 23, 2023

Thank you for this PR. I hope someone who is more familiar with Go can review this but I can comment on a few things.

The HTML/JS code in the example should be identical to the existing examples for other languages.

If possible we should avoid breaking compatibility with existing code. If adding a BindAsync function avoids that then that would be better than changing the existing Bind function.

Is there a standard naming convention for this kind of thing in Go or a best practice in this situation?

I wonder if there is a way to avoid breaking compatibility while allowing Bind to work with both synchronous and asynchronous bindings.

@sheepsteak
Copy link
Author

@SteffenL I did a bit more research and I've come up with something better I think. Backwards compatibility is now preserved and the consumer has the option to return a channel now. They can use the channel to send a BindCallbackResult in the future when any async work is finished. I believe this is a much more idiomatic way to handle this in Go.

The only other way I can think of doing it is by just having the bind callback run as a goroutine itself and then the consumer can just take as long as they need (perhaps by using a WaitGroup to block until ready). The fact it's all running in a goroutine then would prevent the main thread blocking.

It would be great to get someone else's opinion like you say.

I also fixed the example to be identical to the C/C++ one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants