Remove deadcode: loading saved-state with informant-induced target
[hiphop-php.git] / hphp / hack / src / server / hhServerMonitorConfig.ml
blobdd3ef417af808c86d1b976d5caf79abd45556bee
1 (*
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 (** Responsible for starting up a Hack server process. *)
12 module SP = ServerProcess
14 type pipe_type =
15 | Default
16 | Priority
17 | Force_dormant_start_only
19 let pipe_type_to_string = function
20 | Default -> "default"
21 | Priority -> "priority"
22 | Force_dormant_start_only -> "force_dormant_start_only"
24 let start_server_daemon ~informant_managed options log_link daemon_entry =
25 let log_fds =
26 let in_fd = Daemon.null_fd () in
27 if ServerArgs.should_detach options then (
28 (try
29 let old_log_name i = Printf.sprintf "%s.%d.old" log_link i in
30 let max_n_log_files = 20 in
31 for i = max_n_log_files - 1 downto 1 do
32 if Sys.file_exists (old_log_name i) then
33 Sys.rename (old_log_name i) (old_log_name (i + 1))
34 done;
35 let old = log_link ^ ".old" in
36 if Sys.file_exists old then Sys.rename old (old_log_name 1);
37 if Sys.file_exists log_link then Sys.rename log_link old
38 with _ -> ());
39 let log_file = Sys_utils.make_link_of_timestamped log_link in
40 Hh_logger.log
41 "About to spawn typechecker daemon. Logs will go to %s\n%!"
42 ( if Sys.win32 then
43 log_file
44 else
45 log_link );
46 let fd = Daemon.fd_of_path log_file in
47 (in_fd, fd, fd)
48 ) else (
49 Hh_logger.log "About to spawn typechecker daemon. Logs will go here.";
50 (in_fd, Unix.stdout, Unix.stderr)
53 let start_t = Unix.time () in
54 let state = ServerGlobalState.save ~logging_init:(fun () -> ()) in
55 let monitor_pid = Unix.getpid () in
56 (* Setting some additional channels between monitor and server *)
57 let (parent_priority_fd, child_priority_fd) =
58 Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0
60 let () = Unix.set_close_on_exec parent_priority_fd in
61 let () = Unix.clear_close_on_exec child_priority_fd in
62 let ( parent_force_dormant_start_only_fd,
63 child_force_dormant_start_only_force_fd ) =
64 Unix.socketpair Unix.PF_UNIX Unix.SOCK_STREAM 0
66 let () = Unix.set_close_on_exec parent_force_dormant_start_only_fd in
67 let () = Unix.clear_close_on_exec child_force_dormant_start_only_force_fd in
68 let { Daemon.pid; Daemon.channels = (ic, oc) } =
69 Daemon.spawn
70 ~channel_mode:`socket
71 log_fds
72 daemon_entry
73 ( informant_managed,
74 state,
75 options,
76 monitor_pid,
77 child_priority_fd,
78 child_force_dormant_start_only_force_fd )
80 Unix.close child_priority_fd;
81 Unix.close child_force_dormant_start_only_force_fd;
82 Hh_logger.log "Just started typechecker server with pid: %d." pid;
84 (* We'll write an initial progress message to guarantee that the client will
85 certainly be able to read the progress file as soon as it learns the progress filename.
86 There's a benign race as to whether our message is written first, or whether the server
87 started up quickly enough to write its initial message first. It's benign because
88 either message will communicate the right intent to the user, and in any case the server
89 will always have further progress updates to write. *)
90 let server_progress_file = ServerFiles.server_progress_file pid in
91 let server_progress =
92 ServerCommandTypes.
94 server_progress = "starting hh_server";
95 server_warning = None;
96 server_timestamp = Unix.gettimeofday ();
99 ServerCommandTypesUtils.write_progress_file
100 ~server_progress_file
101 ~server_progress;
103 let server =
106 pid;
107 server_specific_files =
109 ServerCommandTypes.server_finale_file =
110 ServerFiles.server_finale_file pid;
111 server_progress_file;
113 in_fd = Daemon.descr_of_in_channel ic;
114 out_fds =
116 (pipe_type_to_string Default, Daemon.descr_of_out_channel oc);
117 (pipe_type_to_string Priority, parent_priority_fd);
118 ( pipe_type_to_string Force_dormant_start_only,
119 parent_force_dormant_start_only_fd );
121 start_t;
122 last_request_handoff = ref (Unix.time ());
125 server
127 let start_hh_server ~informant_managed options =
128 let log_link = ServerFiles.log_link (ServerArgs.root options) in
129 start_server_daemon ~informant_managed options log_link ServerMain.entry
131 module HhServerConfig = struct
132 type server_start_options = ServerArgs.options
134 let start_server ~informant_managed ~prior_exit_status options =
135 match prior_exit_status with
136 | Some c
137 when (c = Exit_status.(exit_code Sql_assertion_failure))
138 || (c = Exit_status.(exit_code Sql_cantopen))
139 || (c = Exit_status.(exit_code Sql_corrupt))
140 || c = Exit_status.(exit_code Sql_misuse) ->
141 start_hh_server ~informant_managed (ServerArgs.set_no_load options true)
142 | _ -> start_hh_server ~informant_managed options
144 let kill_server process =
145 try Unix.kill process.ServerProcess.pid Sys.sigusr2
146 with _ ->
147 Hh_logger.log
148 "Failed to send sigusr2 signal to server process. Trying violently";
149 (try Unix.kill process.ServerProcess.pid Sys.sigkill
150 with e ->
151 let stack = Printexc.get_backtrace () in
152 Hh_logger.exc
153 ~prefix:"Failed to violently kill server process: "
154 ~stack
157 let rec wait_for_server_exit process start_t =
158 let exit_status =
159 Unix.waitpid [Unix.WNOHANG; Unix.WUNTRACED] process.ServerProcess.pid
161 match exit_status with
162 | (0, _) ->
163 Unix.sleep 1;
164 wait_for_server_exit process start_t
165 | _ ->
166 ignore
167 (Hh_logger.log_duration
168 (Printf.sprintf "typechecker has exited. Time since sigterm: ")
169 start_t)
171 let wait_pid process =
172 Unix.waitpid [Unix.WNOHANG; Unix.WUNTRACED] process.ServerProcess.pid
174 let is_saved_state_precomputed = ServerArgs.is_using_precomputed_saved_state