Skip to content

Commit 196f4e9

Browse files
author
Colin James
committed
Remove mutable last_generation from Xapi_event
In event accumulation for event.from, the code uses a mutable variable to thread a value through event accumulation. However, this value itself is accumulated in the fold: it gets larger for each matching database event that matches a subscription. To avoid the complexity in effectively having a global, mutable variable, we drop it and make it more evident when it changes: it is changed when no events are accumulated (by grab_range). In the case that no events are accumulated, but the deadline hasn't been reached, the code tries to collect events again. It is during a retry that the last_generation needs to be bumped, as it defines the starting point by which to query the database for recent and deleted objects. In short, if no suitable events were gleaned from matching database object records since a given point, there's no point starting from there again. Signed-off-by: Colin James <[email protected]>
1 parent 30308b6 commit 196f4e9

File tree

1 file changed

+17
-19
lines changed

1 file changed

+17
-19
lines changed

ocaml/xapi/xapi_event.ml

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -543,13 +543,13 @@ let collect_events subs tables last_generation acc table =
543543
if Subscription.object_matches subs table obj then
544544
let last = max last (max modified deleted) in
545545
let creates =
546-
if created > !last_generation then
546+
if created > last_generation then
547547
(table, obj, created) :: creates
548548
else
549549
creates
550550
in
551551
let mods =
552-
if modified > !last_generation && not (created > !last_generation) then
552+
if modified > last_generation && not (created > last_generation) then
553553
(table, obj, modified) :: mods
554554
else
555555
mods
@@ -563,7 +563,7 @@ let collect_events subs tables last_generation acc table =
563563
if Subscription.object_matches subs table obj then
564564
let last = max last (max modified deleted) in
565565
let deletes =
566-
if created <= !last_generation then
566+
if created <= last_generation then
567567
(table, obj, deleted) :: deletes
568568
else
569569
deletes
@@ -573,8 +573,8 @@ let collect_events subs tables last_generation acc table =
573573
entries
574574
in
575575
acc
576-
|> Table.fold_over_recent !last_generation prepend_recent table_value
577-
|> Table.fold_over_deleted !last_generation prepend_deleted table_value
576+
|> Table.fold_over_recent last_generation prepend_recent table_value
577+
|> Table.fold_over_deleted last_generation prepend_deleted table_value
578578

579579
let from_inner __context session subs from from_t timer batching =
580580
let open Xapi_database in
@@ -592,9 +592,8 @@ let from_inner __context session subs from from_t timer batching =
592592
in
593593
List.filter (fun table -> Subscription.table_matches subs table) all
594594
in
595-
let last_generation = ref from in
596595
let last_msg_gen = ref from_t in
597-
let grab_range t =
596+
let grab_range ~since t =
598597
let tableset = Db_cache_types.Database.tableset (Db_ref.get_database t) in
599598
let msg_gen, messages =
600599
if Subscription.table_matches subs "message" then
@@ -603,10 +602,8 @@ let from_inner __context session subs from from_t timer batching =
603602
(0L, [])
604603
in
605604
let events =
606-
let initial =
607-
{creates= []; mods= []; deletes= []; last= !last_generation}
608-
in
609-
let folder = collect_events subs tableset last_generation in
605+
let initial = {creates= []; mods= []; deletes= []; last= since} in
606+
let folder = collect_events subs tableset since in
610607
List.fold_left folder initial tables
611608
in
612609
(msg_gen, messages, tableset, events)
@@ -615,9 +612,9 @@ let from_inner __context session subs from from_t timer batching =
615612
let msg_gen, messages, tableset, events =
616613
with_call session subs (fun sub ->
617614
let grab_nonempty_range =
618-
Throttle.Batching.with_recursive_loop batching @@ fun self arg ->
615+
Throttle.Batching.with_recursive_loop batching @@ fun self since ->
619616
let result =
620-
Db_lock.with_lock (fun () -> grab_range (Db_backend.make ()))
617+
Db_lock.with_lock (fun () -> grab_range ~since (Db_backend.make ()))
621618
in
622619
let msg_gen, messages, _tables, events = result in
623620
let {creates; mods; deletes; last} = events in
@@ -628,21 +625,22 @@ let from_inner __context session subs from from_t timer batching =
628625
&& messages = []
629626
&& not (Clock.Timer.has_expired timer)
630627
then (
631-
last_generation := last ;
632-
(* Cur_id was bumped, but nothing relevent fell out of the db. Therefore the *)
628+
(* cur_id was bumped, but nothing relevent fell out of the database.
629+
Therefore the last ID the client got is equivalent to the current one. *)
633630
sub.cur_id <- last ;
634-
(* last id the client got is equivalent to the current one *)
635631
last_msg_gen := msg_gen ;
636632
wait2 sub last timer ;
637-
(self [@tailcall]) arg
633+
(* The next iteration will fold over events starting after
634+
the last database event that matched a subscription. *)
635+
let next = last in
636+
(self [@tailcall]) next
638637
) else
639638
result
640639
in
641-
grab_nonempty_range ()
640+
grab_nonempty_range from
642641
)
643642
in
644643
let {creates; mods; deletes; last} = events in
645-
last_generation := last ;
646644
let event_of op ?snapshot (table, objref, time) =
647645
{
648646
id= Int64.to_string time

0 commit comments

Comments
 (0)