zotonic icon indicating copy to clipboard operation
zotonic copied to clipboard

pub/sub

Open heiheshang opened this issue 4 years ago • 29 comments

I see that webworker is sending an event on authorization model/ui/render-template/signup_logon_box How can I subscribe to this event on a page or in an erlang module?

heiheshang avatar Mar 18 '20 09:03 heiheshang

What would you like to do?

This is a post to the UI model on the page, it requests to render a template in the HTML element with the id signup_logon_box. The template is rendered on the server, using m_template

mworrell avatar Mar 18 '20 09:03 mworrell

I need to run javascript after loading the template, I want to get the template loading event. I wanted to connect vuejs on the page, but it turned out to be difficult, after loading the template, I need to call the template rendering

heiheshang avatar Mar 18 '20 12:03 heiheshang

So after there was an update of the UI, because the UI model loaded a template, you want to be notified that we updated with the id of the element that was updated?

@mmzeeman what do you think of this use case?

mworrell avatar Mar 18 '20 13:03 mworrell

I need to mean that the template has loaded in order to invoke client side javascript

heiheshang avatar Mar 18 '20 13:03 heiheshang

I had a similar use-case in the cotonic chat example.

Ideally I would also like to trigger a javascript after something was added. Currently I cheat: https://github.com/cotonic/cotonic/blob/master/examples/chat/index.html#L118

So I guess this is a more general thing.

mmzeeman avatar Mar 18 '20 13:03 mmzeeman

I think it would be nice to get a list of workers and get the onmessage function, the problem is that cotonic does not show the workers that it creates

heiheshang avatar Mar 18 '20 14:03 heiheshang

What do you suggest? Adding some introspection functions? How would that solve your problem?

I thought you needed a callback/sub which is triggered when the dom is updated in some place?

mmzeeman avatar Mar 18 '20 14:03 mmzeeman

Maybe the ui manager publishes every element id on a topic after that element is patched?

mworrell avatar Mar 18 '20 14:03 mworrell

yes, I need it, but the DOM is not available in the worker itself, look at the zotonic.auth-ui.worker.js script, exchange is possible only through postmessage between the page and the worker

heiheshang avatar Mar 18 '20 14:03 heiheshang

Something like model/ui/event/dom-update/:id ?

Then you could hook into that event whenever an element you are interested in is updated in the DOM by the ui manager.

mworrell avatar Mar 18 '20 14:03 mworrell

Why can’t you give access to the created workers? Why can't I assign an onmessage function?

heiheshang avatar Mar 18 '20 14:03 heiheshang

Something like model/ui/event/dom-update/:id ?

Then you could hook into that event whenever an element you are interested in is updated in the DOM by the ui manager.

it would be nice to subscribe to the event

heiheshang avatar Mar 18 '20 14:03 heiheshang

Ok, I think we can add that to the Cotonic UI manager - @mmzeeman are you ok with that?

mworrell avatar Mar 18 '20 14:03 mworrell

I think so too. I have to look through the hooks that incremental dom provides.

Why can’t you give access to the created workers? Why can't I assign an onmessage function?

Maybe for safety? It could be that this is a little bit short sighted of me.

mmzeeman avatar Mar 18 '20 14:03 mmzeeman

I don't think we need an incremental DOM hook, the UI manager know when it called the incremental DOM to update a certain element, so it could publish to the topic after all updates are done.

Regarding the onmessage, I think it is good to have the workers use the MQTT topics, in that way we can always move them to other places (ui thread, serviceWorker, server, ...).

mworrell avatar Mar 18 '20 14:03 mworrell

Ideally I would also be able to spawn workers by using mqtt topics. It should also be used to report crashes and errors.

mmzeeman avatar Mar 18 '20 15:03 mmzeeman

We could add a "worker supervisor" and have its API made accessible by standard model topics. But that is something for Cotonic.

mworrell avatar Mar 18 '20 15:03 mworrell

I think so too. I have to look through the hooks that incremental dom provides.

Why can’t you give access to the created workers? Why can't I assign an onmessage function?

Maybe for safety? It could be that this is a little bit short sighted of me.

what are the problems? this is the easiest way to exchange messages with the page

heiheshang avatar Mar 18 '20 15:03 heiheshang

See https://github.com/cotonic/cotonic/pull/32 for the DOM update event.

mworrell avatar Mar 18 '20 15:03 mworrell

@heiheshang the onmessage is indeed the easiest way to exchange, but we want to stay flexible where a handler is running. This decoupling of locality is possible by using the MQTT topics, it also enables introspection into the communication.

Only if there are huge efficiency problems I would not encourage to directly use the onmessage routines.

Having said that it would be possible to add a hook into the onmessage routines to be called when unknown messages are received that could not be handled by the normal worker routines.

I am not sure how that should be done at the end to the UI thread though.

If such a feature is needed shall we then continue this discussion in the cotonic issues?

mworrell avatar Mar 18 '20 15:03 mworrell

I have no need to use onmessage, I just need to get the event, any way will be good

heiheshang avatar Mar 18 '20 23:03 heiheshang

Cotonic now publishes to the topic model/ui/event/dom-updated/+id where id is the element id of the HTML node that was updated.

You can update Cotonic with git pull in apps/zotonic_mod_base/priv/lib-src/cotonic/

mworrell avatar Mar 19 '20 08:03 mworrell

Does this solve the problem you described?

mworrell avatar Mar 19 '20 08:03 mworrell

there is a problem, events come before the element is inserted into dom

heiheshang avatar Mar 19 '20 09:03 heiheshang

Interesting, as we do wait with a 0 timeout after the html is patched, so that the DOM should be stable after the patching.

In my testing I did see 4 updates to the element, probably all the moments some state changes.

@mmzeeman can you confirm the DOM is updated after the publish?

mworrell avatar Mar 19 '20 10:03 mworrell

I’m afk right now. Maybe because it is fired inside an animation frame?

Sent from my iPhone

On 19 Mar 2020, at 11:46, Marc Worrell [email protected] wrote:

 Interesting, as we do wait with a 0 timeout after the html is patched, so that the DOM should be stable after the patching.

In my testing I did see 4 updates to the element, probably all the moments some state changes.

@mmzeeman can you confirm the DOM is updated after the publish?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

mmzeeman avatar Mar 19 '20 13:03 mmzeeman

I see that events come to every inserted tag in my element. I am now checking the number of children because I know the number of elements var logon = document.getElementById("signup_logon_box"); if (logon != null & logon.childElementCount == 3) {

heiheshang avatar Mar 19 '20 13:03 heiheshang

It is fired for every ui update. I double checked the ui composer code.

The events are really only fired after an update. There is no async code in the dom manipulation code, and the event is really fired after the whole update is done.

Could you be a little bit more specific?

mmzeeman avatar Mar 20 '20 10:03 mmzeeman

Unchecked runtime.lastError: The message port closed before a response was received. I get this error all the time

heiheshang avatar Mar 24 '20 01:03 heiheshang