diff --git a/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/dune b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/dune index 663c24437c7..cdaf50ee02f 100644 --- a/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/dune +++ b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/dune @@ -1,16 +1,24 @@ (library (public_name xapi-stdext-threads) (name xapi_stdext_threads) - (modules :standard \ threadext_test) + (modules :standard \ ipq scheduler threadext_test ipq_test) (libraries threads.posix unix xapi-stdext-unix xapi-stdext-pervasives) ) -(test - (name threadext_test) + +(library + (public_name xapi-stdext-threads.scheduler) + (name xapi_stdext_threads_scheduler) + (modules ipq scheduler) + (libraries mtime mtime.clock threads.posix unix xapi-log xapi-stdext-threads) +) + +(tests + (names threadext_test ipq_test) (package xapi-stdext-threads) - (modules threadext_test) - (libraries xapi_stdext_threads alcotest mtime.clock.os mtime fmt threads.posix) + (modules threadext_test ipq_test) + (libraries xapi_stdext_threads alcotest mtime.clock.os mtime fmt threads.posix xapi_stdext_threads_scheduler) ) diff --git a/ocaml/xapi/ipq.ml b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.ml similarity index 73% rename from ocaml/xapi/ipq.ml rename to ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.ml index ba56825ebe0..4cf29ed3d9b 100644 --- a/ocaml/xapi/ipq.ml +++ b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.ml @@ -15,15 +15,16 @@ type 'a event = {ev: 'a; time: Mtime.t} -type 'a t = {mutable size: int; mutable data: 'a event array} +type 'a t = {default: 'a event; mutable size: int; mutable data: 'a event array} exception EmptyHeap -let create n = +let create n default = if n <= 0 then invalid_arg "create" else - {size= -n; data= [||]} + let default = {ev= default; time= Mtime_clock.now ()} in + {default; size= 0; data= Array.make n default} let is_empty h = h.size <= 0 @@ -32,16 +33,11 @@ let resize h = assert (n > 0) ; let n' = 2 * n in let d = h.data in - let d' = Array.make n' d.(0) in + let d' = Array.make n' h.default in Array.blit d 0 d' 0 n ; h.data <- d' let add h x = - (* first addition: we allocate the array *) - if h.size < 0 then ( - h.data <- Array.make (-h.size) x ; - h.size <- 0 - ) ; let n = h.size in (* resizing if needed *) if n = Array.length h.data then resize h ; @@ -64,10 +60,21 @@ let maximum h = let remove h s = if h.size <= 0 then raise EmptyHeap ; + if s < 0 || s >= h.size then + invalid_arg (Printf.sprintf "%s: index %d out of bounds" __FUNCTION__ s) ; let n = h.size - 1 in - h.size <- n ; let d = h.data in let x = d.(n) in + d.(n) <- h.default ; + (* moving [x] up in the heap *) + let rec moveup i = + let fi = (i - 1) / 2 in + if i > 0 && Mtime.is_later d.(fi).time ~than:x.time then ( + d.(i) <- d.(fi) ; + moveup fi + ) else + d.(i) <- x + in (* moving [x] down in the heap *) let rec movedown i = let j = (2 * i) + 1 in @@ -84,7 +91,13 @@ let remove h s = else d.(i) <- x in - movedown s + if s = n then + () + else if Mtime.is_later d.(s).time ~than:x.time then + moveup s + else + movedown s ; + h.size <- n let find h ev = let rec iter n = @@ -112,32 +125,24 @@ let pop_maximum h = let m = maximum h in remove h 0 ; m +let check h = + let d = h.data in + for i = 1 to h.size - 1 do + let fi = (i - 1) / 2 in + let ordered = Mtime.is_later d.(i).time ~than:d.(fi).time in + assert ordered + done + let iter f h = let d = h.data in for i = 0 to h.size - 1 do f d.(i) done +(* let fold f h x0 = let n = h.size in let d = h.data in let rec foldrec x i = if i >= n then x else foldrec (f d.(i) x) (succ i) in foldrec x0 0 - -(* -let _ = - let test : int t = create 100 in - for i=0 to 99 do - let e = {time=Random.float 10.0; ev=i} in - add test e - done; - for i=0 to 49 do - let xx=find test i in - remove test xx - done; -(* remove test xx;*) - for i=0 to 49 do - let e=pop_maximum test in - Printf.printf "time: %f, site: %d\n" e.time e.ev - done *) diff --git a/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.mli b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.mli new file mode 100644 index 00000000000..b7c4974e642 --- /dev/null +++ b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq.mli @@ -0,0 +1,58 @@ +(* + * Copyright (C) 2024 Cloud Software Group + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *) + +type 'a event = {ev: 'a; time: Mtime.t} + +type 'a t + +exception EmptyHeap + +val create : int -> 'a -> 'a t +(** [create n default] creates an empty Imperative priority queue. + The queue initially is initialized to store [n] elements. + The queue will expand beyond [n] automatically if needed. + [default] value will the used to fill unused data. *) + +val is_empty : 'a t -> bool +(** Check if the queue is empty *) + +val add : 'a t -> 'a event -> unit +(** Add an event to the queue *) + +val remove : 'a t -> int -> unit +(** Remove an event from the queue passing the index. + @raise EmptyHeap if the queue is empty. + @raise Invalid_argument if the index is invalid. *) + +val find_p : 'a t -> ('a -> bool) -> int +(** Find the index of an event which matches a given condition + or -1 if not found *) + +val find : 'a t -> 'a -> int +(** Find the index of an event which matches a given event + or -1 if not found *) + +val maximum : 'a t -> 'a event +(** Return a copy of the event with the next time. + @raise EmptyHeap if the queue is empty. *) + +val pop_maximum : 'a t -> 'a event +(** Return and remove the event with the next time. + @raise EmptyHeap if the queue is empty. *) + +val iter : ('a event -> unit) -> 'a t -> unit +(** Iterate given function on the list of events in the queue *) + +val check : 'a t -> unit +(** Check internal queue state, used for debugging *) diff --git a/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq_test.ml b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq_test.ml new file mode 100644 index 00000000000..e8e64093e16 --- /dev/null +++ b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq_test.ml @@ -0,0 +1,143 @@ +(* + * Copyright (C) 2024 Cloud Software Group + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *) + +module Ipq = Xapi_stdext_threads_scheduler.Ipq + +(* test we get "out of bound" exception calling Ipq.remove *) +let test_out_of_index () = + let q = Ipq.create 10 0 in + Ipq.add q {Ipq.ev= 123; Ipq.time= Mtime_clock.now ()} ; + let is_oob = function + | Invalid_argument s when String.ends_with ~suffix:" out of bounds" s -> + true + | _ -> + false + in + let oob_check n = + (Alcotest.match_raises "out of bound" is_oob @@ fun () -> Ipq.remove q n) ; + Alcotest.(check bool) "same value" false (Ipq.is_empty q) + in + oob_check 10 ; + oob_check (-1) ; + oob_check 9 ; + oob_check 1 ; + (* this should succeed *) + Ipq.remove q 0 + +(* check queue does not retain some data after being removed *) +let test_leak () = + let default () = () in + let q = Ipq.create 10 default in + let array = Array.make 1024 'x' in + let use_array () = array.(0) <- 'a' in + let allocated = Atomic.make true in + Gc.finalise (fun _ -> Atomic.set allocated false) array ; + Ipq.add q {Ipq.ev= use_array; Ipq.time= Mtime_clock.now ()} ; + Ipq.remove q 0 ; + Gc.full_major () ; + Gc.full_major () ; + Alcotest.(check bool) "allocated" false (Atomic.get allocated) ; + Ipq.add q {Ipq.ev= default; Ipq.time= Mtime_clock.now ()} + +(* test Ipq.is_empty call *) +let test_empty () = + let q = Ipq.create 10 0 in + Alcotest.(check bool) "same value" true (Ipq.is_empty q) ; + Ipq.add q {Ipq.ev= 123; Ipq.time= Mtime_clock.now ()} ; + Alcotest.(check bool) "same value" false (Ipq.is_empty q) ; + Ipq.remove q 0 ; + Alcotest.(check bool) "same value" true (Ipq.is_empty q) + +module Int64Set = Set.Make (Int64) + +let check = Ipq.check + +(* get size of the queue *) +let size queue = + let l = ref 0 in + Ipq.iter (fun _ -> l := !l + 1) queue ; + !l + +(* get a set of times from the queue *) +let set queue = + let s = ref Int64Set.empty in + Ipq.iter + (fun d -> + let t = d.time in + let t = Mtime.to_uint64_ns t in + s := Int64Set.add t !s + ) + queue ; + !s + +let test_old () = + let test : int Ipq.t = Ipq.create 100 0 in + let s = ref Int64Set.empty in + let add i = + let ti = Random.int64 1000000L in + let t = Mtime.of_uint64_ns ti in + let e = {Ipq.time= t; Ipq.ev= i} in + Ipq.add test e ; + s := Int64Set.add ti !s + in + for i = 0 to 49 do + add i + done ; + let first_half = set test in + for i = 50 to 99 do + add i + done ; + check test ; + (* we should have all elements *) + Alcotest.(check int) "100 elements" 100 (size test) ; + + let all = set test in + Alcotest.(check int) "same list" 0 (Int64Set.compare !s all) ; + + (* remove half of the elements *) + for i = 0 to 49 do + let xx = Ipq.find test i in + Printf.printf "Removing element %d position %d\n%!" i xx ; + Ipq.remove test xx ; + check test + done ; + Alcotest.(check int) "50 elements" 50 (size test) ; + + (* make sure we have the right elements in the list *) + let s = set test in + let second_half = Int64Set.diff all first_half in + Alcotest.(check int) "same list" 0 (Int64Set.compare s second_half) ; + + (* remove test *) + let prev = ref 0L in + for _ = 0 to 49 do + let e = Ipq.pop_maximum test in + let t = Mtime.to_uint64_ns e.time in + Alcotest.(check bool) + (Printf.sprintf "%Ld bigger than %Ld" t !prev) + true (t >= !prev) ; + Printf.printf "time: %Ld, site: %d\n" t e.ev ; + prev := t ; + check test + done + +let tests = + [ + ("test_out_of_index", `Quick, test_out_of_index) + ; ("test_leak", `Quick, test_leak) + ; ("test_empty", `Quick, test_empty) + ; ("test_old", `Quick, test_old) + ] + +let () = Alcotest.run "Ipq" [("generic", tests)] diff --git a/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq_test.mli b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/ipq_test.mli new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ocaml/xapi/xapi_periodic_scheduler.ml b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/scheduler.ml similarity index 82% rename from ocaml/xapi/xapi_periodic_scheduler.ml rename to ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/scheduler.ml index 1edcb938857..3e8543ec04d 100644 --- a/ocaml/xapi/xapi_periodic_scheduler.ml +++ b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/scheduler.ml @@ -12,7 +12,7 @@ * GNU Lesser General Public License for more details. *) -module D = Debug.Make (struct let name = "backgroundscheduler" end) +module D = Debug.Make (struct let name = __MODULE__ end) open D module Delay = Xapi_stdext_threads.Threadext.Delay @@ -25,21 +25,27 @@ type t = {func: unit -> unit; ty: func_ty; name: string} let delay = Delay.make () -let (queue : t Ipq.t) = Ipq.create 50 +let queue_default = {func= (fun () -> ()); ty= OneShot; name= ""} + +let (queue : t Ipq.t) = Ipq.create 50 queue_default let lock = Mutex.create () module Clock = struct - (** time span of s seconds *) let span s = Mtime.Span.of_uint64_ns (Int64.of_float (s *. 1e9)) + let span_to_s span = + Mtime.Span.to_uint64_ns span |> Int64.to_float |> fun ns -> ns /. 1e9 + let add_span clock secs = + (* return mix or max available value if the add overflows *) match Mtime.add_span clock (span secs) with | Some t -> t + | None when secs > 0. -> + Mtime.max_stamp | None -> - raise - Api_errors.(Server_error (internal_error, ["clock overflow"; __LOC__])) + Mtime.min_stamp end let add_to_queue ?(signal = true) name ty start newfunc = @@ -59,7 +65,7 @@ let remove_from_queue name = Ipq.remove queue index let loop () = - debug "Periodic scheduler started" ; + debug "%s started" __MODULE__ ; try while true do let empty = with_lock lock (fun () -> Ipq.is_empty queue) in @@ -82,8 +88,8 @@ let loop () = ) else (* Sleep until next event. *) let sleep = Mtime.(span next.Ipq.time now) - |> Mtime.Span.add (Clock.span 0.001) - |> Scheduler.span_to_s + |> Mtime.Span.(add ms) + |> Clock.span_to_s in try ignore (Delay.wait delay sleep) with e -> @@ -102,5 +108,5 @@ let loop () = done with _ -> error - "Periodic scheduler died! Xapi will no longer function well and should \ - be restarted." + "Scheduler thread died! This daemon will no longer function well and \ + should be restarted." diff --git a/ocaml/xapi/xapi_periodic_scheduler.mli b/ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/scheduler.mli similarity index 100% rename from ocaml/xapi/xapi_periodic_scheduler.mli rename to ocaml/libs/xapi-stdext/lib/xapi-stdext-threads/scheduler.mli diff --git a/ocaml/tests/common/dune b/ocaml/tests/common/dune index c578f5f9785..29acca3d2cb 100644 --- a/ocaml/tests/common/dune +++ b/ocaml/tests/common/dune @@ -26,6 +26,7 @@ xapi-test-utils xapi-types xapi-stdext-date + xapi-stdext-threads.scheduler xapi-stdext-unix ) ) diff --git a/ocaml/tests/common/test_event_common.ml b/ocaml/tests/common/test_event_common.ml index 149a27d5ea8..9d37c038ab4 100644 --- a/ocaml/tests/common/test_event_common.ml +++ b/ocaml/tests/common/test_event_common.ml @@ -2,16 +2,16 @@ let ps_start = ref false let scheduler_mutex = Mutex.create () +module Scheduler = Xapi_stdext_threads_scheduler.Scheduler + let start_periodic_scheduler () = Mutex.lock scheduler_mutex ; if !ps_start then () else ( - Xapi_periodic_scheduler.add_to_queue "dummy" - (Xapi_periodic_scheduler.Periodic 60.0) 0.0 (fun () -> () - ) ; + Scheduler.add_to_queue "dummy" (Scheduler.Periodic 60.0) 0.0 (fun () -> ()) ; Xapi_event.register_hooks () ; - ignore (Thread.create Xapi_periodic_scheduler.loop ()) ; + ignore (Thread.create Scheduler.loop ()) ; ps_start := true ) ; Mutex.unlock scheduler_mutex diff --git a/ocaml/xapi/dune b/ocaml/xapi/dune index 5602e62d152..d2e2fb17de8 100644 --- a/ocaml/xapi/dune +++ b/ocaml/xapi/dune @@ -196,6 +196,7 @@ xapi-stdext-pervasives xapi-stdext-std xapi-stdext-threads + xapi-stdext-threads.scheduler xapi-stdext-unix xapi-stdext-zerocheck xapi-tracing @@ -256,6 +257,7 @@ xapi-stdext-pervasives xapi-stdext-std xapi-stdext-threads + xapi-stdext-threads.scheduler xapi-stdext-unix xapi-types xapi_aux diff --git a/ocaml/xapi/extauth_plugin_ADwinbind.ml b/ocaml/xapi/extauth_plugin_ADwinbind.ml index fc0aa01ad0b..6f51eea9cc5 100644 --- a/ocaml/xapi/extauth_plugin_ADwinbind.ml +++ b/ocaml/xapi/extauth_plugin_ADwinbind.ml @@ -22,6 +22,7 @@ end) open D open Xapi_stdext_std.Xstringext open Auth_signature +module Scheduler = Xapi_stdext_threads_scheduler.Scheduler let finally = Xapi_stdext_pervasives.Pervasiveext.finally @@ -1172,16 +1173,14 @@ module ClosestKdc = struct let trigger_update ~start = if Pool_role.is_master () then ( debug "Trigger task: %s" periodic_update_task_name ; - Xapi_periodic_scheduler.add_to_queue periodic_update_task_name - (Xapi_periodic_scheduler.Periodic - !Xapi_globs.winbind_update_closest_kdc_interval - ) + Scheduler.add_to_queue periodic_update_task_name + (Scheduler.Periodic !Xapi_globs.winbind_update_closest_kdc_interval) start update ) let stop_update () = if Pool_role.is_master () then - Xapi_periodic_scheduler.remove_from_queue periodic_update_task_name + Scheduler.remove_from_queue periodic_update_task_name end module RotateMachinePassword = struct @@ -1302,11 +1301,10 @@ module RotateMachinePassword = struct let trigger_rotate ~start = debug "Trigger task: %s" task_name ; - Xapi_periodic_scheduler.add_to_queue task_name - (Xapi_periodic_scheduler.Periodic !Xapi_globs.winbind_machine_pwd_timeout) - start rotate + Scheduler.add_to_queue task_name + (Scheduler.Periodic !Xapi_globs.winbind_machine_pwd_timeout) start rotate - let stop_rotate () = Xapi_periodic_scheduler.remove_from_queue task_name + let stop_rotate () = Scheduler.remove_from_queue task_name end let build_netbios_name ~config_params = diff --git a/ocaml/xapi/helpers.ml b/ocaml/xapi/helpers.ml index 8c2f91fc2a3..68368754e72 100644 --- a/ocaml/xapi/helpers.ml +++ b/ocaml/xapi/helpers.ml @@ -443,8 +443,9 @@ let make_timeboxed_rpc ~__context timeout rpc : Rpc.response = in List.iter Locking_helpers.kill_resource resources in - Xapi_periodic_scheduler.add_to_queue (Ref.string_of task_id) - Xapi_periodic_scheduler.OneShot timeout cancel ; + let module Scheduler = Xapi_stdext_threads_scheduler.Scheduler in + Scheduler.add_to_queue (Ref.string_of task_id) Scheduler.OneShot timeout + cancel ; let transport = if Pool_role.is_master () then Unix Xapi_globs.unix_domain_socket @@ -459,7 +460,7 @@ let make_timeboxed_rpc ~__context timeout rpc : Rpc.response = let result = XMLRPC_protocol.rpc ~srcstr:"xapi" ~dststr:"xapi" ~transport ~http rpc in - Xapi_periodic_scheduler.remove_from_queue (Ref.string_of task_id) ; + Scheduler.remove_from_queue (Ref.string_of task_id) ; result ) diff --git a/ocaml/xapi/pool_periodic_update_sync.ml b/ocaml/xapi/pool_periodic_update_sync.ml index 45aacf82a9c..a9755d0cf1e 100644 --- a/ocaml/xapi/pool_periodic_update_sync.ml +++ b/ocaml/xapi/pool_periodic_update_sync.ml @@ -16,6 +16,7 @@ module D = Debug.Make (struct let name = __MODULE__ end) open D open Client +module Scheduler = Xapi_stdext_threads_scheduler.Scheduler type frequency = Daily | Weekly of int @@ -162,12 +163,11 @@ let rec update_sync () = ) and add_to_queue ~__context () = - let open Xapi_periodic_scheduler in - add_to_queue periodic_update_sync_task_name OneShot + Scheduler.add_to_queue periodic_update_sync_task_name Scheduler.OneShot (seconds_until_next_schedule ~__context) update_sync let set_enabled ~__context ~value = - Xapi_periodic_scheduler.remove_from_queue periodic_update_sync_task_name ; + Scheduler.remove_from_queue periodic_update_sync_task_name ; if value then add_to_queue ~__context () diff --git a/ocaml/xapi/xapi.ml b/ocaml/xapi/xapi.ml index ca87e740efb..fd5c0650266 100644 --- a/ocaml/xapi/xapi.ml +++ b/ocaml/xapi/xapi.ml @@ -1114,7 +1114,7 @@ let server_init () = ) ; ( "Starting periodic scheduler" , [Startup.OnThread] - , Xapi_periodic_scheduler.loop + , Xapi_stdext_threads_scheduler.Scheduler.loop ) ; ( "Synchronising host configuration files" , [] diff --git a/ocaml/xapi/xapi_event.ml b/ocaml/xapi/xapi_event.ml index 8c7432106ab..600d2859dd3 100644 --- a/ocaml/xapi/xapi_event.ml +++ b/ocaml/xapi/xapi_event.ml @@ -425,12 +425,12 @@ module From = struct && (not (session_is_invalid call)) && Unix.gettimeofday () < deadline do - Xapi_periodic_scheduler.add_to_queue timeoutname - Xapi_periodic_scheduler.OneShot + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue timeoutname + Xapi_stdext_threads_scheduler.Scheduler.OneShot (deadline -. Unix.gettimeofday () +. 0.5) (fun () -> Condition.broadcast c) ; Condition.wait c m ; - Xapi_periodic_scheduler.remove_from_queue timeoutname + Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue timeoutname done ) ; if session_is_invalid call then ( diff --git a/ocaml/xapi/xapi_host.ml b/ocaml/xapi/xapi_host.ml index 46e06a9b4d7..cd6ae3a7d35 100644 --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -938,12 +938,12 @@ let ask_host_if_it_is_a_slave ~__context ~host = "ask_host_if_it_is_a_slave: host taking a long time to respond - IP: \ %s; uuid: %s" ip uuid ; - Xapi_periodic_scheduler.add_to_queue task_name - Xapi_periodic_scheduler.OneShot timeout + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue task_name + Xapi_stdext_threads_scheduler.Scheduler.OneShot timeout (log_host_slow_to_respond (min (2. *. timeout) 300.)) in - Xapi_periodic_scheduler.add_to_queue task_name - Xapi_periodic_scheduler.OneShot timeout + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue task_name + Xapi_stdext_threads_scheduler.Scheduler.OneShot timeout (log_host_slow_to_respond timeout) ; let res = Message_forwarding.do_op_on_localsession_nolivecheck ~local_fn ~__context @@ -951,7 +951,7 @@ let ask_host_if_it_is_a_slave ~__context ~host = Client.Client.Pool.is_slave ~rpc ~session_id ~host ) in - Xapi_periodic_scheduler.remove_from_queue task_name ; + Xapi_stdext_threads_scheduler.Scheduler.remove_from_queue task_name ; res in Server_helpers.exec_with_subtask ~__context "host.ask_host_if_it_is_a_slave" @@ -1497,8 +1497,8 @@ let sync_data ~__context ~host = Xapi_sync.sync_host ~__context host (* Nb, no attempt to wrap exceptions yet *) let backup_rrds ~__context ~host:_ ~delay = - Xapi_periodic_scheduler.add_to_queue "RRD backup" - Xapi_periodic_scheduler.OneShot delay (fun _ -> + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "RRD backup" + Xapi_stdext_threads_scheduler.Scheduler.OneShot delay (fun _ -> let master_address = Pool_role.get_master_address_opt () in log_and_ignore_exn (Rrdd.backup_rrds master_address) ; log_and_ignore_exn (fun () -> diff --git a/ocaml/xapi/xapi_periodic_scheduler_init.ml b/ocaml/xapi/xapi_periodic_scheduler_init.ml index d74b349e240..39866292460 100644 --- a/ocaml/xapi/xapi_periodic_scheduler_init.ml +++ b/ocaml/xapi/xapi_periodic_scheduler_init.ml @@ -76,46 +76,53 @@ let register ~__context = let update_all_subjects_delay = 10.0 in (* initial delay = 10 seconds *) if master then - Xapi_periodic_scheduler.add_to_queue "Synchronising RRDs/messages" - (Xapi_periodic_scheduler.Periodic sync_timer) sync_delay sync_func ; + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue + "Synchronising RRDs/messages" + (Xapi_stdext_threads_scheduler.Scheduler.Periodic sync_timer) sync_delay + sync_func ; if master then - Xapi_periodic_scheduler.add_to_queue "Backing up RRDs" - (Xapi_periodic_scheduler.Periodic rrdbackup_timer) rrdbackup_delay - rrdbackup_func ; + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "Backing up RRDs" + (Xapi_stdext_threads_scheduler.Scheduler.Periodic rrdbackup_timer) + rrdbackup_delay rrdbackup_func ; if master then - Xapi_periodic_scheduler.add_to_queue + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "Revalidating externally-authenticated sessions" - (Xapi_periodic_scheduler.Periodic + (Xapi_stdext_threads_scheduler.Scheduler.Periodic !Xapi_globs.session_revalidation_interval - ) session_revalidation_delay session_revalidation_func ; + ) + session_revalidation_delay session_revalidation_func ; if master then - Xapi_periodic_scheduler.add_to_queue + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "Trying to update subjects' info using external directory service (if \ any)" - (Xapi_periodic_scheduler.Periodic !Xapi_globs.update_all_subjects_interval) + (Xapi_stdext_threads_scheduler.Scheduler.Periodic + !Xapi_globs.update_all_subjects_interval + ) update_all_subjects_delay update_all_subjects_func ; - Xapi_periodic_scheduler.add_to_queue "Periodic scheduler heartbeat" - (Xapi_periodic_scheduler.Periodic hb_timer) 240.0 hb_func ; - Xapi_periodic_scheduler.add_to_queue "Update monitor configuration" - (Xapi_periodic_scheduler.Periodic 3600.0) 3600.0 + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue + "Periodic scheduler heartbeat" + (Xapi_stdext_threads_scheduler.Scheduler.Periodic hb_timer) 240.0 hb_func ; + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue + "Update monitor configuration" + (Xapi_stdext_threads_scheduler.Scheduler.Periodic 3600.0) 3600.0 Monitor_master.update_configuration_from_master ; ( if master then let freq = !Xapi_globs.failed_login_alert_freq |> float_of_int in - Xapi_periodic_scheduler.add_to_queue + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "Periodic alert failed login attempts" - (Xapi_periodic_scheduler.Periodic freq) freq + (Xapi_stdext_threads_scheduler.Scheduler.Periodic freq) freq Xapi_pool.alert_failed_login_attempts ) ; - Xapi_periodic_scheduler.add_to_queue "broken_kernel" - (Xapi_periodic_scheduler.Periodic 600.) 600. (fun () -> + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "broken_kernel" + (Xapi_stdext_threads_scheduler.Scheduler.Periodic 600.) 600. (fun () -> Server_helpers.exec_with_new_task "Periodic alert if the running kernel is broken in some serious way." (fun __context -> Xapi_host.alert_if_kernel_broken ~__context ) ) ; - Xapi_periodic_scheduler.add_to_queue + Xapi_stdext_threads_scheduler.Scheduler.add_to_queue "Period alert if TLS verification emergency disabled" - (Xapi_periodic_scheduler.Periodic 600.) 600. (fun () -> + (Xapi_stdext_threads_scheduler.Scheduler.Periodic 600.) 600. (fun () -> Server_helpers.exec_with_new_task "Period alert if TLS verification emergency disabled" (fun __context -> Xapi_host.alert_if_tls_verification_was_emergency_disabled ~__context diff --git a/quality-gate.sh b/quality-gate.sh index b1d170041f1..b72ca099aa7 100755 --- a/quality-gate.sh +++ b/quality-gate.sh @@ -25,7 +25,7 @@ verify-cert () { } mli-files () { - N=498 + N=497 # do not count ml files from the tests in ocaml/{tests/perftest/quicktest} MLIS=$(git ls-files -- '**/*.mli' | grep -vE "ocaml/tests|ocaml/perftest|ocaml/quicktest|ocaml/message-switch/core_test" | xargs -I {} sh -c "echo {} | cut -f 1 -d '.'" \;) MLS=$(git ls-files -- '**/*.ml' | grep -vE "ocaml/tests|ocaml/perftest|ocaml/quicktest|ocaml/message-switch/core_test" | xargs -I {} sh -c "echo {} | cut -f 1 -d '.'" \;)