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

Order of port declarations in resulting JS influences behaviour #1110

Open
Jtalk opened this issue May 22, 2021 · 1 comment
Open

Order of port declarations in resulting JS influences behaviour #1110

Jtalk opened this issue May 22, 2021 · 1 comment

Comments

@Jtalk
Copy link

Jtalk commented May 22, 2021

SSCCE

https://ellie-app.com/dfBrYLCyNPga1

Environment

  • Elm 0.19.1
  • Elm/Core 1.0.5

Trivia

  • This seems to be a special case of Order of port declarations influences behaviour #896
  • We're sending an outgoing port command that synchronously responds via another (incoming) port.
  • When an outgoing port command is issued together with a model change that triggers an incoming port subscription, the response to that port might get skipped if the outgoing port is registered first in the resulting JS.
  • In the above example, the first message from the button gets lost because Subs of the receiving port get updated after the Cmd is fired.
  • In the above example, renaming zsubscriptions to subscriptions puts it above update in the resulting JS, changing the behaviour of the button (Subs now come first & the incoming port's data is received correctly).

Problem

  • The order of registration of incoming and outgoing ports in the resulting JS file influences behaviour for dynamic subscriptions.

Impact

  • It makes synchronous data requests via Ports unpredictable as soon as we start making subscriptions dynamically.
  • For me it breaks localStorage access from nested components (components request data on init and never get it back).

Possible fix

The problem seems related to how _Platform_dispatchEffects iterates over effect managers. It bundles Cmd and Sub updates into a single object & submits it to each manager in the order of their appearance in the managers object.

The fix would involve forcing the order, I see two options:

  • Separate Sub and Cmd effects and submit them separately, iterating over the managers container twice (e.g. submit { __subs: subs, __cmds: __List_Nil } to each of the managers followed by { __subs: __List_Nil, __cmds: cmds }. The downside is that each manager would receive 2 events per lifecycle tick.
  • Introduce the idea of manager ordering & set priority for managers handling incoming ports over outgoing. It would require a new field in the managers, but the change should remain private within Kernel.Platform.

Since the existing behaviour is unpredictable, I guess it can be seen as backward-compatible patch-level fix.

I'm happy to raise a PR if you think it's worth fixing

@github-actions
Copy link

Thanks for reporting this! To set expectations:

  • Issues are reviewed in batches, so it can take some time to get a response.
  • Ask questions a community forum. You will get an answer quicker that way!
  • If you experience something similar, open a new issue. We like duplicates.

Finally, please be patient with the core team. They are trying their best with limited resources.

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

No branches or pull requests

1 participant