purescript-contrib/purescript-affjax

Pending Requests and Timeouts

Closed this issue · 7 comments

I've run into two different failure situations, one handled well, the other not:

  1. AJAX requests made while offline to an external server fail immediately with AJAX request failed; I can handle this, choose to retry, etc; this all works fine.
  2. AJAX requests that are open but then stay open with no activity are stuck in a Pending state forever. For example:
    • We make a connection, then the network goes down.
    • We make a connection, but the server never finishes the request (holds it open, sending no data).

As far as I can tell scenario two is handled by the ontimeout event and the timeout attribute, neither of which Affjax uses.

Have I misunderstood something, or is this something that'd need implementing (either in Affjax itself, or exposing the XHR itself like in #71)? Thanks.

garyb commented

You do this by using Aff's parallel behaviour:

  let
    req = AX.get "/some/slow/url"
    timeout = later' 1000 (throwError (error "Timed out"))
  res <- sequential $ parallel req <|> parallel timeout

The Alt instance for parallel things let you race them (prior to the current parallel it is/was possible with the race function instead). I think using that's preferrable to introducing another mechanism that does the same thing, but I'm open to discussing it.

garyb commented

Actually, sorry, the above isn't quite right, it should be more like:

    req = AX.get "/some/slow/url"
    timeout = later' 1000 $ pure (Left "Timed out")
  res <- sequential $ parallel (Right <$> req) <|> parallel timeout

The race behaviour awaits the first successful aff, so using throwError means it will always be ignored.

That might work for GET (I don't know what creating a bunch of Pending-forever requests does, but I'm putting that to one side until I can get more information), but that's possibly dangerous for, say, POST, where something may take effect every time you hit the server.

The above example seems to preclude the possibility of only hitting the server once, and waiting for a specified timeout period.

garyb commented

The above example seems to preclude the possibility of only hitting the server once, and waiting for a specified timeout period.

I'm not sure I understand how that's the case?

Regarding pending forever requests, I realised that also and proposed this: purescript-contrib/purescript-aff#87, which will do the trick.

garyb commented

Yep, thats the one! But until that PR goes in the pending request will potentially be left hanging indefinitely, which is obviously not good. So thanks for raising this issue, otherwise I never would have considered that 😄

purescript-contrib/purescript-aff#87 has merged, so closing this. Thanks!