Search code examples
f#websharper

WebSharper force a message passing call to be asynchronous


Knowing an RPC call to a server method that returns unit is a message passing call, I want to force the call to be asynchronous and be able to fire the next server call only after the first one has gone to the server.

Server code:

[<Rpc>]
let FirstCall value =
    printfn "%s" value
    async.Zero()

[<Rpc>]
let SecondCall() =
    "test"

Client code:

|>! OnClick (fun _ _ -> async {
                            do! Server.FirstCall "test"
                            do Server.SecondCall() |> ignore
                        } |> Async.Start)

This seems to crash on the client since returning unit, replacing the server and client code to:

[<Rpc>]
let FirstCall value =
    printfn "%s" value
    async { return () }

let! _ = Server.FirstCall "test"

Didn't fix the problem, while the following did:

[<Rpc>]
let FirstCall value =
    printfn "%s" value
    async { return "" }

let! _ = Server.FirstCall "test"

Is there another way to force a message passing call to be asynchronous instead?


Solution

  • This is most definitely a bug. I added it here:

    https://bugs.intellifactory.com/websharper/show_bug.cgi?id=468

    Your approach is completely legit. Your workaround is also probably the best for now, e.g. instead of returning Async<unit> return Async<int> with a zero and ignore it.

    We are busy with preparing the 2.4 release due next week and the fix will make it there. Thanks!

    Also, in 2.4 we'll be dropping synchronous calls, so you will have to use Async throughout for RPC, as discussed in https://bugs.intellifactory.com/websharper/show_bug.cgi?id=467 -- primarily motivated by new targets (Android and WP7) that do not support sync AJAX.