github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/indexer/requeuer.go (about) 1 package indexer 2 3 import ( 4 "context" 5 "sync" 6 "time" 7 8 "k8s.io/apimachinery/pkg/types" 9 "k8s.io/client-go/util/workqueue" 10 "sigs.k8s.io/controller-runtime/pkg/reconcile" 11 "sigs.k8s.io/controller-runtime/pkg/source" 12 ) 13 14 // Small helper class for triggering a Reconcile() from a goroutine. 15 type Requeuer struct { 16 mu sync.Mutex 17 q workqueue.RateLimitingInterface 18 } 19 20 var _ source.Source = &Requeuer{} 21 22 func NewRequeuer() *Requeuer { 23 return &Requeuer{} 24 } 25 26 func (s *Requeuer) Start(ctx context.Context, q workqueue.RateLimitingInterface) error { 27 s.mu.Lock() 28 defer s.mu.Unlock() 29 s.q = q 30 return nil 31 } 32 33 func (s *Requeuer) Add(nn types.NamespacedName) { 34 s.mu.Lock() 35 defer s.mu.Unlock() 36 if s.q != nil { 37 s.q.Add(reconcile.Request{ 38 NamespacedName: nn, 39 }) 40 } 41 } 42 43 type RequeueForTestResult struct { 44 ObjName types.NamespacedName 45 Error error 46 Result reconcile.Result 47 } 48 49 func StartSourceForTesting( 50 ctx context.Context, 51 s source.Source, 52 reconciler reconcile.Reconciler, 53 resultChan chan RequeueForTestResult, 54 ) { 55 q := workqueue.NewRateLimitingQueue( 56 workqueue.NewItemExponentialFailureRateLimiter(time.Millisecond, time.Millisecond)) 57 _ = s.Start(ctx, q) 58 59 go func() { 60 for ctx.Err() == nil { 61 next, shutdown := q.Get() 62 if shutdown { 63 return 64 } 65 66 req := next.(reconcile.Request) 67 res, err := reconciler.Reconcile(ctx, req) 68 if resultChan != nil { 69 result := RequeueForTestResult{ 70 ObjName: req.NamespacedName, 71 Error: err, 72 Result: res, 73 } 74 resultChan <- result 75 } 76 77 q.Done(next) 78 } 79 }() 80 }