-
-
Notifications
You must be signed in to change notification settings - Fork 145
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
RenderBody became blocking (it never returns) after PR #232 #247
Comments
Maybe, due to support for WASM. |
I understand it's likely related to WebAssembly, but it doesn't tell me if this was intentional or not. The user program can arrange for the If it's meant to be intentional, I believe it should be documented. The user shouldn't have to look into the source code to know a function will never return. Further, how is a vecty app that needs to re-render the main body after the initial render expected to do so? I looked at the examples and the most informative one seems to be It sets up some listeners in advance of calling /cc @slimsag |
Apologies for the delayed response here! Yes, this change was intentional -- but I clearly should've thought out the consequences more than I did. Why did we change anything?When investigating WebAssembly support, it became clear we needed to do something here because of the fact that WebAssembly and GopherJS differ in how they handle goroutines that are executing after the In GopherJS, background goroutines (such as ones that would run on a click event, for example) continue execution even after By contrast, in WebAssembly with the Go compiler, once
...
func main() {
vecty.SetTitle("Hello Vecty!")
vecty.RenderBody(&PageView{})
select{} // keep Go alive (you can just ignore this for now, but it is needed)
}
...
Forethought / decision makingThe main reason for going with #2 above instead of #1 was that #1 introduces an additional complexity that beginners would need to understand and reason about. In my experience, when learning something, seeing somewhat magical lines of code that are dire to an application working is not super friendly. Initially, I had just planned to use This is, clearly, when I dropped the ball a bit. Thinking of existing Vecty applications, I couldn't think of any case where someone would not be calling I also incorrectly thought that this part of the description would communicate no guarantee about how quickly rendering occurs:
Should async usages be supported?
This is a good, but also difficult, question. One possibility I had considered was that if there was a compelling reason to keep this functionality (users owning the 'main loop'), we could retain it via a new method like The main reason I thought of when thinking about why we would support this was to allow for Go WebAssembly applications which already do some work on their own and own a main goroutine (e.g. a WebGL video game written in Go) to make use of Vecty. I remain convinced this is a compelling reason to add this. What I hadn't considered was that this could also be useful in applications such as yours where there is an existing scheduler and Vecty is being integrated more ad-hoc. In other words, I don't think of this as the canonical / most correct way to write a Vecty app but at the same time I don't have enough knowledge of the G-P-S codebase in order to say for certain which changes I would make. I'll try to find some time to investigate from this angle. Next steps
I'll do my best to land both of the above this weekend Apologies for the trouble this caused and for my not considering this case! I want Vecty to be the go-to web frontend for Go, and clearly need to do better here in order to get there! I consider G-P-S to be a shining star of sorts as far as Vecty real-world use cases go, so I also want to support you better there :) |
Thank you very much for such a thoughtful and detailed answer @slimsag! I don't mind making changes in my codebase to update to a new/different API, but I couldn't do that without first understanding whether this was an intentional change or not. Your reply has helped clarify that. I want to confirm my understanding of another question. I was considering using the current API like this: go func() {
for {
// sleep or wait for event ...
vecty.Rerender(body)
}
}()
vecty.RenderBody(body) But my current understanding is that it's not safe to do that, because there's a race condition. If the event arrives too quickly, |
I'm not near a computer at the moment, so I cant reply in full, but thats
correct and Rerender would panic in particular because we cannot rerender
components that haven't been rendered once before
…On Fri, Aug 16, 2019, 6:59 PM Dmitri Shuralyov ***@***.***> wrote:
Thank you very much for such a thoughtful and detailed answer @slimsag
<https://github.com/slimsag>!
I don't mind making changes in my codebase to update to a new/different
API, but I couldn't do that without first understanding whether this was an
intentional change or not. Your reply has helped clarify that.
I want to confirm my understanding of another question. If I were to
consider using the current API like this:
go func() {
for {
// sleep or wait for event ...
vecty.Rerender(body)
}
}()
vecty.RenderBody(body)
But my current understanding is that it's not safe to do that, because
there's a race condition. If the event arrives too quickly,
vecty.Rerender(body) can be called before vecty.RenderBody(body) has
completed running. Is that right?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#247>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAYGWOHTQ6KP2UIVJ2OE5ITQE5LRXANCNFSM4IKYQ3LA>
.
|
Friendly ping on this issue to indicate I'm still interested in this (with full understanding this is open source, so there are no expectations of work). This is blocking me from making updates to Go Package Store, so I may end up making a temporary fork to work around this. (It's not a problem if I have to do that; thanks for all your work so far that I could benefit from.) |
This PR adds support for rendering into arbitrary DOM nodes in the same way that rendering into the `body` worked previously, with one exception: blocking. `RenderBody` remains blocking, since it effectively becomes a helper that 90% of Vecty applications will rely on, whereas `RenderInto` and `RenderIntoNode` which are introduced in this PR do not block. This is because: a. Anyone rendering Vecty into arbitrary DOM nodes will likely want to do it more than once, so making the API of these functions non-blocking makes sense. b. Anyone using these functions will be a more advanced user and understand when blocking is / is not needed. In order to land this PR earlier for users who need this functionality, tests will not be added. They will be added in a follow-up as part of #168. Fixes #81 Fixes #247
This PR adds support for rendering into arbitrary DOM nodes in the same way that rendering into the `body` worked previously, with one exception: blocking. `RenderBody` remains blocking, since it effectively becomes a helper that 90% of Vecty applications will rely on, whereas `RenderInto` and `RenderIntoNode` which are introduced in this PR do not block. This is because: a. Anyone rendering Vecty into arbitrary DOM nodes will likely want to do it more than once, so making the API of these functions non-blocking makes sense. b. Anyone using these functions will be a more advanced user and understand when blocking is / is not needed. In order to land this PR earlier for users who need this functionality, tests will not be added. They will be added in a follow-up as part of #168. Fixes #81 Fixes #247
* Add support for rendering into non-body DOM nodes This PR adds support for rendering into arbitrary DOM nodes in the same way that rendering into the `body` worked previously, with one exception: blocking. `RenderBody` remains blocking, since it effectively becomes a helper that 90% of Vecty applications will rely on, whereas `RenderInto` and `RenderIntoNode` which are introduced in this PR do not block. This is because: a. Anyone rendering Vecty into arbitrary DOM nodes will likely want to do it more than once, so making the API of these functions non-blocking makes sense. b. Anyone using these functions will be a more advanced user and understand when blocking is / is not needed. In order to land this PR earlier for users who need this functionality, tests will not be added. They will be added in a follow-up as part of #168. Fixes #81 Fixes #247
Thanks for the ping and apologies for the massive delay! I've just merged the fix now: #249 To fix G-P-S, you can simply replace all current blocking calls of if err := vecty.RenderInto("body", comp); err != nil {
panic(err)
} Documentation is of course available on godoc:
If this works, or doesn't and gives you trouble, please let me know! :) |
Thank you very much Stephen! |
Update Go Package Store to be compatible with Vecty API after vecty.RenderBody became blocking as part of hexops/vecty#232. Use the new non-blocking vecty.RenderInto instead, which was created as part of the solution described in hexops/vecty#247. Updates hexops/vecty#232. Updates hexops/vecty#247.
In one of my applications, I've been using vecty's API roughly as follows:
It's possible I'm not using vecty API correctly, but that's what I came up with based on reading the documentation and experimenting (a while ago). It worked without noticeable issues until PR #232.
According to https://github.com/gopherjs/vecty/blob/master/doc/CHANGELOG.md#june-30-2019-pr-232-major-breaking-change, there have not been changes to
vecty.RenderBody
behavior.The documentation of
vecty.RenderBody
says:I don't see anything that suggests that
vecty.RenderBody
would block execution and never return.However, as of PR #232, that's what it does:
https://github.com/gopherjs/vecty/blob/2b6fc20f8913c7dadc6a67786be15c8c92bbd16a/dom.go#L1194-L1195
Which means my application never proceeds past the
vecty.RenderBody(body)
call.Am I doing something wrong, or is this a bug/regression?
The text was updated successfully, but these errors were encountered: