Skip to content

Commit cb417d1

Browse files
committed
strengthening(grader): Add a safeguard against grading workers going haywire
An uncaught exception could get caught upper on the stack, and lead the worker to start running pending lwt stuff that belong to the master.. Also attempt to fix "too many open files" error with many workers
1 parent ee57ac1 commit cb417d1

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

src/grader/grading_cli.ml

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,29 @@ let get_grade ?callback ?timeout ?dirname exo solution =
5252
| 0 ->
5353
(* /!\ there must be strictly no Lwt calls in the child *)
5454
Unix.close in_fd;
55-
let oc = Unix.out_channel_of_descr out_fd in
56-
let (ret: grader_answer) =
57-
Load_path.init [ cmis_dir ] ;
58-
Toploop_unix.initialize () ;
59-
let divert name chan cb =
60-
let redirection = Toploop_unix.redirect_channel name chan cb in
61-
fun () -> Toploop_unix.stop_channel_redirection redirection in
62-
let load_code compiled_code =
63-
try
64-
Toploop_unix.use_compiled_string compiled_code.Learnocaml_exercise.cma;
65-
Toploop_ext.Ok (true, [])
66-
with _ -> Toploop_ext.Ok (false, [])
67-
in
68-
Grading.get_grade ?callback ?timeout ?dirname ~divert ~load_code
69-
exo solution
55+
let () =
56+
try
57+
let oc = Unix.out_channel_of_descr out_fd in
58+
let (ret: grader_answer) =
59+
Load_path.init [ cmis_dir ] ;
60+
Toploop_unix.initialize () ;
61+
let divert name chan cb =
62+
let redirection = Toploop_unix.redirect_channel name chan cb in
63+
fun () -> Toploop_unix.stop_channel_redirection redirection in
64+
let load_code compiled_code =
65+
try
66+
Toploop_unix.use_compiled_string
67+
compiled_code.Learnocaml_exercise.cma;
68+
Toploop_ext.Ok (true, [])
69+
with _ -> Toploop_ext.Ok (false, [])
70+
in
71+
Grading.get_grade ?callback ?timeout ?dirname ~divert ~load_code
72+
exo solution
73+
in
74+
output_value oc ret
75+
with e ->
76+
Format.eprintf "Subprocess failed with: %s\n%!" (Printexc.to_string e)
7077
in
71-
output_value oc ret;
7278
flush_all ();
7379
Unix._exit 0
7480
| child_pid ->
@@ -79,6 +85,7 @@ let get_grade ?callback ?timeout ?dirname exo solution =
7985
(function End_of_file -> Lwt.return_none | exn -> Lwt.fail exn)
8086
>>= fun (ans: grader_answer option) ->
8187
Lwt_unix.waitpid [] child_pid >>= fun (_pid, stat) ->
88+
Lwt_io.close ic >>= fun () ->
8289
match ans, stat with
8390
| _, Unix.WSIGNALED n ->
8491
Printf.ksprintf Lwt.fail_with "Grading sub-process was killed (%d)" n

0 commit comments

Comments
 (0)