Can you post a simple repro on Try WebSharper?

By on 9/20/2017 5:48 PM ()

OK, here are two samples. The first one behaves like I would like to have it, the second shows the blocking behavior. You have to adapt the loop number to a value that gives the right delay on your machine to watch the circles pop up.

Responsive: http://try.websharper.com/snippet/Martin%20000/0000Fy

Non-responsive: http://try.websharper.com/snippet/Martin%20000/0000GO

In my real code, I am calling functions of another module, so I cannot inline this into the Async as in the first sample.

Is there any way to explicitly yield control?

By on 9/22/2017 3:07 AM ()

If you have a let inside of an async block, that does not translate to a .Bind as in normal F#. So in the second sample, you still need to make sure that the expensive loop is inside an async, like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let SolveAsync =
    async {
        let solve m i =
            async {
                let mutable k = 0
                for j in 1 .. loops do k <- k + j/i
                let c = makeCircle (m%i) (100 + 60*i)
                circles.Value <- circles.Value @ [c]
                return m + k/i
            }
        let mutable m = 0
        for i in 1 .. 5 do 
            let! res = solve m i
            m <- res
    }

Or in your real case, the other module exposes the calculation similarly as an async<int>.

By on 9/22/2017 4:31 AM ()

It's not that easy in my case. The actual time consuming operations are called five layers deeper in the code. So I have to wrap all the related functions in these layers into asyncs. Plus I have to duplicate them because I still need the synchronous version for calls from other places of the top layer.

I am still wondering if there is another way to deal with such background calculations. Would it be possible to adapt the round robin scheduler in Concurrency to give internal tasks priority over user-scheduled asyncs?

By on 9/25/2017 5:00 AM ()

The problem is with the single threaded JavaScript execution. If you have a single code block that executes synchronously, you can do nothing about it being blocking from the outside.

We are planning support for Web Workers, so that you can run the heavy computation in parallel. Then, the internals of the computation won't need to be reworked to be asynchronous, but the communication would have to be. Keep an eye on https://github.com/intellifactory/websharper/issues/641

By on 9/27/2017 4:13 AM ()

In this case it is not about a single code block executing synchronously. In my non-responsive example above, the code returns for every circle, but the circles are not drawn. So it seems that control is given back to the user code before the Next.UI Dataflow finishes.

Anyway, don't put too much effort into this, I can wait for the Web Workers.

By on 9/28/2017 8:05 AM ()

UI.Next does not expose its pending state nicely, but I've found a hack that can work, add this after the call to solve:

1
2
do! Async.Sleep 0
do! Async.Sleep 0

Async.Sleep uses setTimeout internally, independent of WebSharper's scheduler. It is done twice so that it is not executing next heavier computation in the current or the next scheduling cycle, so at least a full one can be available for UI.Next to catch up with the mappings and update the DOM properly.

However this can still be disrupted when there are other heavy asyncs going on...

By on 9/29/2017 6:56 AM ()

This works great. Thanks a lot! It is just beautiful to see the growth of my data structure in real-time in the browser. And fantastic how this can be done with a few lines of code with Websharper.UI.Next.

By on 9/30/2017 7:41 AM ()

Sounds like you are doing some cool stuff, can you share some of it on Try WebSharper?

By on 9/30/2017 8:06 AM ()

It needs some more work, but then I will.

By on 10/3/2017 11:01 PM ()

Thanks a lot, this may work, I will try it later today.

By on 9/22/2017 4:59 AM ()

While trying to do this, I ran into a weird issue. I could not get any output from the templates. So I took the TODOLIST example on try.websharper and minimized it to this:

http://try.websharper.com/snippet/Martin%20000/0000Fx

This still works as expected. But if you now delete the second but last line in the markup (the <!--[BODY]--> comment), there is no output any more.

By on 9/22/2017 2:32 AM ()

Yes, the <!--[BODY]--> is a marker that gets replaced by the script tags generated by tryws.

By on 9/22/2017 2:34 AM ()

Took me a while to find this out. What about using <!-- DONT REMOVE THIS - NEEDED BY TRY.WEBSHARPER --> instead? Or else it would be good to mention it in the Help tab.

BTW it took me also a while to find out how to create a new snippet. Also here a hint would be nice for newbies.

By on 9/22/2017 2:55 AM ()

Agreed. Did you run into any other difficulties once you got on, or was everything more or less as you expected (other than figuring out the bit you mentioned on templating)? Every detail helps to improve the site, thanks!

By on 9/22/2017 3:12 AM ()

The rest of the Try.Websharper experience was great. One thing perhaps: I miss (or did not find) a way to delete a snippet.

Regarding the async question, see my other post below.

By on 9/22/2017 3:59 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us
Built with WebSharper