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

Ports do not register immediate `send` #595

Closed
knewter opened this Issue May 11, 2016 · 18 comments

Comments

Projects
None yet
10 participants
@knewter

knewter commented May 11, 2016

I've produced an example here: https://github.com/knewter/counter

It's actually published here: http://knewter.github.io/counter/Counter.html

If you load the page, the counter will have value 0. The Counter.html file has the following code:

var app = Elm.Main.fullscreen();
app.ports.jsMsgs.send(1);
window.app = app;

I mention the last bit because you can open up the browser's console, issue app.ports.jsMsgs.send(1), and the counter will update. So the inbound port works, but it doesn't work immediately.

@knowthen

This comment has been minimized.

Show comment
Hide comment
@knowthen

knowthen May 11, 2016

I think this is the same bug as this one: https://github.com/elm-lang/core/issues/582

knowthen commented May 11, 2016

I think this is the same bug as this one: https://github.com/elm-lang/core/issues/582

@knewter

This comment has been minimized.

Show comment
Hide comment
@knewter

knewter May 11, 2016

it would appear to be the same bug. This is a simpler case that produces the error though. I didn't realize they were the same error before.

knewter commented May 11, 2016

it would appear to be the same bug. This is a simpler case that produces the error though. I didn't realize they were the same error before.

@roine

This comment has been minimized.

Show comment
Hide comment
@roine

roine May 12, 2016

As a workaround I'm using something like:

setTimeout(function(){ app.ports.jsMsgs.send(1); }, 0)

That's not pretty but it does the job.

roine commented May 12, 2016

As a workaround I'm using something like:

setTimeout(function(){ app.ports.jsMsgs.send(1); }, 0)

That's not pretty but it does the job.

@yoni-tock

This comment has been minimized.

Show comment
Hide comment
@yoni-tock

yoni-tock Jun 16, 2016

Contributor

Yep, just hit this in our production app :(. Thanks to @lukewestby for pointing us at this bug!

Contributor

yoni-tock commented Jun 16, 2016

Yep, just hit this in our production app :(. Thanks to @lukewestby for pointing us at this bug!

@vjousse

This comment has been minimized.

Show comment
Hide comment
@vjousse

vjousse Jun 17, 2016

Same here, pretty annoying when discovering elm.
You often start by integrating it to your existing JS code with ports and you can encounter this bug pretty early in your development process.

vjousse commented Jun 17, 2016

Same here, pretty annoying when discovering elm.
You often start by integrating it to your existing JS code with ports and you can encounter this bug pretty early in your development process.

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Jun 29, 2016

Member

@yoni-tock and I are going to pair on fixing this when he has some time in a couple weeks if no one can get to it earlier

Member

lukewestby commented Jun 29, 2016

@yoni-tock and I are going to pair on fixing this when he has some time in a couple weeks if no one can get to it earlier

@kittykatattack

This comment has been minimized.

Show comment
Hide comment
@kittykatattack

kittykatattack commented Jul 27, 2016

Just letting you all know I've experienced this bug too:

https://www.reddit.com/r/elm/comments/4u3icn/incoming_port_not_working/

@artisonian

This comment has been minimized.

Show comment
Hide comment
@artisonian

artisonian Jul 27, 2016

I've been looking into the issue. So far, I can tell that the app gets initialized using the scheduler (which doesn't do any work until the next turn of the event loop). I imagine three possible fixes:

  • Add a way to schedule work immediately (to ensure the app is initialized in the same turn as fullscreen/embed/worker)
  • Rearrange the work queue on the on the first loop so that the scheduler runs initialization first
  • Make initialization synchronous (which may mean bypassing the scheduler altogether, but that may cause other things to break)

artisonian commented Jul 27, 2016

I've been looking into the issue. So far, I can tell that the app gets initialized using the scheduler (which doesn't do any work until the next turn of the event loop). I imagine three possible fixes:

  • Add a way to schedule work immediately (to ensure the app is initialized in the same turn as fullscreen/embed/worker)
  • Rearrange the work queue on the on the first loop so that the scheduler runs initialization first
  • Make initialization synchronous (which may mean bypassing the scheduler altogether, but that may cause other things to break)
@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Jul 27, 2016

Member

What if the initialization functions accepted a callback instead of returning the application object synchronously?

Elm.Main.fullscreen(flags, function (app) {
  app.ports.whatever.send('a string')
})
Member

lukewestby commented Jul 27, 2016

What if the initialization functions accepted a callback instead of returning the application object synchronously?

Elm.Main.fullscreen(flags, function (app) {
  app.ports.whatever.send('a string')
})
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Jul 27, 2016

Member

@lukewestby, I don't think we should make the API more complex. It's just a bug. It's totally possible to queue messages while things are initializing. In fact, the way I implemented the scheduler, that is exactly what I expect to be happening already. I looked into this quite some time ago and could not figure it out.

If folks want to continue discussion on this thread, please focus on exploring and sharing technical details. Obviously more people will run into this as more time passes. We do not need to record that every time it happens. So learn about the scheduler. If there is something you are really struggling with, ask on elm-dev. There's also a timing bug in the scheduler that I could not figure out. I think the scheduler is one of the coolest parts of the platform, so I think it would be fun for folks to look into these things.

Member

evancz commented Jul 27, 2016

@lukewestby, I don't think we should make the API more complex. It's just a bug. It's totally possible to queue messages while things are initializing. In fact, the way I implemented the scheduler, that is exactly what I expect to be happening already. I looked into this quite some time ago and could not figure it out.

If folks want to continue discussion on this thread, please focus on exploring and sharing technical details. Obviously more people will run into this as more time passes. We do not need to record that every time it happens. So learn about the scheduler. If there is something you are really struggling with, ask on elm-dev. There's also a timing bug in the scheduler that I could not figure out. I think the scheduler is one of the coolest parts of the platform, so I think it would be fun for folks to look into these things.

@artisonian

This comment has been minimized.

Show comment
Hide comment
@artisonian

artisonian Jul 27, 2016

@evancz @lukewestby The initial messages are being queued. I see this sequence:

  • setupOutgoingPort and setupIncomingPort both execute
  • makeEmbedHelp executes (but in the process, enqueues the initialization code)
  • any sends on that same turn of the event loop are enqueued, but onEffects for those ports haven't run yet, thus subList is empty (effectively dropping the messages)

I'll jump on elm-dev with questions about the scheduler, but just wanted to leave more details here.

artisonian commented Jul 27, 2016

@evancz @lukewestby The initial messages are being queued. I see this sequence:

  • setupOutgoingPort and setupIncomingPort both execute
  • makeEmbedHelp executes (but in the process, enqueues the initialization code)
  • any sends on that same turn of the event loop are enqueued, but onEffects for those ports haven't run yet, thus subList is empty (effectively dropping the messages)

I'll jump on elm-dev with questions about the scheduler, but just wanted to leave more details here.

@yoni-tock

This comment has been minimized.

Show comment
Hide comment
@yoni-tock

yoni-tock Jul 27, 2016

Contributor

@artisonian, let @lukewestby and I know what we can do to help. We were planning to dive into this next week

Contributor

yoni-tock commented Jul 27, 2016

@artisonian, let @lukewestby and I know what we can do to help. We were planning to dive into this next week

@yoni-tock

This comment has been minimized.

Show comment
Hide comment
@yoni-tock

yoni-tock Aug 8, 2016

Contributor

@lukewestby and I just set up a SSCCE here

Candidate fix PR to core coming soon

Contributor

yoni-tock commented Aug 8, 2016

@lukewestby and I just set up a SSCCE here

Candidate fix PR to core coming soon

@artisonian

This comment has been minimized.

Show comment
Hide comment
@artisonian

artisonian Aug 8, 2016

Cool. How did you tackle it?

BTW, I'm thinking about writing a blog post or something that walks through the internals of the scheduler. Think it's worth it?

artisonian commented Aug 8, 2016

Cool. How did you tackle it?

BTW, I'm thinking about writing a blog post or something that walks through the internals of the scheduler. Think it's worth it?

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Aug 9, 2016

Member

@artisonian this is what we did: https://github.com/elm-lang/core/pull/685

YES! Definitely write that blog post!

Member

lukewestby commented Aug 9, 2016

@artisonian this is what we did: https://github.com/elm-lang/core/pull/685

YES! Definitely write that blog post!

evancz added a commit that referenced this issue Aug 10, 2016

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Aug 11, 2016

Member

Closing this as elm-lang/core 4.0.5 was published yesterday containing the fix

Member

lukewestby commented Aug 11, 2016

Closing this as elm-lang/core 4.0.5 was published yesterday containing the fix

@lukewestby lukewestby closed this Aug 11, 2016

@amitu

This comment has been minimized.

Show comment
Hide comment
@amitu

amitu Oct 25, 2016

I am using elm-lang/core 4.0.5 and it is not fully fixed.

In init I return a port Cmd, and the port is this:

app.ports.is_key_set.subscribe(function(key){
    app.ports.keyData.send([key, localStorage.getItem(key) == "true"])
})

If I do a Debug.log on subscriptions, it says subscribed on keyData before is_key_set is called in javascript side, yet update function is not called.

If I change it to:

app.ports.is_key_set.subscribe(function(key){
    setTimeout(function(){
        app.ports.keyData.send([key, localStorage.getItem(key) == "true"])
    }, 0)
})

update is called.

amitu commented Oct 25, 2016

I am using elm-lang/core 4.0.5 and it is not fully fixed.

In init I return a port Cmd, and the port is this:

app.ports.is_key_set.subscribe(function(key){
    app.ports.keyData.send([key, localStorage.getItem(key) == "true"])
})

If I do a Debug.log on subscriptions, it says subscribed on keyData before is_key_set is called in javascript side, yet update function is not called.

If I change it to:

app.ports.is_key_set.subscribe(function(key){
    setTimeout(function(){
        app.ports.keyData.send([key, localStorage.getItem(key) == "true"])
    }, 0)
})

update is called.

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Oct 25, 2016

Member

@amitu please open a new issue and provide enough code to constitute an SSCCE of the problem you're experiencing

Member

lukewestby commented Oct 25, 2016

@amitu please open a new issue and provide enough code to constitute an SSCCE of the problem you're experiencing

mariash referenced this issue in concourse/atc Dec 13, 2016

add workaround for elm 0.17 ports issue
sometimes JS would fail to get message from Elm to render pipeline and
empty page was shown instead. It seems to be related to elm 0.17 ports
issue https://github.com/elm-lang/core/issues/595. After wrapping JS
code in SetTimeout it stopped failing.

[#133520341]

Signed-off-by: Maria Shaldibina <mshaldibina@pivotal.io>

xtremerui referenced this issue in concourse/web Jan 11, 2018

add workaround for elm 0.17 ports issue
sometimes JS would fail to get message from Elm to render pipeline and
empty page was shown instead. It seems to be related to elm 0.17 ports
issue https://github.com/elm-lang/core/issues/595. After wrapping JS
code in SetTimeout it stopped failing.

[#133520341]

Signed-off-by: Maria Shaldibina <mshaldibina@pivotal.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment