Skip to content

chore(controller): move action declarations from reconcile to init - #6571

Merged
squakez merged 6 commits into
apache:mainfrom
chaojixinren:6567-review-controller-actions-initialization
Apr 19, 2026
Merged

squakez merged 6 commits into
apache:mainfrom
chaojixinren:6567-review-controller-actions-initialization

Conversation

@chaojixinren

Copy link
Copy Markdown
Contributor

Summary

This PR addresses #6567 by moving controller action declarations from reconcile-time to reconciler initialization.

  • Introduce actionFactory in controller reconcilers and initialize action factories in newReconciler(...)
  • Replace inline []Action{...} declarations in Reconcile(...) with newActions(...) creation
  • Cover all relevant controllers:
    • catalog
    • integration
    • integrationkit
    • integrationplatform
    • pipe
  • Add/extend unit tests to verify:
    • expected action order/types
    • fresh action instances are created on each call
    • synthetic/non-synthetic branching for integration controller

Closes #6567

Test Plan

  • go test ./pkg/controller/integration/ ./pkg/controller/catalog/ ./pkg/controller/integrationkit/ ./pkg/controller/integrationplatform/ ./pkg/controller/pipe/ -run TestNewActions -v
  • go vet ./pkg/controller/integration/ ./pkg/controller/catalog/ ./pkg/controller/integrationkit/ ./pkg/controller/integrationplatform/ ./pkg/controller/pipe/
  • ./bin/golangci-lint run --config .golangci.yml --timeout 5m ./pkg/controller/integration/ ./pkg/controller/catalog/ ./pkg/controller/integrationkit/ ./pkg/controller/integrationplatform/ ./pkg/controller/pipe/

@squakez squakez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the work. However, this is not really changing the dynamic creation of the actions. It really complicates that by generating an additional interface that is not really needed.

What I'd propose is to move the scope of the actions array from the func to the struct instead. In this way we just delegate their creation upon initialization instead of having them recreated at every reconcile loop. The only special case is where we have to filter based on a flag. In that case we can think to have 3 arrays and use the one specific to each flag type.

Keep the catalog controller actions initialized once on the reconciler,
but stop mutating shared action instances with request-scoped logger state
during each reconcile. The client is injected once at action creation time,
while the reconcile-specific logger is now passed through context so the
concurrent catalog controller can safely reuse its action list.

Constraint: catalog-controller runs with MaxConcurrentReconciles enabled
Rejected: recreating actions on every reconcile | goes against the requested initialization-time action setup
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Shared controller actions must not retain per-request mutable state unless they are concurrency-safe
Tested: go test ./pkg/controller/catalog
Tested: go test -race ./pkg/controller/catalog
Tested: go test ./pkg/controller/integration ./pkg/controller/integrationkit ./pkg/controller/pipe
Not-tested: integrationplatform package tests in this environment (missing mvn)
Update the remaining controllers that still stored action factories on the
reconciler and rebuilt action slices during each reconcile. Integration,
integrationkit, integrationplatform, and pipe now keep initialized action
arrays directly on the struct, with integration selecting between the
prebuilt synthetic and non-synthetic lists.

Constraint: reviewer requested initialization-time action setup without an extra factory interface
Rejected: keeping actionFactory on the reconciler | still recreates actions on each reconcile and preserves the unwanted indirection
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When controller actions are intended to be fixed at initialization time, store Action instances directly instead of factories
Tested: go test ./pkg/controller/integration ./pkg/controller/integrationkit ./pkg/controller/pipe
Tested: go test ./pkg/controller/integrationplatform -run TestActions
Tested: go test ./pkg/controller/catalog
Not-tested: full integrationplatform package in this environment (missing mvn)
@chaojixinren

Copy link
Copy Markdown
Contributor Author

Thanks for the work. However, this is not really changing the dynamic creation of the actions. It really complicates that by generating an additional interface that is not really needed.

What I'd propose is to move the scope of the actions array from the func to the struct instead. In this way we just delegate their creation upon initialization instead of having them recreated at every reconcile loop. The only special case is where we have to filter based on a flag. In that case we can think to have 3 arrays and use the one specific to each flag type.

Thanks for the feedback. I aligned the implementation with your suggestion by moving the actions from function scope to the reconciler struct, so they are initialized once instead of being recreated on every reconcile.

For the Integration controller, I handled the flag-specific case by preparing dedicated action arrays for the synthetic and non-synthetic paths and selecting the appropriate one during reconcile.

While doing that, I also fixed a concurrency issue in the catalog controller, where shared action instances could otherwise carry request-scoped mutable state across concurrent reconciliations.

@squakez squakez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This version looks better but it still requires some changes.

Comment thread pkg/controller/catalog/action.go
Comment thread pkg/controller/integration/integration_controller.go Outdated
Comment thread pkg/controller/integration/integration_controller_test.go
Comment thread pkg/controller/integrationkit/integrationkit_controller_test.go Outdated
Comment thread pkg/controller/integrationplatform/integrationplatform_controller_test.go Outdated
Comment thread pkg/controller/pipe/pipe_controller_test.go Outdated
@github-actions

Copy link
Copy Markdown
Contributor

✔️ Unit test coverage report - coverage increased from 62.2% to 62.3% (+0.1%)

…e to init

Move the integration controller's action arrays from function-scoped
variables recreated on every reconcile to struct fields initialized once
at reconciler creation. Use a shared baseActions slice to eliminate
duplication between the synthetic and non-synthetic action lists.

Drop the catalog controller changes from this PR as requested by the
reviewer — any concurrency optimization there will be handled in a
separate PR.

Remove trivial action-type-only tests for integrationkit,
integrationplatform, and pipe controllers that provided no real business
logic coverage. Restore the original integration controller tests
(TestIsIntegrationUpdated, TestReadinessTimestampCalculation,
TestDeploymentTimestampIsSet) that were inadvertently removed.

@squakez squakez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, thanks! I think now it's fine. If you can, please just rename a variable to better define the meaning of those actions. Also, about the Catalog, I think you could also apply only the actions refactoring to be completely consistent with this new pattern.

Comment thread pkg/controller/integration/integration_controller.go Outdated
@github-actions

Copy link
Copy Markdown
Contributor

✔️ Unit test coverage report - coverage increased from 62.2% to 62.3% (+0.1%)

@squakez squakez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff, thanks for the contribution!

@github-actions

Copy link
Copy Markdown
Contributor

✔️ Unit test coverage report - coverage increased from 62.2% to 62.3% (+0.1%)

@squakez
squakez merged commit 17b0157 into apache:main Apr 19, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review controller actions initialization

2 participants