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

Port interactions do not preserve the order of Cmd.batch #799

Closed
lguminski opened this Issue Dec 30, 2016 · 8 comments

Comments

Projects
None yet
4 participants
@lguminski

lguminski commented Dec 30, 2016

I have noticed that Elm 0.18 does not respect the order of port interactions defined by Cmd.batch. This is a problem for me as I am writing an Elm web client which receives data with a series of events (log file), parses it, and dispatches a series of event to a Javascript module through Elm ports. Cmd.batch like this

  {} ! [ portA 5, portA 4, portB 3, portB 2, portA 1 ]

in Javascript console produces

Event [1] received through portA
Event [4] received through portA
Event [5] received through portA
Event [2] received through portB
Event [3] received through portB

As you can see first Javascript subscription handlers of Port A have been called, and then Port B, which broke the original ordering portA 5, portA 4, portB 3, portB 2, portA 1. Note: the test has been started after all subscriptions are in place (see elm.ports.triggerTest.send(null); line in index.html below). So the order of subscribing should not affect the observed behavior.

How to reproduce
All files are in https://github.com/lguminski/ElmOrderingPortEventsTest repository. Clone them

git clone https://github.com/lguminski/ElmOrderingPortEventsTest
cd ElmOrderingPortEventsTest
make

and open http://localhost:8000 in your browser and check logs in Javascript console.

Files

OrderingPortEventsTest.elm

port module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)

type alias Model =
  {}

type Msg
  = NoOp
  | Test ()


main =
  Html.program
    { init = init
    , update = update
    , view = view
    , subscriptions = subscriptions
    }

view : Model -> Html Msg
view model =
  div [] []

subscriptions : Model -> Sub Msg
subscriptions model =
  Sub.batch [ triggerTest Test ]

port portA : Int -> Cmd msg
port portB : Int -> Cmd msg
port triggerTest : (() -> msg) -> Sub msg

init : ( Model, Cmd Msg )
init =
  {} ! []

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
  case msg of

    NoOp ->
      model ! []

    Test _ ->
      model  !  [ portA 5, portA 4, portB 3, portB 2, portA 1 ]

index.html

<!DOCTYPE html>
<html lang="en">
    <body>
        <script src="elm.js"></script>
        <script>
            const elm = Elm.Main.fullscreen();
            elm.ports.portA.subscribe((number) => {
                console.log("Event [" + number + "] received through portA")
            });
            elm.ports.portB.subscribe((number) => {
                console.log("Event [" + number + "] received through portB")
            });
            elm.ports.triggerTest.send(null);
        </script>
    </body>
</html>
@process-bot

This comment has been minimized.

Show comment
Hide comment
@process-bot

process-bot Dec 30, 2016

Thanks for the issue! 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 Dec 30, 2016

Thanks for the issue! 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.

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Dec 30, 2016

Contributor

This is not a bug. The specification of Cmd.batch doesn't promise any order preservation. See the comments in https://github.com/elm-lang/core/issues/730.

Contributor

jvoigtlaender commented Dec 30, 2016

This is not a bug. The specification of Cmd.batch doesn't promise any order preservation. See the comments in https://github.com/elm-lang/core/issues/730.

@fosskers

This comment has been minimized.

Show comment
Hide comment
@fosskers

fosskers Apr 21, 2017

Just hit this problem. Definitely an unexpected result. It should be documented in Cmd.batch that no effect order is guaranteed, although mine appeared to be last-to-first.

The following gives the expected behaviour (notice the reverse):

 -- | All tests.                                                                                          
 tests : Cmd Event
 tests = Cmd.batch <| List.reverse
         [ H.send (Res "register/") (register host guy)
         , H.send (Res "signin/") (signin host guy.uuid)
         , H.send (Res "groups/ (A)") (groups host <| BlockSignin A "Foo" [guy.uuid])
         , H.send (Res "groups/ (B)") (groups host <| BlockSignin B "Bar" [guy.uuid])
         , H.send (Res "groups/ (C)") (groups host <| BlockSignin C "Baz" [guy.uuid])
         ]

fosskers commented Apr 21, 2017

Just hit this problem. Definitely an unexpected result. It should be documented in Cmd.batch that no effect order is guaranteed, although mine appeared to be last-to-first.

The following gives the expected behaviour (notice the reverse):

 -- | All tests.                                                                                          
 tests : Cmd Event
 tests = Cmd.batch <| List.reverse
         [ H.send (Res "register/") (register host guy)
         , H.send (Res "signin/") (signin host guy.uuid)
         , H.send (Res "groups/ (A)") (groups host <| BlockSignin A "Foo" [guy.uuid])
         , H.send (Res "groups/ (B)") (groups host <| BlockSignin B "Bar" [guy.uuid])
         , H.send (Res "groups/ (C)") (groups host <| BlockSignin C "Baz" [guy.uuid])
         ]
@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Apr 21, 2017

Contributor

@fosskers, as explained above and in #730, this is not a bug. If you think it is something that should be documented better/differently, a comment in this closed issue here will probably not help much. What might help is a new issue or PR calling for such a concrete documentation change.

Contributor

jvoigtlaender commented Apr 21, 2017

@fosskers, as explained above and in #730, this is not a bug. If you think it is something that should be documented better/differently, a comment in this closed issue here will probably not help much. What might help is a new issue or PR calling for such a concrete documentation change.

@fosskers

This comment has been minimized.

Show comment
Hide comment
@fosskers

fosskers Apr 21, 2017

It may not be a bug, but the "feature behaviour" is unexpected, and documenting as such in old issues is helpful for future devs, I've found. The more people that report the behaviour, the better.

fosskers commented Apr 21, 2017

It may not be a bug, but the "feature behaviour" is unexpected, and documenting as such in old issues is helpful for future devs, I've found. The more people that report the behaviour, the better.

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Apr 21, 2017

Contributor

So you say it "should be documented in Cmd.batch", but are unwilling to open an issue or PR that would work toward that goal? (The issue here is not working toward that goal of adding information to the documentation of Cmd.batch.)

Contributor

jvoigtlaender commented Apr 21, 2017

So you say it "should be documented in Cmd.batch", but are unwilling to open an issue or PR that would work toward that goal? (The issue here is not working toward that goal of adding information to the documentation of Cmd.batch.)

@fosskers

This comment has been minimized.

Show comment
Hide comment
@fosskers

fosskers Apr 24, 2017

Relax Janis ;)

fosskers commented Apr 24, 2017

Relax Janis ;)

@jvoigtlaender

This comment has been minimized.

Show comment
Hide comment
@jvoigtlaender

jvoigtlaender Apr 24, 2017

Contributor

Am relaxing.

Contributor

jvoigtlaender commented Apr 24, 2017

Am relaxing.

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