@@ -387,7 +387,7 @@ func (s *ServiceReconciler) Poll(ctx context.Context) error {
387387 logger .V (4 ).Info ("enqueueing update for" , "service" , svc .Node .ID )
388388 s .svcCache .Add (svc .Node .ID , svc .Node )
389389 currentServices .Add (svc .Node .Name )
390- s .svcQueue .AddAfter (svc .Node .ID , utils .Jitter (15 * time . Second ))
390+ s .svcQueue .AddAfter (svc .Node .ID , utils .Jitter (s . pollJitterWindow () ))
391391 }
392392 }
393393
@@ -489,6 +489,11 @@ func (s *ServiceReconciler) Reconcile(ctx context.Context, id string) (result re
489489 dir , err := s .manifestCache .Fetch (svc )
490490 if err != nil {
491491 logger .Error (err , "failed to parse manifests" , "service" , svc .Name )
492+ if isRateLimitError (err ) {
493+ // The manifest fetcher already retries 429s; do not add a second workqueue backoff loop.
494+ done = true
495+ return ctrl.Result {}, nil
496+ }
492497 if isExpectedError (err ) {
493498 // mark as the expected error so that it won't get propagated to the API as a service error
494499 err = plrlerrors .ErrExpected
@@ -615,3 +620,16 @@ func isExpectedError(err error) bool {
615620 }
616621 return false
617622}
623+
624+ func isRateLimitError (err error ) bool {
625+ var httpErr * manis.HTTPError
626+ return errors .As (err , & httpErr ) && httpErr .StatusCode == http .StatusTooManyRequests
627+ }
628+
629+ func (s * ServiceReconciler ) pollJitterWindow () time.Duration {
630+ interval := s .GetPollInterval ()()
631+ if interval <= 0 {
632+ return 15 * time .Second
633+ }
634+ return interval / 2
635+ }
0 commit comments