I'm trying to write a function that tries to evaluate a function, but stops after a specific timeout.
I tried to use Deferred.any, which returns a deferred that is fulfilled when one of the underlying deferred is fulfilled.
type 'a output = OK of 'a | Exn of exn
let fun_test msg f eq (inp,ans) =
let outp = wait_for (Deferred.any
[ return (try OK (f inp) with e -> Exn e)
; (after (Core.Std.sec 0.0) >>| (fun () -> Exn TIMEOUT))])
in {msg = msg;inp = inp;outp = outp;ans = ans;pass = eq outp ans}
I was not sure how to extract a value from the deferred monad, so I wrote a function 'wait_for' which just spins until the underlying value is determined.
let rec wait_for x =
match Deferred.peek x with
| None -> wait_for x
| Some done -> done;;
This did not work. After reading through the Async chapter of Real World OCaml, I realized I needed to start the scheduler. However I'm not sure where I would call Schedule.go in my code. I do not see where the type go : ?raise_unhandled_exn:bool -> unit -> Core.Std.never_returns would fit into code where you actually want your asynchronous code to return. The documentation for go says "Async programs do not exit until shutdown is called."
I was beginning to doubt I had taken the entirely wrong approach to the problem until I found a very similar solution to that same problem on this Cornell website
let timeout (thunk:unit -> 'a Deferred.t) (n:float) : ('a option) Deferred.t
= Deferred.any
[ after (sec n) >>| (fun () -> None) ;
thunk () >>= (fun x -> Some x) ]
Anyway, I'm not quite sure my use of wait_for is correct. Is there a canonical way to extract a value from the deferred monad? Also how do I start the scheduler?
Update:
I tried writing a timeout function using only Core.Std.Thread and Core.Std.Mutex.
let rec wait_for lck ptr =
Core.Std.Thread.delay 0.25;
Core.Std.Mutex.lock lck;
(match !ptr with
| None -> Core.Std.Mutex.unlock lck; wait_for lck ptr
| Some x -> Core.Std.Mutex.unlock lck; x);;
let timeout t f =
let lck = Core.Std.Mutex.create () in
let ptr = ref None in
let _ = Core.Std.Thread.create
(fun () -> Core.Std.Thread.delay t;
Core.Std.Mutex.lock lck;
(match !ptr with
| None -> ptr := Some (Exn TIMEOUT)
| Some _ -> ());
Core.Std.Mutex.unlock lck;) () in
let _ = Core.Std.Thread.create
(fun () -> let x = f () in
Core.Std.Mutex.lock lck;
(match !ptr with
| None -> ptr := Some x
| Some _ -> ());
Core.Std.Mutex.unlock lck;) () in
wait_for lck ptr
I think this is pretty close to working. It works on computations like let rec loop x = print_string ".\n"; loop x, but it does not work on computations like let rec loop x = loop x. I believe the problem right now is that if the computation f () loops infinitely, then its thread is never preempted, so none of other threads can notice the timeout has expired. If the thread does IO like printing a string, then the thread does get preempted. Also I don't know how to kill a thread, I couldn't find such a function in the documentation for Core.Std.Thread
The solution I came up with is
let kill pid sign =
try Unix.kill pid sign with
| Unix.Unix_error (e,f,p) -> debug_print ((Unix.error_message e)^"|"^f^"|"^p)
| e -> raise e;;
let timeout f arg time default =
let pipe_r,pipe_w = Unix.pipe () in
(match Unix.fork () with
| 0 -> let x = Some (f arg) in
let oc = Unix.out_channel_of_descr pipe_w in
Marshal.to_channel oc x [];
close_out oc;
exit 0
| pid0 ->
(match Unix.fork () with
| 0 -> Unix.sleep time;
kill pid0 Sys.sigkill;
let oc = Unix.out_channel_of_descr pipe_w in
Marshal.to_channel oc default [];
close_out oc;
exit 0
| pid1 -> let ic = Unix.in_channel_of_descr pipe_r in
let result = (Marshal.from_channel ic : 'b option) in
result ));;
I think I might be creating two zombie processes with this though. But it is the only solution that works on let rec loop x = loop x when compiled using ocamlopt (The solution using Unix.alarm given here works when compiled with ocamlc but not when compiled with ocamlopt).
Related
I'm writing code to monitor the content of a file. When the program reaches the end of the the file I want it to terminate cleanly.
let log () : input_channel Lwt.t =
openfile "log" [O_RDONLY] 0 >>= fun fd ->
Lwt.return (of_fd input fd);;
let rec loop (ic: input_channel) = Lwt_io.read_line ic >>= fun text ->
Lwt_io.printl text >>= fun _ -> loop ic;;
let monitor () : unit Lwt.t = log () >>= loop;;
let handler : exn -> unit Lwt.t = fun e -> match e with
| End_of_file -> let (p: unit Lwt.t), r = Lwt.wait() in p
| x -> Lwt.fail x;;
let main () : unit Lwt.t = Lwt.catch monitor handler;;
let _ = Lwt_main.run (main ());;
However, when reading a file and reaching the end, the program does not terminate, it just hangs and I have to escape with Ctrl+c. I am not sure what is going on under the hood with bind but I figured whatever it's doing, eventually Lwt_io.readline ic should eventually hit the end of the file and return an End_of_file exception, which presumably would get passed over to the handler, etc.
If I had to guess at a resolution, I would think maybe in the last bind of the definition of >>= I would include some if check. But I'd be checking, I think, whether Lwt_io.read_line returned End_of_file, which I though should be handled by the handler.
The Lwt.wait function creates a promise which could only be resolved using the second element of the returned pair, basically, this function will never terminate:
let never_ready () =
let (p,_) = Lwt.wait in
p
and this is exactly what you've written.
Concerning a graceful termination, ideally, you should do this in the loop function so that you can close the channel and prevent leaking of the valuable resources, e.g.,
let rec loop (ic: input_channel) =
Lwt_io.read_line ic >>= function
| exception End_of_file ->
Lwt.close ic
| text->
Lwt_io.printl text >>= fun () ->
loop ic
The minimum change to your code would be, however, to use Lwt.return () instead of Lwt.wait in the body of your handler.
I'm just a begginer in Ocaml, and I wanted to study the graph theory, but with implementations in Ocaml. And I've got a trouble to do something : I just wanted to list the connected components of a graph by using a Depth first search. So, I did :
#open "stack" ;;
let non_empty pile =
try push (pop pile) pile ; true with Empty -> false ;;
let connected_comp g =
let already_seen = make_vect (vect_length g) false in
let comp = [] in
let dfs s lst =
let totreat = new () in
already_seen.(s) <- true; push s totreat;
let rec add_neighbour l = match l with
| [] -> ()
| q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
| q::r -> add_neighbour r
in
while non_empty totreat do
let s = pop totreat in
already_seen.(s) <- true;
(* we want to add s to the list lst *) s::lst;
add_neighbour g.(s);
done
in
let rec head_list l = match l with
| [] -> failwith "Empty list"
| p::q -> p
in
let rec aux comp t = match t with
| t when t = vect_length g -> comp
| t when already_seen.(t) = true -> aux comp (t+1)
| t -> aux ((dfs t [])::comp) (t+1) (* we want that dfs t [] return the list lst modified *)
in aux comp 0;;
And I obtain :
> | t -> (dfs t [])::comp ; aux comp (t+1) (* we want that dfs t [] return the list lst modified *)
> ^^^^^^^^^^^^^^^^
Warning : this expression is of type unit list,
but is used with the type unit.
connected_comp : int list vect -> unit list = <fun>
- : unit list = []
- : unit = ()
Of course, I'm not surprised. But what I want to do is that the function dfs return the list sent on argument (the lst list) but modified, and here it's not the case as the function is of type unit, cause it return nothing. But in Ocaml, as the language is made for returning the last expression I think, I don't know how to do. I could as well use recursive algorithm for the dfs function, as, through filtering, it would permit me to return the list, but I just wanted to learn about Ocaml, and so modified (even if it's not optimal) my algorithm.
Someone could help me, please ?
Edit : As we ask me, I will try to reduce my code and get to the point. So, I have the function dfs which correspond to a Depth first search (for a graph)
let dfs s lst =
let totreat = new () in
already_seen.(s) <- true; push s totreat;
let rec add_neighbour l = match l with
| [] -> ()
| q::r when already_seen.(q) = false -> push q totreat; already_seen.(q) <- true; add_neighbour r
| q::r -> add_neighbour r
in
while non_empty totreat do
let s = pop totreat in
already_seen.(s) <- true;
(* we want to add s to the list lst *) s::lst;
add_neighbour g.(s);
done
in
(alreadyseen is a vector of boolean, defined previously)
And my only problem is that I want that the function return the list lst modified (in the loop while), when, at this point, it's a unit function.
I tried to define lst as a reference, but then I don't know how to return it...
I hope it's more clear, I'm not familiar with all of this at the moment...
Thank you !
Here is a degraded version of your code that demonstrate one way to do what you want.
let non_empty _ = false
let dfs s lst =
let local_lst = ref lst in
while non_empty () do
(*do stuff here*)
let s = 1 in
local_lst := s::!local_lst;
(*do stuff here*)
done;
!local_lst
I first initialize a local mutable value local_lst to the list lst given as an argument. I then update this value in the while loop. And finally I return the value stored in local_lst.
I have some tests on infinite lazy structures that might run indefinitely if the tested function is not correctly implemented, but I can’t find in the OUnit docs how to set a timeout on tests.
If you're using OUnit2, the following should work:
let tests =
"suite" >::: [OUnitTest.TestCase (
OUnitTest.Short,
(fun _ -> assert_equal 2 (1+1))
);
OUnitTest.TestCase (
OUnitTest.Long,
(fun _ -> assert_equal 4 (2+2))
)]
The type test_length is defined as:
type test_length =
| Immediate
| Short
| Long
| Huge
| Custom_length of float
I don't think that oUnit provides this functionality. I remember having to do this a while back and this is the quick hack I've come up with:
let race seconds ~f =
let ch = Event.new_channel () in
let timeout = Thread.create (fun () ->
Thread.delay seconds;
`Time_out |> Event.send ch |> Event.sync
) () in
let tf = Thread.create (fun () ->
`Result (f ()) |> Event.send ch |> Event.sync) () in
let res = ch |> Event.receive |> Event.sync in
try
Thread.kill timeout;
Thread.kill tf;
res
with _ -> res
let () =
let big_sum () =
let arr = Array.init 1_000_000 (fun x -> x) in
Array.fold_left (+) 0 arr in
match race 0.0001 ~f:big_sum with
| `Time_out -> print_endline "time to upgrade";
| `Result x -> Printf.printf "sum is: %d\n" x
This worked well enough for my use case but I'd definitely would not recommend using this if only because race will not work as you'd expect if ~f does no allocations or calls Thread.yield manually.
I have a homework where i need to write 2 communication servers, one which generates natural numbers and the other which prints them. the generating server will be sending to the printing server. The servers should communicate over the shared channel chan.The main function should spawn a thread for each server.
`
val sender = fn : int -> unit
val receiver = fn : unit -> 'a
val main = fn : unit -> unit
`
And so far this is code i have written:
`
datatype 'a inflist = NIL
| CONS of 'a * (unit -> 'a inflist);
fun HD (CONS(a,b)) = a
| HD NIL = raise Subscript;
fun TL (CONS(a,b)) = b()
| TL NIL = raise Subscript;
fun NULL NIL = true
| NULL _ = false;
fun TAKE(xs, 0) = []
| TAKE(NIL, n) = raise Subscript
| TAKE(CONS(x,xf), n) = x::TAKE(xf(), n-1);
fun FROMN n = CONS (n,fn () => FROMN (n+1));
val natnumber = FROMN 0;
fun printGenList f (h::t) = (f h; printGenList f t);
fun printList l = printGenList (fn(e) => print(Int.toString(e)^" ")) l;
fun printPairList l = printGenList (fn(e,f) => print("("^Int.toString(e)^", "^Int.toString(f)^") ")) l;
CM.make "$cml/cml.cm";
open CML;
val chan: int chan = channel();
fun gen ch () = send (ch, printList(TAKE(natnumber,101)));
fun printnat ch () = recv (ch);
fun main () =
let
val ch = channel() :int chan ;
val _ = spawn (gen ch);
val _ = spawn (printnat ch);
in
()
end;
`
But i am not getting the output. Am i going wrong in my syntax or the logic?
I am new to SML and Concurrent ML. Please help me.
Why are you using a infinite list? There are simpler ways to implement this.
I'm playing around with async in F#. Does this look right, or am I mangling things?
let time f =
let before = System.DateTime.Now
f () |> ignore
let after = System.DateTime.Now
after - before;;
let rec fib = function 0 | 1 -> 1
| n -> fib (n - 1) + fib (n - 2);;
let source = [45; 40; 45; 40]
let synchronous = time <| fun () -> List.map fib source
let para = time <| fun () -> source
|> List.map (fun n -> async {ignore <| fib n})
|> Async.Parallel
|> Async.RunSynchronously
In particular, how do I return results from an async block? Do I have to use mutable state?
Update: here's another approach:
#r "FSharp.PowerPack.Parallel.Seq.dll"
open Microsoft.FSharp.Collections
let pseq = time <| fun () -> source
|> PSeq.map fib
|> PSeq.toList
Firstly, it's a bit of an anti-pattern to use async for parallel CPU processing. See these questions and answers for more information:
Why shouldn't I use F# asynchronous workflows for parallelism?
Task Parallel Library vs Async Workflows
Secondly, your fib function should be re-written to be tail recursive, here's an example from here (including changing to BigInt):
let fib n =
let rec loop acc1 acc2 = function
| n when n = 0I -> acc1
| n -> loop acc2 (acc1 + acc2) (n - 1I)
loop 0I 1I n
Finally, the full code:
let source = [| 45I; 40I; 45I; 40I |]
let sync = time <| fun () -> Array.map fib source
let para = time <| fun () -> Array.Parallel.map fib source
Note that in both cases an Array of the results is returned, you're just throwing it away in your time function. How about a time function that returns both the time and the result?
let time f =
let watch = new System.Diagnostics.Stopwatch()
watch.Start()
let res = f ()
watch.Stop()
(res, watch.ElapsedMilliseconds)
Usage remains the same, but now showing results:
printfn "Sync: %A in %ims" (fst sync) (snd sync)
printfn "Para: %A in %ims" (fst para) (snd para)