pkamenarsky / concur-replica

Server-side VDOM UI framework for Concur
BSD 3-Clause "New" or "Revised" License
139 stars 20 forks source link

Blank page with simplest possible widget #41

Open rossng opened 4 years ago

rossng commented 4 years ago

I encountered an issue I don't entirely understand while experimenting with concur-replica.

The examples work as expected, but I tried to write a very simple widget that just displays some text in a div. For some reason, this results in a blank page.

Here's what I tried:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}

module Main where

import Concur.Core (Widget)
import Concur.Replica
import Control.Monad (forever)
import Data.Maybe
import Data.Text (Text)
import Replica.VDOM (HTML)

import Prelude hiding (div)

textWidget :: forall a. Widget HTML a
textWidget = div [] [ text "Hello world" ]

main :: IO ()
main = runDefault 8080 "TestWidget" $ const textWidget

I also tried wrapping the definition of textWidget in forever, i.e.


textWidget :: forall a. Widget HTML a
textWidget = forever $ div [] [ text "Hello world" ]

When running these programs, I see a blank page and a 'The connection to ws://localhost:8080/ was interrupted while the page was loading.' message in the Firefox console.

This does work, but adding an onClick event handler feels wrong.

textWidget :: forall a. Widget HTML a
textWidget = forever $ p [onClick] [text "Hello world"]

Am I doing something wrong, or is this meant to work?

pkamenarsky commented 4 years ago

Strange, I can't reproduce this. This works as expected on both FF and Chrome:

textWidget :: Widget HTML a
textWidget = div [] [ text "Hello world" ]

main :: IO ()
main = runDefault 8080 "TestWidget" $ const textWidget
Screen Shot 2020-05-24 at 15 05 24

(As a side note, you are correct, there is no need to add an onClick handler or wrap things in forever, etc).

Are you on the newest concur-replica and replica commits? Not sure what else might be going on here.

rossng commented 4 years ago

Interesting. I am definitely on the latest commit. Just to be sure that I have things set up correctly, I also tried substituting the textWidget code directly into one of the examples in the concur-replica repo and saw the same issue.

However, I have been running it on Windows. I tried building and running the example in WSL (Ubuntu on Windows) and it works perfectly.

Is there any logging I can enable to help solve this?

pkamenarsky commented 4 years ago

Oh, that's not good. There is no logging ootb unfortunately, but I suspect the problem lies within concur-core - that's where all the multithreaded widget stuff gets done (more specifically, here).

Maybe Windows threads behave somewhat differently to *nix threads? Either way this points to an underlying problem, since at the end of the day everything should behave deterministically. I've been meaning to clean up concur-core and simplify it for a while now, but I haven't found the time yet.

If you're up for delving into the inner workings of concur-core, some trace statements in and around orr would probably point you in the right direction. I'd help in any way I can.

rossng commented 4 years ago

I spent most of today trying to debug this but without much success. Unfortunately I don't think I quite have the knowledge to effectively fix this ☹️

I noticed that adding trace statements actually affected the behaviour of the program. With no tracing, it worked none of the time, then with some tracing it worked some of the time. With lots of tracing it worked every time I refreshed the page. Perhaps a race condition?

pkamenarsky commented 4 years ago

Note to self: might be connected to #38.