Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This seems like it would introduce bugs, where the model changes before that message is handled, and your old model you put in your message overwrites those changes.


If the model changes, a new view is generated, so your message should take that into account.

I can't remember of any concurrency issue arising from handling multiple messages from the view, to be honest. I don't know if there's a specific mechanism blocking them, but it's simply never happened in 3 years of building elm apps for a living.


> If the model changes, a new view is generated, so your message should take that into account.

You don't have any guarantees about when that will occur though. Updates and view rendering are run independently.

I have an application that tracks mouse movement using pointer events for the user to draw, and I've definitely had a message from that come through after my model has updated and I'm no longer on that screen (and so nothing in the view generated from the model should produce that message), so it definitely can happen, even if you haven't encountered it.

Even if you don't encounter it that way, there are a bunch of footguns using this approach (e.g: doing this with tasks, HTTP requests, anything that has a defined delay before the message comes back).


Yes, the message needs to never be sent in a batch with other messages which change the model.


But it's not just that, you may e.g. be racing against messages from a subscription (this one is really dangerous if your subscriptions are things like listening for resizing, where that can mean your resizing message is effectively dropped and users see a really needed up UI).


Correct, you shouldn't do that. On the other hand, event of simultaneously resizing and writing input is kind of rare, and this will be fixed on next resize/input event, so I wouldn't be too bothered.


Well the tricky thing is you can't "not do that" because your Elm code doesn't have control over when subscriptions fire.

Note that this applies to any subscription and that it is effectively dropped forever; the next input event won't recover it (so in the case of resizing only the next resize event will change things, not the next input event). So e.g. you could have a long running operation in a Web Worker over ports and then if its result comes in right when your user happens to be inputting something then it is dropped and never returns.


Javascript is single-threaded so those sort of bugs can't ever happen.


No they still can. You can still have concurrency bugs in the absence of parallelism (the classic example of why concurrency and parallelism are not the same thing) as long as you have a concurrent API (which the Elm architecture is an example of).

The basic problem is that there is an undefined delay between a message is issued and when `update` is called on the message which can be caused by other messages being in the queue.

Here's an example with subscriptions and views.

Time 0: A subscription arrives with message `A` which is added to the message queue in Elm's runtime. Note that one "tick" in Elm's runtime has not yet passed so we don't process the queue just yet (to see why this can happen we can either look at Elm's source code or note that the fact that Elm doesn't lose a subscription even if updates are busy processing forces there to be a message queue of length > 1).

Time 1: Your view sends a message `B` which contains a snapshot of the model `M0` at Time 1. `B` is added to the message queue.

Time 2: Your update function pops off the message queue and processes `A`, resulting in a new model `M1`.

Time 3: The Elm runtime processes another tick and sees no new messages from either views or subscriptions.

Time 4: Since the runtime is now done examining subscriptions and view messages, your update function pops off the message queue and processes `B`, resetting the model back to `M0`.

At the end of this sequence you effectively haven't handled the subscription at all, and all this is on a single thread.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: