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