I have a question about lwt's wait function and how I would use it in my own custom function which would return a 'a Lwt.t thread. First let's show you an example.
open Lwt_io
open Lwt.Infix
let i, o = Lwt_io.pipe()
let get_int () =
let t, w = Lwt.wait() in
(*what do I do here to provide the sleeping thread*)
(*with a possible integer reply*)
Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;
t
let ans = get_int()
In the above function I call wait to produce a sleeping thread plus its wakener but I'm unsure how to provide the sleeping thread with a possible integer reply and still be able to return a sleeping thread from the get_int function. I provided a line (Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;) which appears to work but I'm unsure if this the proper way to accomplish this. Any pointers or links or comments?
Note: I'm asking because adding Lwt_io.read_int(i) to the function is redundant. I could just eliminate the get_int function and just call Lwt_io.read_int(i) but I'm curious how you would do this without the redundancy.
First of all, let's switch to a new Lwt terminology. According to the new terminology, that was accepted in the Lwt library, the
Lwt.wait
function returns a promise and a resolver.This is a pretty low-level interface, that is usually used to implement more high-level interfaces. And indeed, in your case, the
get_int
function can be implemented as justLwt_io.read_int
.So, for the sake of an experiment let's implement something that makes slightly more sense:
Our
wait
function returns a promise, that will be fulfilled after a random delay. You may see, that there is a call toLwt.async
that will take a thunk and execute it in the event handler asynchonously, thus a functionwait
returns immediately. Of course, this example doesn't make much more sense, as a function with the same semantics can be implemented as:But this just shows, that the
wait
function is needed only to implement Lwt primitives.One of the justified use of this interface is when you need to decouple a service provider and a service consumer. Then you can use
Lwt.wait
(or even betterLwt.add_task_*
, e.g.,Of course, we just reimplemented mailbox (that is yet another proof, that we don't usually need to go that low, as everything is already done for us), but in general, when you have multiple requests, and you want to implement your own scheduling of them, then you can use this low-level interface.