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

Candidate fix for #595 #685

Merged
merged 4 commits into from Aug 10, 2016

Conversation

Projects
None yet
7 participants
@lukewestby
Member

lukewestby commented Aug 8, 2016

This PR demonstrates one possible way to deal with calls to send prior to incoming ports being ready ( #595 ). As @artisonian mentioned, send can be called before onEffects in the port effect manager is called, so there are no Subs around to handle the send. This fix demonstrates queuing things that are sent until onEffects has been called for the first time, and then pushing all enqueued values through during that first call.

By @yjkogan and myself.

We demonstrated that this fixes the issue in https://github.com/lukewestby/elm-port-bootup-sscce

@process-bot

This comment has been minimized.

Show comment
Hide comment
@process-bot

process-bot Aug 8, 2016

Thanks for the pull request! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

process-bot commented Aug 8, 2016

Thanks for the pull request! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

Show outdated Hide outdated src/Native/Platform.js
if (!onEffectsCalled) {
onEffectsCalled = true;
enqueuedBeforeSetup.forEach(internalSend);
enqueuedBeforeSetup = null;

This comment has been minimized.

@knewter

knewter Aug 9, 2016

should this be turned into an empty array again? Feels weird changing its type.

@knewter

knewter Aug 9, 2016

should this be turned into an empty array again? Feels weird changing its type.

This comment has been minimized.

@evancz

evancz Aug 9, 2016

Member

I don't think it'll really matter.

@evancz

evancz Aug 9, 2016

Member

I don't think it'll really matter.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 9, 2016

Member

Switch to use the style in all the rest of the JS. Notice that { is always brought down a line. Notice that } else { is always split onto three lines. Also, can we switch forEach out for a for loop? I'm not sure how old forEach is and I avoid things like this in the JS I write or generate as much as possible.

Member

evancz commented Aug 9, 2016

Switch to use the style in all the rest of the JS. Notice that { is always brought down a line. Notice that } else { is always split onto three lines. Also, can we switch forEach out for a for loop? I'm not sure how old forEach is and I avoid things like this in the JS I write or generate as much as possible.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 9, 2016

Member

There are two alternate approaches.

  1. There is no such thing as onEffectsCalled, only queue = []. If it is instanceof Array you push values on it. If you send all the things, you switch queue to be null or undefined or something. This way there's no potential for synchronization issues between two different variables.
  2. Rather than having ifs, switch between two different send functions. The first one queues things. When it's time to switch, you send all the things and switch to the real send function.

Why is your approach better than these?

Member

evancz commented Aug 9, 2016

There are two alternate approaches.

  1. There is no such thing as onEffectsCalled, only queue = []. If it is instanceof Array you push values on it. If you send all the things, you switch queue to be null or undefined or something. This way there's no potential for synchronization issues between two different variables.
  2. Rather than having ifs, switch between two different send functions. The first one queues things. When it's time to switch, you send all the things and switch to the real send function.

Why is your approach better than these?

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Aug 9, 2016

Member

Of the option we posted and the two alternatives I think alternative 2 is the best approach. It has the same benefit as alternative 1 of limiting the potential for variables to become out of sync and it also allows for the onEffects and send implementations in use for the majority of the application's lifetime to not need to check some condition that will never be relevant again.

I'll for sure change the forEach to a loop - forEach isn't present in IE8.

Member

lukewestby commented Aug 9, 2016

Of the option we posted and the two alternatives I think alternative 2 is the best approach. It has the same benefit as alternative 1 of limiting the potential for variables to become out of sync and it also allows for the onEffects and send implementations in use for the majority of the application's lifetime to not need to check some condition that will never be relevant again.

I'll for sure change the forEach to a loop - forEach isn't present in IE8.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 9, 2016

Member

Cool. Also, thanks for figuring this out and working on the PR!

Member

evancz commented Aug 9, 2016

Cool. Also, thanks for figuring this out and working on the PR!

@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Aug 9, 2016

Member

No problem! It seems to be affecting a number of people and I got to hang out and code with @yjkogan for a couple hours 😄 win/win/win

Updates coming shortly

Member

lukewestby commented Aug 9, 2016

No problem! It seems to be affecting a number of people and I got to hang out and code with @yjkogan for a couple hours 😄 win/win/win

Updates coming shortly

@yjkogan

This comment has been minimized.

Show comment
Hide comment
@yjkogan

yjkogan Aug 10, 2016

Looks awesome!

yjkogan commented Aug 10, 2016

Looks awesome!

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 10, 2016

Member

Cool :) The solution feels a little tricky, but I think that's inherent to the problem. I.e. This seems like the best way to do a hard thing. Point is, thanks @lukewestby and @yjkogan for sorting this one out! :D (Also hi!)

Do you think it makes sense to do 4.0.5 to get this out as quick as possible? I'll have to look back and see if there are any other changes on master, but that seems like the way to go to me.

Member

evancz commented Aug 10, 2016

Cool :) The solution feels a little tricky, but I think that's inherent to the problem. I.e. This seems like the best way to do a hard thing. Point is, thanks @lukewestby and @yjkogan for sorting this one out! :D (Also hi!)

Do you think it makes sense to do 4.0.5 to get this out as quick as possible? I'll have to look back and see if there are any other changes on master, but that seems like the way to go to me.

@evancz evancz merged commit efe096f into elm:master Aug 10, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@lukewestby

This comment has been minimized.

Show comment
Hide comment
@lukewestby

lukewestby Aug 10, 2016

Member

I'll defer to @yjkogan, @knewter and anyone else currently experiencing this in production to make a recommendation - I don't have any applications in this situation myself so I don't know how urgent it is.

Thanks!

Member

lukewestby commented Aug 10, 2016

I'll defer to @yjkogan, @knewter and anyone else currently experiencing this in production to make a recommendation - I don't have any applications in this situation myself so I don't know how urgent it is.

Thanks!

@knewter

This comment has been minimized.

Show comment
Hide comment
@knewter

knewter Aug 10, 2016

It's not urgent at all because you can always do a setTimeout(fn(){}, 0), it's just nice to keep new people from seeing the confusing result.

knewter commented Aug 10, 2016

It's not urgent at all because you can always do a setTimeout(fn(){}, 0), it's just nice to keep new people from seeing the confusing result.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Aug 10, 2016

Member

Eh, I just looked through the commits on master, and this is the only thing since 4.0.4 so I decided to just publish it. If you install things now, it should be 4.0.5 and this should be fixed.

Talk about it here if there are further issues. Otherwise, great work! :)

Member

evancz commented Aug 10, 2016

Eh, I just looked through the commits on master, and this is the only thing since 4.0.4 so I decided to just publish it. If you install things now, it should be 4.0.5 and this should be fixed.

Talk about it here if there are further issues. Otherwise, great work! :)

@yjkogan

This comment has been minimized.

Show comment
Hide comment
@yjkogan

yjkogan Aug 11, 2016

Woohoo! Late to the party but same as @knewter. It was easy to work-around once we found the issue but I think this makes the logic simpler (and lets our site load/paint faster!)

yjkogan commented Aug 11, 2016

Woohoo! Late to the party but same as @knewter. It was easy to work-around once we found the issue but I think this makes the logic simpler (and lets our site load/paint faster!)

@bipvanwinkle

This comment has been minimized.

Show comment
Hide comment
@bipvanwinkle

bipvanwinkle Aug 12, 2016

Thank you all for taking time to work on this issue!

bipvanwinkle commented Aug 12, 2016

Thank you all for taking time to work on this issue!

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