Skip to content

Commit 478f499

Browse files
committed
Eliminate redundant Describe call and add ErrFunctionNotFound
Move the "not found" error detection from the controller into funccli.Describe as a typed ErrFunctionNotFound sentinel error. Pass the initial Describe result through to checkMiddlewareState, removing one Describe roundtrip per reconcile.
1 parent f51177a commit 478f499

2 files changed

Lines changed: 16 additions & 29 deletions

File tree

internal/controller/function_controller.go

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controller
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"strconv"
2324
"strings"
@@ -218,17 +219,16 @@ func (r *FunctionReconciler) reconcileDeployment(ctx context.Context, function *
218219
logger := log.FromContext(ctx)
219220
logger.Info("Reconciling Function")
220221

221-
deployed, err := r.isDeployed(ctx, metadata.Name, function.Namespace)
222-
if err != nil {
223-
function.MarkDeployNotReady("DeployFailed", "Failed to check deployment status: %s", err.Error())
224-
return fmt.Errorf("failed to check if function is already deployed: %w", err)
225-
}
226-
227-
if !deployed {
222+
initialDesc, err := r.FuncCliManager.Describe(ctx, metadata.Name, function.Namespace)
223+
if errors.Is(err, funccli.ErrFunctionNotFound) {
228224
logger.Info("Function is not deployed")
229225
function.MarkDeployNotReady("NotDeployed", "Function not deployed yet")
230226
return nil
231227
}
228+
if err != nil {
229+
function.MarkDeployNotReady("DeployFailed", "Failed to check deployment status: %s", err.Error())
230+
return fmt.Errorf("failed to check if function is already deployed: %w", err)
231+
}
232232

233233
// function is deployed -> update status with metadata information
234234
deployer := metadata.Deploy.Deployer
@@ -241,7 +241,7 @@ func (r *FunctionReconciler) reconcileDeployment(ctx context.Context, function *
241241
applyLastDeployedAnnotation(ctx, function)
242242

243243
// Function is deployed - check middleware version
244-
return r.handleMiddlewareUpdate(ctx, function, repo, metadata)
244+
return r.handleMiddlewareUpdate(ctx, function, repo, metadata, &initialDesc)
245245
}
246246

247247
// middlewareCheck is a sealed interface representing the result of inspecting a function's
@@ -279,12 +279,7 @@ type autoUpdateStatus struct {
279279
source string // "function" or "operator"
280280
}
281281

282-
func (r *FunctionReconciler) checkMiddlewareState(ctx context.Context, function *v1alpha1.Function, metadata *funcfn.Function) (middlewareCheck, error) {
283-
desc, err := r.FuncCliManager.Describe(ctx, metadata.Name, function.Namespace)
284-
if err != nil {
285-
return nil, fmt.Errorf("failed to describe function: %w", err)
286-
}
287-
282+
func (r *FunctionReconciler) checkMiddlewareState(ctx context.Context, function *v1alpha1.Function, metadata *funcfn.Function, desc *funcfn.Instance) (middlewareCheck, error) {
288283
autoUpdate, err := r.getAutoUpdateStatus(ctx, function)
289284
if err != nil {
290285
return nil, fmt.Errorf("failed to check middleware update setting: %w", err)
@@ -326,10 +321,10 @@ func (r *FunctionReconciler) getAutoUpdateStatus(ctx context.Context, function *
326321
}
327322

328323
// handleMiddlewareUpdate checks if the function is using the latest middleware and redeploys if needed
329-
func (r *FunctionReconciler) handleMiddlewareUpdate(ctx context.Context, function *v1alpha1.Function, repo *git.Repository, metadata *funcfn.Function) error {
324+
func (r *FunctionReconciler) handleMiddlewareUpdate(ctx context.Context, function *v1alpha1.Function, repo *git.Repository, metadata *funcfn.Function, desc *funcfn.Instance) error {
330325
logger := log.FromContext(ctx)
331326

332-
check, err := r.checkMiddlewareState(ctx, function, metadata)
327+
check, err := r.checkMiddlewareState(ctx, function, metadata, desc)
333328
if err != nil {
334329
function.MarkMiddlewareNotUpToDate("MiddlewareCheckFailed", "Failed to check middleware: %s", err)
335330
return err
@@ -412,19 +407,6 @@ func markServiceStatus(ready string, function *v1alpha1.Function) {
412407
}
413408
}
414409

415-
func (r *FunctionReconciler) isDeployed(ctx context.Context, name, namespace string) (bool, error) {
416-
_, err := r.FuncCliManager.Describe(ctx, name, namespace)
417-
if err != nil {
418-
if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "no describe function") {
419-
return false, nil
420-
}
421-
422-
return false, fmt.Errorf("failed to describe function: %w", err)
423-
}
424-
425-
return true, nil
426-
}
427-
428410
// SetupWithManager sets up the controller with the Manager.
429411
func (r *FunctionReconciler) SetupWithManager(mgr ctrl.Manager) error {
430412
return ctrl.NewControllerManagedBy(mgr).

internal/funccli/manager.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
funcfn "knative.dev/func/pkg/functions"
2121
)
2222

23+
var ErrFunctionNotFound = fmt.Errorf("function not found")
24+
2325
const (
2426
githubAPIURL = "https://api.github.com/repos/knative/func/releases/latest"
2527
defaultCheckInterval = 5 * time.Minute
@@ -190,6 +192,9 @@ func (m *managerImpl) Run(ctx context.Context, dir string, args ...string) (stri
190192
func (m *managerImpl) Describe(ctx context.Context, name, namespace string) (funcfn.Instance, error) {
191193
out, err := m.Run(ctx, "", "describe", "-n", namespace, "-o", "json", name)
192194
if err != nil {
195+
if strings.Contains(err.Error(), "not found") || strings.Contains(err.Error(), "no describe function") {
196+
return funcfn.Instance{}, ErrFunctionNotFound
197+
}
193198
return funcfn.Instance{}, fmt.Errorf("failed to describe function: %q. %w", out, err)
194199
}
195200

0 commit comments

Comments
 (0)