Skip to content

Commit 6ff5090

Browse files
committed
localdb: expose option-based get functions
Allows callers to avoid exceptions, the previous get is now called get_exn so it's clear which users have to be have to be mindful of exceptions. Not all get_exn were converted to get, previous behaviour was widespread, and doing the change without changing behaviour is not trivial, better to do it only once its detected. Signed-off-by: Pau Ruiz Safont <pau.safont@vates.tech>
1 parent eae3e52 commit 6ff5090

File tree

10 files changed

+72
-57
lines changed

10 files changed

+72
-57
lines changed

ocaml/xapi/localdb.ml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,25 @@ exception Missing_key of string
6464
let m = Mutex.create ()
6565

6666
let get (key : string) =
67+
let __FUN = __FUNCTION__ in
68+
let ( let* ) = Option.bind in
6769
with_lock m (fun () ->
68-
assert_loaded () ;
69-
match Hashtbl.find_opt db key with
70-
| Some x ->
71-
x
72-
| None ->
73-
raise (Missing_key key)
70+
let* () =
71+
try assert_loaded () ; Some ()
72+
with e ->
73+
warn "%s: unexpected error, ignoring it: %s" __FUN
74+
(Printexc.to_string e) ;
75+
None
76+
in
77+
Hashtbl.find_opt db key
7478
)
7579

76-
let get_with_default (key : string) (default : string) =
77-
try get key with Missing_key _ -> default
80+
let get_exn key =
81+
match get key with Some x -> x | None -> raise (Missing_key key)
82+
83+
let get_bool key = Option.bind (get key) bool_of_string_opt
84+
85+
let get_int key = Option.bind (get key) int_of_string_opt
7886

7987
(* Returns true if a change was made and should be flushed *)
8088
let put_one (key : string) (v : string) =

ocaml/xapi/localdb.mli

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@
1818
(** Thrown when a particular named key could not be found. *)
1919
exception Missing_key of string
2020

21-
val get : string -> string
21+
val get : string -> string option
2222
(** Retrieves a value *)
2323

24-
val get_with_default : string -> string -> string
25-
(** [get_with_default key default] returns the value associated with [key],
26-
or [default] if the key is missing. *)
24+
val get_exn : string -> string
25+
(** Retrieves the value for the key, raises Missing_key when the key is not
26+
present *)
27+
28+
val get_bool : string -> bool option
29+
(** Retrieves the value for the key, returns a value when it's found and is a
30+
valid boolean, otherwise is [None] *)
31+
32+
val get_int : string -> int option
33+
(** Retrieves the value for the key, returns a value when it's found and is a
34+
valid int, otherwise is [None] *)
2735

2836
val put : string -> string -> unit
2937
(** Inserts a value into the database, only returns when the insertion has

ocaml/xapi/xapi.ml

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,9 @@ let synchronize_certificates_with_coordinator ~__context =
288288

289289
(* Make sure the local database can be read *)
290290
let init_local_database () =
291-
( try
292-
let (_ : string) = Localdb.get Constants.ha_armed in
293-
()
294-
with Localdb.Missing_key _ ->
295-
Localdb.put Constants.ha_armed "false" ;
296-
debug "%s = 'false' (by default)" Constants.ha_armed
291+
if Option.is_none (Localdb.get_bool Constants.ha_armed) then (
292+
Localdb.put Constants.ha_armed "false" ;
293+
debug "%s = 'false' (by default)" Constants.ha_armed
297294
) ;
298295
(* Add the local session check hook *)
299296
Session_check.check_local_session_hook :=
@@ -519,13 +516,14 @@ let start_ha () =
519516
(** Enable and load the redo log if we are the master, the local-DB flag is set
520517
* and HA is disabled *)
521518
let start_redo_log () =
519+
let redo_log_enabled () =
520+
Localdb.get_bool Constants.redo_log_enabled |> Option.value ~default:false
521+
in
522+
let ha_armed () =
523+
Localdb.get_bool Constants.ha_armed |> Option.value ~default:false
524+
in
522525
try
523-
if
524-
Pool_role.is_master ()
525-
&& bool_of_string
526-
(Localdb.get_with_default Constants.redo_log_enabled "false")
527-
&& not (bool_of_string (Localdb.get Constants.ha_armed))
528-
then (
526+
if Pool_role.is_master () && redo_log_enabled () && not (ha_armed ()) then (
529527
debug "Redo log was enabled when shutting down, so restarting it" ;
530528
Static_vdis.reattempt_on_boot_attach () ;
531529
(* enable the use of the redo log *)
@@ -610,7 +608,7 @@ let resynchronise_ha_state () =
610608
let pool = Helpers.get_pool ~__context in
611609
let pool_ha_enabled = Db.Pool.get_ha_enabled ~__context ~self:pool in
612610
let local_ha_enabled =
613-
bool_of_string (Localdb.get Constants.ha_armed)
611+
Localdb.get_bool Constants.ha_armed |> Option.value ~default:false
614612
in
615613
match (local_ha_enabled, pool_ha_enabled) with
616614
| true, true ->

ocaml/xapi/xapi_ha.ml

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ let propose_master () =
7676

7777
(** Returns true if local failover decisions have not been disabled on this node *)
7878
let local_failover_decisions_are_ok () =
79-
try not (bool_of_string (Localdb.get Constants.ha_disable_failover_decisions))
80-
with _ -> true
79+
let disabled =
80+
Localdb.get_bool Constants.ha_disable_failover_decisions
81+
|> Option.value ~default:false
82+
in
83+
not disabled
8184

8285
(** Since the liveset info doesn't include the host IP address, we persist these ourselves *)
8386
let write_uuid_to_ip_mapping ~__context =
@@ -91,8 +94,11 @@ let write_uuid_to_ip_mapping ~__context =
9194

9295
(** Since the liveset info doesn't include the host IP address, we persist these ourselves *)
9396
let get_uuid_to_ip_mapping () =
94-
let v = Localdb.get Constants.ha_peers in
95-
String_unmarshall_helper.map (fun x -> x) (fun x -> x) v
97+
match Localdb.get Constants.ha_peers with
98+
| Some peers ->
99+
String_unmarshall_helper.map (fun k -> k) (fun v -> v) peers
100+
| None ->
101+
[]
96102

97103
(** Without using the Pool's database, returns the IP address of a particular host
98104
named by UUID. *)
@@ -303,7 +309,7 @@ module Monitor = struct
303309
let statefiles = Xha_statefile.list_existing_statefiles () in
304310
debug "HA background thread starting" ;
305311
(* Grab the base timeout value so we can cook the reported latencies *)
306-
let base_t = int_of_string (Localdb.get Constants.ha_base_t) in
312+
let base_t = int_of_string (Localdb.get_exn Constants.ha_base_t) in
307313
let timeouts = Timeouts.derive base_t in
308314
(* Set up our per-host alert triggers *)
309315
let localhost_uuid = Helpers.get_localhost_uuid () in
@@ -501,8 +507,6 @@ module Monitor = struct
501507
)
502508
in
503509

504-
(* let planned_for = Int64.to_int (Db.Pool.get_ha_plan_exists_for ~__context ~self:pool) in *)
505-
506510
(* First consider whether VM failover actions need to happen.
507511
Convert the liveset into a list of Host references used by the VM failover code *)
508512
let liveset_uuids =
@@ -629,11 +633,9 @@ module Monitor = struct
629633
(* and yet has no statefile access *)
630634
in
631635
let all_live_nodes_lost_statefile =
632-
List.fold_left ( && ) true
633-
(List.map
634-
(fun (_, xha_host) -> relying_on_rule_2 xha_host)
635-
host_host_table
636-
)
636+
List.for_all
637+
(fun (_, xha_host) -> relying_on_rule_2 xha_host)
638+
host_host_table
637639
in
638640
warning_all_live_nodes_lost_statefile
639641
all_live_nodes_lost_statefile ;
@@ -984,19 +986,18 @@ let ha_start_daemon () =
984986
()
985987

986988
let on_server_restart () =
987-
let armed = bool_of_string (Localdb.get Constants.ha_armed) in
988-
if armed then (
989+
let armed () =
990+
Localdb.get_bool Constants.ha_armed |> Option.value ~default:false
991+
in
992+
if armed () then (
989993
debug "HA is supposed to be armed" ;
990994
(* Make sure daemons are up *)
991995
let finished = ref false in
992996
(* Do not proceed any further until the situation is resolved.
993997
XXX we might need some kind of user-override *)
994998
while not !finished do
995999
(* If someone has called Host.emergency_ha_disable in the background then we notice the change here *)
996-
if
997-
not
998-
(try bool_of_string (Localdb.get Constants.ha_armed) with _ -> false)
999-
then (
1000+
if not (armed ()) then (
10001001
warn
10011002
"ha_start_daemon aborted because someone has called \
10021003
Host.emergency_ha_disable" ;
@@ -1147,7 +1148,7 @@ let ha_stop_daemon __context _localhost =
11471148

11481149
let emergency_ha_disable __context soft =
11491150
let ha_armed =
1150-
try bool_of_string (Localdb.get Constants.ha_armed) with _ -> false
1151+
Localdb.get_bool Constants.ha_armed |> Option.value ~default:false
11511152
in
11521153
if not ha_armed then
11531154
if soft then

ocaml/xapi/xapi_host.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ let assert_safe_to_reenable ~__context ~self ~user_request =
7979
Repository_helpers.assert_no_host_pending_mandatory_guidance ~__context
8080
~host:self ;
8181
let host_disabled_until_reboot =
82-
try bool_of_string (Localdb.get Constants.host_disabled_until_reboot)
83-
with _ -> false
82+
Localdb.get_bool Constants.host_disabled_until_reboot
83+
|> Option.value ~default:false
8484
in
8585
if host_disabled_until_reboot then
8686
raise

ocaml/xapi/xapi_host_crashdump.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ let resynchronise ~__context ~host =
7171
let gone_away = Listext.List.set_difference db_filenames real_filenames
7272
and arrived = Listext.List.set_difference real_filenames db_filenames in
7373
let was_shutdown_cleanly =
74-
try bool_of_string (Localdb.get Constants.host_restarted_cleanly)
75-
with _ -> false
74+
Localdb.get_bool Constants.host_restarted_cleanly
75+
|> Option.value ~default:false
7676
in
7777
Localdb.put Constants.host_restarted_cleanly "false" ;
7878
(* If HA is enabled AND no crashdump appeared AND we weren't shutdown cleanly then assume it was a fence. *)

ocaml/xapi/xapi_host_helpers.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ let consider_enabling_host_nolock ~__context =
380380
Disabled hosts are excluded from the HA planning calculations. Otherwise a host may boot,
381381
fail to plug in a PBD and cause all protected VMs to suddenly become non-agile. *)
382382
let ha_enabled =
383-
try bool_of_string (Localdb.get Constants.ha_armed) with _ -> false
383+
Localdb.get_bool Constants.ha_armed |> Option.value ~default:false
384384
in
385385
let localhost = Helpers.get_localhost ~__context in
386386
let pbds = Db.Host.get_PBDs ~__context ~self:localhost in
@@ -451,8 +451,8 @@ let consider_enabling_host_nolock ~__context =
451451
until manually re-enabled by the user"
452452
)
453453
) else if
454-
try bool_of_string (Localdb.get Constants.host_disabled_until_reboot)
455-
with _ -> false
454+
Localdb.get_bool Constants.host_disabled_until_reboot
455+
|> Option.value ~default:false
456456
then
457457
debug
458458
"Host.enabled: system not just rebooted but host_disabled_until_reboot \

ocaml/xapi/xapi_pool.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,12 +1882,12 @@ let exchange_ca_certificates_on_join ~__context ~import ~export :
18821882

18831883
(* Assume that db backed up from master will be there and ready to go... *)
18841884
let emergency_transition_to_master ~__context =
1885-
if Localdb.get Constants.ha_armed = "true" then
1885+
if Localdb.get Constants.ha_armed = Some "true" then
18861886
raise (Api_errors.Server_error (Api_errors.ha_is_enabled, [])) ;
18871887
Xapi_pool_transition.become_master ()
18881888

18891889
let emergency_reset_master ~__context ~master_address =
1890-
if Localdb.get Constants.ha_armed = "true" then
1890+
if Localdb.get Constants.ha_armed = Some "true" then
18911891
raise (Api_errors.Server_error (Api_errors.ha_is_enabled, [])) ;
18921892
let master_address = Helpers.gethostbyname master_address in
18931893
Xapi_pool_transition.become_another_masters_slave master_address

ocaml/xapi/xapi_pool_transition.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ let run_external_scripts becoming_master =
6262
order
6363
in
6464
let already_run =
65-
try bool_of_string (Localdb.get Constants.master_scripts) with _ -> false
65+
Localdb.get_bool Constants.master_scripts |> Option.value ~default:false
6666
in
6767
(* Only do anything if we're switching mode *)
6868
if already_run <> becoming_master then (
@@ -228,8 +228,8 @@ let become_another_masters_slave master_address =
228228
(** If we just transitioned slave -> master (as indicated by the localdb flag) then generate a single alert *)
229229
let consider_sending_alert __context () =
230230
if
231-
try bool_of_string (Localdb.get Constants.this_node_just_became_master)
232-
with _ -> false
231+
Localdb.get_bool Constants.this_node_just_became_master
232+
|> Option.value ~default:false
233233
then
234234
let obj_uuid = Helpers.get_localhost_uuid () in
235235
let name, priority = Api_messages.pool_master_transition in

ocaml/xapi/xha_scripts.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module D = Debug.Make (struct let name = "xapi_ha" end)
1717
open D
1818

1919
let ha_dir () =
20-
let stack = Localdb.get Constants.ha_cluster_stack in
20+
let stack = Localdb.get_exn Constants.ha_cluster_stack in
2121
Filename.concat !Xapi_globs.cluster_stack_root stack
2222

2323
let ha_set_pool_state = "ha_set_pool_state"

0 commit comments

Comments
 (0)