easafe / purescript-flame

Fast & simple framework for building web applications
https://flame.asafe.dev
MIT License
292 stars 10 forks source link

Question about Stale model in `AffUpdate` #77

Closed stevenyap closed 1 year ago

stevenyap commented 1 year ago

I am studying the example at https://github.com/easafe/purescript-flame/blob/master/examples/EffectfulAffjax/Affjax.purs and I think there is a racing condition which concerns model being stale while there are multiple model update in AffUpdate using display.

I have created a short video to capture this racing condition:

https://github.com/easafe/purescript-flame/assets/5533717/e04477f3-d7bb-4450-aafc-871efa5e590d

So when user click Fetch for https://hub.dummyapis.com/delay?seconds=10 and then before the response is returned, user changed it to https://hub.dummyapis.com/delay?seconds=1 and click Fetch again. Second request is resolved first and displayed then first request gets resolved and displayed as an outdated state now

Looking at the code https://github.com/easafe/purescript-flame/blob/5749e5607332fb0770d0e07682e5f6132bc3afab/examples/EffectfulAffjax/Affjax.purs#L33-L42 At line 40, we would need to check the latest model to see if model.url is still the same as what we have requested. Hence, we have the adjust the code to

update ∷ AffUpdate Model Message
update { display, model, message } =
  case message of
    UpdateUrl url → FAE.diff { url, result: NotFetched }
    Fetch → do
      display $ FAE.diff' { result: Fetching }
      response ← A.get AR.string model.url
      pure $ \m ->
        if m.url /= model.url then
          m
        else
          m { result = _ } $ case response of
            Left error → Error $ A.printError error
            Right payload → Ok payload.body

Is this idiomatic in this package? Did I miss out anything? Anyway to make this easier?

easafe commented 1 year ago

Hello again @stevenyap ,

The idiomatic way to do it would be the effect list updating (the type re-exported by default on Flame that mimics Elm). AffUpdate is occasionally useful to play around (hence why it is still there) but I don't recommend it for your apps.