Skip to content

Commit

Permalink
--check mode runs typechecker in main process instead of daemon
Browse files Browse the repository at this point in the history
Summary:
Run typechecker inside the parent process instead of a deamon
when in "--check" mode. This also allows "hh_server --check" on a directory
with a server daemon already running.

Reviewed By: int3

Differential Revision: D2746445

fb-gh-sync-id: b7866db1bd19f7808b6673261447266c4c4c105d
  • Loading branch information
alexchow authored and hhvm-bot committed Dec 15, 2015
1 parent 4eac8cb commit eb4a0cd
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 36 deletions.
64 changes: 34 additions & 30 deletions hphp/hack/src/server/serverMain.ml
Expand Up @@ -432,25 +432,7 @@ let save _genv env (kind, fn) =
| ServerArgs.Complete -> save_complete env fn
| ServerArgs.Mini -> ServerInit.save_state env fn

(* The main entry point of the daemon
* the only trick to understand here, is that env.modified is the set
* of files that changed, it is only set back to SSet.empty when the
* type-checker succeeded. So to know if there is some work to be done,
* we look if env.modified changed.
*
* The server monitor will pass client connections to this process
* via in_fd.
*)
let daemon_main options (ic, oc) =
let in_fd = Daemon.descr_of_in_channel ic in
let out_fd = Daemon.descr_of_out_channel oc in
(** If the client started the server, it opened an FD before forking,
* so it can be notified when the server is ready. The FD number was
* passed in program args. *)
let waiting_channel =
Option.map
(ServerArgs.waiting_client options)
~f:Handle.to_out_channel in
let setup_server options =
let root = ServerArgs.root options in
(* The OCaml default is 500, but we care about minimizing the memory
* overhead *)
Expand All @@ -477,17 +459,39 @@ let daemon_main options (ic, oc) =
if not Sys.win32 then Sys.set_signal Sys.sigpipe Sys.Signal_ignore;
PidLog.init (ServerFiles.pids_file root);
PidLog.log ~reason:"main" (Unix.getpid());
let genv = ServerEnvBuild.make_genv options config local_config in
let is_check_mode = ServerArgs.check_mode genv.options in
if is_check_mode then
let env = program_init genv in
Option.iter (ServerArgs.save_filename genv.options) (save genv env);
Hh_logger.log "Running in check mode";
Program.run_once_and_exit genv env
else
let env = MainInit.go options waiting_channel
(fun () -> program_init genv) in
serve genv env in_fd out_fd
ServerEnvBuild.make_genv options config local_config

let run_once options =
let genv = setup_server options in
if not (ServerArgs.check_mode genv.options) then
(Hh_logger.log "ServerMain run_once only supported in check mode.";
Exit_status.(exit Input_error));
let env = program_init genv in
Option.iter (ServerArgs.save_filename genv.options) (save genv env);
Hh_logger.log "Running in check mode";
Program.run_once_and_exit genv env

(*
* The server monitor will pass client connections to this process
* via ic.
*)
let daemon_main options (ic, oc) =
let genv = setup_server options in
if ServerArgs.check_mode genv.options then
(Hh_logger.log "Invalid program args - can't run daemon in check mode.";
Exit_status.(exit Input_error));
let in_fd = Daemon.descr_of_in_channel ic in
let out_fd = Daemon.descr_of_out_channel oc in
(** If the client started the server, it opened an FD before forking,
* so it can be notified when the server is ready. The FD number was
* passed in program args. *)
let waiting_channel =
Option.map
(ServerArgs.waiting_client options)
~f:Handle.to_out_channel in
let env = MainInit.go options waiting_channel
(fun () -> program_init genv) in
serve genv env in_fd out_fd

let entry =
Daemon.register_entry_point "ServerMain.daemon_main" daemon_main
2 changes: 2 additions & 0 deletions hphp/hack/src/server/serverMain.mli
Expand Up @@ -13,3 +13,5 @@
* these phantom types because OCaml doesn't allow polymorphic values that
* are not functions. *)
val entry: (ServerArgs.options, unit, unit) Daemon.entry

val run_once: ServerArgs.options -> 'a
15 changes: 9 additions & 6 deletions hphp/hack/src/server/serverMonitor.ml
Expand Up @@ -311,12 +311,15 @@ let monitor_daemon_main (options: ServerArgs.options) =
(** Make sure to lock the lockfile before doing *anything*, especially
* opening the socket. *)
let lock_file = ServerFiles.lock_file www_root in
if not (Lock.grab lock_file) then
(Hh_logger.log "Monitor daemon already running. Killing";
Exit_status.exit Exit_status.Ok);
let socket = Socket.init_unix_socket (ServerFiles.socket_file www_root) in
let typechecker = Alive (start_hh_server options) in
check_and_run_loop typechecker lock_file socket
if ServerArgs.check_mode options then
ServerMain.run_once options
else
if not (Lock.grab lock_file) then
(Hh_logger.log "Monitor daemon already running. Killing";
Exit_status.exit Exit_status.Ok);
let socket = Socket.init_unix_socket (ServerFiles.socket_file www_root) in
let typechecker = Alive (start_hh_server options) in
check_and_run_loop typechecker lock_file socket

let daemon_entry =
Daemon.register_entry_point
Expand Down

0 comments on commit eb4a0cd

Please sign in to comment.