You can use Lwt.pick or Lwt_unix.with_timeout for this. An example using Lwt.pick:
let get_or_timeout ?(max_request_duration = max_float) uri =
let open Lwt.Infix in
let timeout =
Lwt_unix.sleep max_request_duration >>= fun () ->
Lwt.return_error `Timed_out
in
let get =
Cohttp_lwt_unix.Client.get uri >>= fun response ->
Lwt.return_ok response
in
Lwt.pick [
timeout;
get;
]
with type
val get_or_timeout : (Cohttp.Response.t * Cohttp_lwt_body.t, [> `Timed_out ]) result
If the timeout promise finishes first the get promise will be canceled. If the get promise finishes first then the timeout promise will be canceled.
let timeout_send2 url timeout =
let aux url timeout =
let uri = Uri.of_string url in
let%bind _, body = Cohttp_async.Client.get ~interrupt:(after (sec timeout)) uri in
Body.to_string body
in
Clock.with_timeout (sec timeout) (aux url timeout)
>>| function
| `Result body -> Log.debug logger "body: %s" body
| `Timeout -> Log.debug logger "Timeout with url:%s" url