Permalink
Browse files

Do not accept new clients in hg.update state

Summary:
Doing things in the middle of update is bad, because it's too easy to accidentally observe O(repo) state (similarly to how we already were trying to not even start the server in the middle of update).

(Note: this ignores all push blocking failures!)

Differential Revision: D10515476

fbshipit-source-id: 622b25c78c02f4f2d8359c9249bc82e0d972c373
  • Loading branch information...
dabek authored and hhvm-bot committed Oct 23, 2018
1 parent f61dcad commit ee0ee18e74be08368a691725e4336ae027251e65
Showing with 22 additions and 11 deletions.
  1. +2 −1 hphp/hack/src/client/clientConnect.ml
  2. +20 −10 hphp/hack/src/server/serverMain.ml
@@ -287,7 +287,8 @@ let rec connect ?(first_attempt=false) env retries start_time tail_env =
let handoff_options = {
MonitorRpc.force_dormant_start = env.force_dormant_start;
pipe_name = HhServerMonitorConfig.(pipe_type_to_string
(if env.use_priority_pipe then Priority else Default))
(if env.force_dormant_start then Force_dormant_start_only else
if env.use_priority_pipe then Priority else Default))
} in
let retries, conn =
let start_t = Unix.gettimeofday () in
@@ -476,18 +476,27 @@ let has_pending_disk_changes genv =
let serve_one_iteration genv env client_provider =
let recheck_id = new_serve_iteration_id () in
ServerMonitorUtils.exit_if_parent_dead ();
let client_kind =
let has_default_client_pending =
Option.is_some env.default_client_pending_command_needs_full_check in
let can_accept_clients = not @@ ServerRevisionTracker.is_in_hg_update_state () in
let client_kind = match can_accept_clients, has_default_client_pending with
(* If we are already blocked on some client, do not accept more of them.
* Other clients (that connect through priority pipe, or persistent clients)
* can still be handled *)
if Option.is_some env.default_client_pending_command_needs_full_check
then `Priority else `Any in
let client, has_persistent_connection_request =
ClientProvider.sleep_and_check
client_provider
env.persistent_client
~ide_idle:env.ide_idle
client_kind
* can still be handled - unless we are in hg.update state, where we want to
* stop accepting any new clients, with the exception of forced ones. *)
| true, true -> Some `Priority
| true, false -> Some `Any
| false, true -> None
| false, false -> Some `Force_dormant_start_only
in
let client, has_persistent_connection_request = match client_kind with
| None -> None, false
| Some client_kind ->
ClientProvider.sleep_and_check
client_provider
env.persistent_client
~ide_idle:env.ide_idle
client_kind
in
(* client here is "None" if we should either handle from our existing *)
(* persistent client (i.e. has_persistent_connection_request), or if *)
@@ -661,6 +670,7 @@ let priority_client_interrupt_handler genv client_provider env =
end else
let client, has_persistent_connection_request =
if ServerRevisionTracker.is_in_hg_update_state () then None, false else
ClientProvider.sleep_and_check
client_provider
env.persistent_client

0 comments on commit ee0ee18

Please sign in to comment.