multithreadingasynchronousocamlocaml-lwtmirage

Lwt.async() not working as expected


I'm developing a web service in Ocaml on top of MirageOS(Unix) and at the moment I'm having some trouble with Lwt.async(). The Lwt documentation states the following:

val async : (unit -> 'a t) -> unit

async f starts a thread without waiting for the result. If it fails (now or later), the exception is given to Lwt.​async_exception_hook.

You should use this function if you want to start a thread that might fail and don't care what its return value is, nor when it terminates (for instance, because it is looping).

So I immediately considered Lwt.async as a good candidate to run some tests and check that actually the execution is asynchronous. Unfortunately it's not working as expected. My code is the following:

let http_callback conn_id req _body =
  Lwt.return(Uri.path (Cohttp.Request.uri req))
  >>= function
     | "/tester" -> Cohttp_lwt_body.to_string _body >>= fun res -> 
        log_lwt ~inject:(fun f -> f "Testing") >>= fun () ->
        Lwt.async(fun () -> TEST.start 100 res !listOfIP);
        H.respond_string ~status:`OK ~body:("DONE") ()
  in
     let spec = H.make ~callback:http_callback () in
     CON.listen conduit (`TCP 8080) (H.listen spec)

For the sake of clarity, TEST.start executes a series of threaded operations. I assume that it doesn't really matter what the function inside Lwt.async is doing, considering that whatever returns/does should be ignored. Am I wrong?

In the end, my question is: why actually the client has to wait for the thread to receive the OK response? With or without async the behaviour is basically the same.


Solution

  • Control will only switch back to the HTTP handler if the async thread blocks waiting for something. If it just uses the CPU 100% until it's done then the async thread will probably run to completion first. Try putting a sleep in the tests to check.