mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-20 20:46:30 +00:00
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package controller
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/stakater/Reloader/internal/pkg/reload"
|
|
"github.com/stakater/Reloader/internal/pkg/workload"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/client-go/util/retry"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
// UpdateWorkloadWithRetry updates a workload with exponential backoff on conflict.
|
|
// On conflict, it re-fetches the object, re-applies the reload changes, and retries.
|
|
func UpdateWorkloadWithRetry(
|
|
ctx context.Context,
|
|
c client.Client,
|
|
reloadService *reload.Service,
|
|
wl workload.WorkloadAccessor,
|
|
resourceName string,
|
|
resourceType reload.ResourceType,
|
|
namespace string,
|
|
hash string,
|
|
autoReload bool,
|
|
) (bool, error) {
|
|
var updated bool
|
|
isFirstAttempt := true
|
|
|
|
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
|
// On retry, re-fetch the object to get the latest ResourceVersion
|
|
if !isFirstAttempt {
|
|
obj := wl.GetObject()
|
|
key := client.ObjectKeyFromObject(obj)
|
|
if err := c.Get(ctx, key, obj); err != nil {
|
|
if errors.IsNotFound(err) {
|
|
// Object was deleted, nothing to update
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
}
|
|
isFirstAttempt = false
|
|
|
|
// Apply reload changes (this modifies the workload in-place)
|
|
var applyErr error
|
|
updated, applyErr = reloadService.ApplyReload(
|
|
ctx,
|
|
wl,
|
|
resourceName,
|
|
resourceType,
|
|
namespace,
|
|
hash,
|
|
autoReload,
|
|
)
|
|
if applyErr != nil {
|
|
return applyErr
|
|
}
|
|
|
|
if !updated {
|
|
return nil
|
|
}
|
|
|
|
// Attempt update with field ownership
|
|
return c.Update(ctx, wl.GetObject(), client.FieldOwner(FieldManager))
|
|
})
|
|
|
|
return updated, err
|
|
}
|