Skip to content

Commit

Permalink
Special pipe between monitor and server for clients using force_dorma…
Browse files Browse the repository at this point in the history
…nt_start option

Summary:
We want to prevent accepting clients, but there are also special clients (using `--force-dormant-start` flag) that need to be accepted. The easiest way I could think to do it (without rewriting entire client handling code, which we should do at some point), is to send them through a special channel.

(Note: this ignores all push blocking failures!)

Differential Revision: D10515469

fbshipit-source-id: f63d5e6bd0661530b9d522cfb7b239c477adb53a
  • Loading branch information
dabek authored and hhvm-bot committed Oct 23, 2018
1 parent 299bfb6 commit f61dcad
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 12 deletions.
4 changes: 2 additions & 2 deletions hphp/hack/src/server/clientProvider_sig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module type S = sig

exception Client_went_away

val provider_from_file_descriptors : (Unix.file_descr * Unix.file_descr) -> t
val provider_from_file_descriptors : (Unix.file_descr * Unix.file_descr * Unix.file_descr) -> t
val provider_for_test : unit -> t

val sleep_and_check : t ->
Expand All @@ -22,7 +22,7 @@ module type S = sig
(* Whether the most recent message received from persistent client
* was IDE_IDLE *)
ide_idle:bool ->
[`Any | `Priority] ->
[`Any | `Priority | `Force_dormant_start_only] ->
(** Returns an optional new client, and a boolean for whether there is
* a request on the persistent client. *)
client option * bool
Expand Down
12 changes: 11 additions & 1 deletion hphp/hack/src/server/hhServerMonitorConfig.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ module SP = ServerProcess
type pipe_type =
| Default
| Priority
| Force_dormant_start_only

let pipe_type_to_string = function
| Default -> "default"
| Priority -> "priority"
| Force_dormant_start_only -> "force_dormant_start_only"

let start_server_daemon ~informant_managed options log_link daemon_entry =
let log_fds =
Expand All @@ -43,13 +45,20 @@ let start_server_daemon ~informant_managed options log_link daemon_entry =
let () = Unix.set_close_on_exec parent_priority_fd in
let () = Unix.clear_close_on_exec child_priority_fd in

let parent_force_dormant_start_only_fd, child_force_dormant_start_only_force_fd =
Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0 in
let () = Unix.set_close_on_exec parent_force_dormant_start_only_fd in
let () = Unix.clear_close_on_exec child_force_dormant_start_only_force_fd in

let {Daemon.pid; Daemon.channels = (ic, oc)} =
Daemon.spawn
~channel_mode:`socket
log_fds
daemon_entry
(informant_managed, state, options, monitor_pid, child_priority_fd) in
(informant_managed, state, options, monitor_pid,
child_priority_fd, child_force_dormant_start_only_force_fd) in
Unix.close child_priority_fd;
Unix.close child_force_dormant_start_only_force_fd;
Hh_logger.log "Just started typechecker server with pid: %d." pid;
let server =
SP.({
Expand All @@ -58,6 +67,7 @@ let start_server_daemon ~informant_managed options log_link daemon_entry =
out_fds = [
pipe_type_to_string Default, Daemon.descr_of_out_channel oc;
pipe_type_to_string Priority, parent_priority_fd;
pipe_type_to_string Force_dormant_start_only, parent_force_dormant_start_only_fd;
];
start_t = start_t;
last_request_handoff = ref (Unix.time());
Expand Down
11 changes: 6 additions & 5 deletions hphp/hack/src/server/serverClientProvider.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ open ServerCommandTypes

exception Client_went_away

(* default pipe, priority pipe *)
type t = Unix.file_descr * Unix.file_descr
(* default pipe, priority pipe, force formant start only pipe *)
type t = Unix.file_descr * Unix.file_descr * Unix.file_descr
type client =
| Non_persistent_client of Timeout.in_channel * Out_channel.t
| Persistent_client of Unix.file_descr
Expand All @@ -40,14 +40,15 @@ let accept_client_opt parent_in_fd =
(* - If we should read from persistent_client, then (None, true) *)
(* - If we should read from in_fd, then (Some (Non_persist in_fd)), false) *)
(* - If there's nothing to read, then (None, false) *)
let sleep_and_check (default_in_fd, priority_in_fd) persistent_client_opt
let sleep_and_check (default_in_fd, priority_in_fd, force_dormant_start_only) persistent_client_opt
~ide_idle kind =
let in_fds = [default_in_fd; priority_in_fd] in
let in_fds = [default_in_fd; priority_in_fd; force_dormant_start_only] in
let is_persistent x = match persistent_client_opt with
| Some (Persistent_client fd) when fd = x -> true
| _ -> false
in
let l = match kind, persistent_client_opt with
| `Force_dormant_start_only, _ -> [force_dormant_start_only]
| `Priority, _ -> [priority_in_fd]
| `Any, Some (Persistent_client fd) ->
(* If we are not sure that there are no more IDE commands, do not even
Expand All @@ -73,7 +74,7 @@ let has_persistent_connection_request = function
ready <> []
| _ -> false

let priority_fd (_, x) = Some x
let priority_fd (_, x, _) = Some x

let get_client_fd = function
| Persistent_client fd -> Some fd
Expand Down
9 changes: 6 additions & 3 deletions hphp/hack/src/server/serverMain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -909,10 +909,13 @@ let daemon_main_exn ~informant_managed options monitor_pid in_fds =
let env = MainInit.go genv options init_id (fun () -> program_init genv) in
serve genv env in_fds

let daemon_main (informant_managed, state, options, monitor_pid, priority_in_fd)
(default_ic, _) =
let daemon_main
(informant_managed, state, options,
monitor_pid, priority_in_fd, force_dormant_start_only_in_fd)
(default_ic, _) =
(* Avoid leaking this fd further *)
let () = Unix.set_close_on_exec priority_in_fd in
let () = Unix.set_close_on_exec force_dormant_start_only_in_fd in
let default_in_fd = Daemon.descr_of_in_channel default_ic in
(* Restore the root directory and other global states from monitor *)
ServerGlobalState.restore state;
Expand All @@ -922,7 +925,7 @@ let daemon_main (informant_managed, state, options, monitor_pid, priority_in_fd)

ServerUtils.with_exit_on_exception @@ fun () ->
daemon_main_exn ~informant_managed options monitor_pid
(default_in_fd, priority_in_fd)
(default_in_fd, priority_in_fd, force_dormant_start_only_in_fd)


let entry =
Expand Down
2 changes: 1 addition & 1 deletion hphp/hack/src/server/serverMain.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* these phantom types because OCaml doesn't allow polymorphic values that
* are not functions. *)
val entry:
(bool * ServerGlobalState.t * ServerArgs.options * int * Unix.file_descr,
(bool * ServerGlobalState.t * ServerArgs.options * int * Unix.file_descr * Unix.file_descr,
unit, unit) Daemon.entry

val run_once: ServerArgs.options -> SharedMem.handle -> 'a
Expand Down

0 comments on commit f61dcad

Please sign in to comment.