github.com/cilium/statedb@v0.3.2/reconciler/index.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package reconciler 5 6 import ( 7 "context" 8 9 "github.com/cilium/statedb" 10 "github.com/cilium/statedb/index" 11 ) 12 13 // NewStatusIndex creates a status index for a table of reconcilable objects. 14 // This is optional and should be only used when there is a need to often check that all 15 // objects are fully reconciled that outweighs the cost of maintaining a status index. 16 func NewStatusIndex[Obj any](getObjectStatus func(Obj) Status) statedb.Index[Obj, StatusKind] { 17 return statedb.Index[Obj, StatusKind]{ 18 Name: "status", 19 FromObject: func(obj Obj) index.KeySet { 20 return index.NewKeySet(getObjectStatus(obj).Kind.Key()) 21 }, 22 FromKey: StatusKind.Key, 23 Unique: false, 24 } 25 } 26 27 // WaitForReconciliation blocks until all objects have been reconciled or the context 28 // has cancelled. 29 func WaitForReconciliation[Obj any](ctx context.Context, db *statedb.DB, table statedb.Table[Obj], statusIndex statedb.Index[Obj, StatusKind]) error { 30 for { 31 txn := db.ReadTxn() 32 33 // See if there are any pending or error'd objects. 34 _, _, watchPending, okPending := table.GetWatch(txn, statusIndex.Query(StatusKindPending)) 35 _, _, watchError, okError := table.GetWatch(txn, statusIndex.Query(StatusKindError)) 36 if !okPending && !okError { 37 return nil 38 } 39 40 // Wait for updates before checking again. 41 select { 42 case <-ctx.Done(): 43 return ctx.Err() 44 case <-watchPending: 45 case <-watchError: 46 } 47 } 48 }