github.com/cilium/statedb@v0.3.2/observable.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package statedb 5 6 import ( 7 "context" 8 9 "github.com/cilium/stream" 10 ) 11 12 // Observable creates an observable from the given table for observing the changes 13 // to the table as a stream of events. 14 // 15 // For high-churn tables it's advisable to apply rate-limiting to the stream to 16 // decrease overhead (stream.Throttle). 17 func Observable[Obj any](db *DB, table Table[Obj]) stream.Observable[Change[Obj]] { 18 return &observable[Obj]{db, table} 19 } 20 21 type observable[Obj any] struct { 22 db *DB 23 table Table[Obj] 24 } 25 26 func (to *observable[Obj]) Observe(ctx context.Context, next func(Change[Obj]), complete func(error)) { 27 go func() { 28 txn := to.db.WriteTxn(to.table) 29 iter, err := to.table.Changes(txn) 30 txn.Commit() 31 if err != nil { 32 complete(err) 33 return 34 } 35 defer complete(nil) 36 37 for { 38 changes, watch := iter.Next(to.db.ReadTxn()) 39 for change := range changes { 40 if ctx.Err() != nil { 41 break 42 } 43 next(change) 44 } 45 select { 46 case <-ctx.Done(): 47 return 48 case <-watch: 49 } 50 } 51 }() 52 }