diff --git a/hphp/hack/src/server/serverMain.ml b/hphp/hack/src/server/serverMain.ml index c000d00f42315..a929d48a505d7 100644 --- a/hphp/hack/src/server/serverMain.ml +++ b/hphp/hack/src/server/serverMain.ml @@ -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 *) @@ -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 diff --git a/hphp/hack/src/server/serverMain.mli b/hphp/hack/src/server/serverMain.mli index b350c03af8647..d029e391164a4 100644 --- a/hphp/hack/src/server/serverMain.mli +++ b/hphp/hack/src/server/serverMain.mli @@ -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 diff --git a/hphp/hack/src/server/serverMonitor.ml b/hphp/hack/src/server/serverMonitor.ml index 64adcb66cb35d..137a70ded6e91 100644 --- a/hphp/hack/src/server/serverMonitor.ml +++ b/hphp/hack/src/server/serverMonitor.ml @@ -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