Skip to content

Commit 3560af8

Browse files
authored
Avoid starting internal requests unnecessarily (#64)
When the switch is off, all the requests waiting for the pool are no longer valid, there's a need to skip them in order to avoid a performance drop of the service.
1 parent 7b11a76 commit 3560af8

1 file changed

Lines changed: 44 additions & 40 deletions

File tree

service/service.ml

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -91,46 +91,50 @@ module Make (Opam_repo : Opam_repository_intf.S) = struct
9191

9292
(* Send [request] to [worker] and read the reply. *)
9393
let process ~switch ~log ~id request worker =
94-
let request_str =
95-
Worker.Solve_request.to_yojson request |> Yojson.Safe.to_string
96-
in
97-
let request_str =
98-
Printf.sprintf "%d\n%s" (String.length request_str) request_str
99-
in
100-
let process =
101-
Worker_process.write worker request_str >>= fun () ->
102-
Worker_process.read_line worker >>= fun time ->
103-
Worker_process.read_line worker >>= fun len ->
104-
match Astring.String.to_int len with
105-
| None -> Fmt.failwith "Bad frame from worker: time=%S len=%S" time len
106-
| Some len -> (
107-
Worker_process.read_into worker len >|= fun results ->
108-
match results.[0] with
109-
| '+' ->
110-
Log.info log "%s: found solution in %s s" id time;
111-
let packages =
112-
Astring.String.with_range ~first:1 results
113-
|> Astring.String.cuts ~sep:" "
114-
in
115-
Ok packages
116-
| '-' ->
117-
Log.info log "%s: eliminated all possibilities in %s s" id time;
118-
let msg = results |> Astring.String.with_range ~first:1 in
119-
Error msg
120-
| '!' ->
121-
let msg = results |> Astring.String.with_range ~first:1 in
122-
Fmt.failwith "BUG: solver worker failed: %s" msg
123-
| _ -> Fmt.failwith "BUG: bad output: %s" results)
124-
in
125-
( Lwt_switch.add_hook_or_exec (Some switch) @@ fun () ->
126-
(* Release the worker before cancelling the promise of the request, in order to prevent the
127-
* workers's pool choosing the worker for another processing.*)
128-
if Lwt.state process = Lwt.Sleep then (
129-
Worker_process.release worker;
130-
Lwt.cancel process;
131-
dispose worker)
132-
else Lwt.return_unit )
133-
>>= fun () -> process
94+
if not (Lwt_switch.is_on switch) then Lwt.fail Lwt.Canceled
95+
else
96+
let request_str =
97+
Worker.Solve_request.to_yojson request |> Yojson.Safe.to_string
98+
in
99+
let request_str =
100+
Printf.sprintf "%d\n%s" (String.length request_str) request_str
101+
in
102+
let process =
103+
Worker_process.write worker request_str >>= fun () ->
104+
Worker_process.read_line worker >>= fun time ->
105+
Worker_process.read_line worker >>= fun len ->
106+
match Astring.String.to_int len with
107+
| None ->
108+
Fmt.failwith "Bad frame from worker: time=%S len=%S" time len
109+
| Some len -> (
110+
Worker_process.read_into worker len >|= fun results ->
111+
match results.[0] with
112+
| '+' ->
113+
Log.info log "%s: found solution in %s s" id time;
114+
let packages =
115+
Astring.String.with_range ~first:1 results
116+
|> Astring.String.cuts ~sep:" "
117+
in
118+
Ok packages
119+
| '-' ->
120+
Log.info log "%s: eliminated all possibilities in %s s" id
121+
time;
122+
let msg = results |> Astring.String.with_range ~first:1 in
123+
Error msg
124+
| '!' ->
125+
let msg = results |> Astring.String.with_range ~first:1 in
126+
Fmt.failwith "BUG: solver worker failed: %s" msg
127+
| _ -> Fmt.failwith "BUG: bad output: %s" results)
128+
in
129+
( Lwt_switch.add_hook_or_exec (Some switch) @@ fun () ->
130+
(* Release the worker before cancelling the promise of the request, in order to prevent the
131+
* workers's pool choosing the worker for another processing.*)
132+
if Lwt.state process = Lwt.Sleep then (
133+
Worker_process.release worker;
134+
Lwt.cancel process;
135+
dispose worker)
136+
else Lwt.return_unit )
137+
>>= fun () -> process
134138

135139
let dispose = Lwt_pool.clear
136140
let ocaml = OpamPackage.Name.of_string "ocaml"

0 commit comments

Comments
 (0)