Skip to content

Fixing #132

Athan Clark requested to merge jsaddle-xhr-sync-bug-20210731 into master

Firstly before delving into the actual issue, and how this MR fixes it, let's define something. I'm going to reference this command as <verify>:

nix-shell --command "ghcid --command 'cabal repl examples:counter' --run"

This will run the examples/Counter.hs shpadoinkle example under localhost:8080.

The issue

If we take the current master commit (hash 35220f3f) and run <verify>, and observe localhost:8080 in a Firefox browser (later than version 30 as detailed in #132 (closed)), we will see that an error is thrown. The issue is that Firefox and Edge have both disabled synchronous XHR requests, because it is likely to lock-up the javascript runtime until the response is received.

The fix

It's almost embarrassingly simple how easy the fix is. In JSaddle, the server / client auto-updating mechanism is written almost entirely in javascript, through escaped strings.

However, in this catacomb of spaghetti, there's some hope - they've built-in the concept of synchronous vs. asynchronous message passing, and furthermore make a backend's synchronous message passing mechanism optional (they provide support for various backends, including clib, webkitgtk, webkit webview, etc.).

All I've done here, is disable the implementation of the synchronous backend for Warp, with Nothing (in jsaddle-warp/src/Language/Javascript/JSaddle/WebSockets.hs on my fork in github):

    "\
    ...
    \ " <> runBatch (\a -> "ws.send(JSON.stringify(" <> a <> "));")
--              (Just (\a -> "(function(){\n\
--                  \                       var xhr = new XMLHttpRequest();\n\
--                  \                       xhr.open('POST', '" <> fromMaybe "" jsaddleUri <> "/sync/'+syncKey, false);\n\
--                  \                       xhr.setRequestHeader(\"Content-type\", \"application/json\");\n\
--                  \                       xhr.send(JSON.stringify(" <> a <> "));\n\
--                  \                       return JSON.parse(xhr.response);})()")) <> "\
              Nothing <> "\
    ..."

This fixes the issue observed in <verify> (on this MR hash 1a9c7428), because now it only relies on websockets to facilitate communication.

Edited by Athan Clark

Merge request reports