Skip to content

refactor: split controller.go into focused files by concern#69

Open
bdehamer wants to merge 1 commit intomainfrom
bdehamer/refactor-controller-split
Open

refactor: split controller.go into focused files by concern#69
bdehamer wants to merge 1 commit intomainfrom
bdehamer/refactor-controller-split

Conversation

@bdehamer
Copy link
Copy Markdown
Contributor

@bdehamer bdehamer commented Mar 23, 2026

Summary

Splits the 995-line internal/controller/controller.go into four focused files organized by responsibility. Includes one bug fix; otherwise pure structural refactoring.

New file layout

File Lines Responsibility
controller.go ~195 Types, interfaces, Controller struct, New(), newAPIClient(), Run()
handlers.go ~205 registerEventHandlers(), runWorker(), processNextItem(), startWorkers()
reconcile.go ~450 processEvent(), recordContainer(), getWorkloadRef(), resolveJobWorkload(), workloadActive(), workload existence checks, getCacheKey()
pod.go ~195 createInformerFactory(), getARDeploymentName(), getContainerDigest(), getDeploymentName(), hasSupportedOwner(), isTerminalPhase(), getJobOwnerName(), getDaemonSetName(), getStatefulSetName(), isNumeric(), podToPartialMetadata()
config.go 42 Unchanged

Key changes

  • registerEventHandlers() extracted from New() as a Controller method — the event handler closures now use c.workqueue instead of closing over a local queue variable.
  • newAPIClient() extracted as a package-level helper to isolate API client construction from the controller constructor.
  • startWorkers() extracted from Run() for clarity.

Bug fix

Fixed a pre-existing bug in DeleteFunc where cache.MetaNamespaceKeyFunc(obj) was called on the original obj, which may be a DeletedFinalStateUnknown tombstone. MetaNamespaceKeyFunc cannot extract the key from a tombstone, so delete events were silently dropped in that case. Now derives the key from the extracted pod instead.

Testing

All existing unit and integration tests pass without modification. No test changes needed since all files remain in the same package.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors the Kubernetes deployment-tracker controller by splitting the previous monolithic internal/controller/controller.go into smaller files organized by responsibility, aiming to keep behavior unchanged while improving readability and maintainability.

Changes:

  • Extracted event handler registration and worker lifecycle logic into handlers.go.
  • Extracted reconciliation / posting logic into reconcile.go.
  • Extracted pod/informer helper utilities into pod.go and simplified controller.go to core wiring (New, Run, API client construction).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
internal/controller/controller.go Slimmed down to core types + constructor + API client creation + Run(), delegating handlers/workers elsewhere.
internal/controller/handlers.go New file containing informer event handlers and queue worker processing logic.
internal/controller/reconcile.go New file containing processEvent/recordContainer and caching logic for posts.
internal/controller/pod.go New file containing informer factory creation + pod/container helper functions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 23, 2026

@bdehamer I've opened a new pull request, #70, to work on those changes. Once the pull request is ready, I'll request review from you.

@bdehamer bdehamer marked this pull request as ready for review March 24, 2026 01:57
@bdehamer bdehamer requested a review from a team as a code owner March 24, 2026 01:57
tingx2wang
tingx2wang previously approved these changes Mar 25, 2026
@piceri piceri self-requested a review March 25, 2026 18:13
@ajbeattie
Copy link
Copy Markdown
Contributor

Heads up, I'm probably about to merge this PR: #72

It adds/updates several functions/methods in controller.go, so it will probably have some conflicts with this refactor. I'm not 100% sure whether/how the new stuff will fit into the concept/file split proposed here, but hopefully it either fits or illuminates some other natural separation of functionality that can be further split out 😅

Split the 995-line controller.go into four files organized by responsibility:

- controller.go (~195 lines): types, interfaces, Controller struct, New(), Run()
- handlers.go (~205 lines): event handler registration, worker loop
- reconcile.go (~450 lines): event processing, deployment recording, workload
  resolution, cache existence checks
- pod.go (~195 lines): pod utility functions, informer factory

Extract registerEventHandlers() from New() as a Controller method and
newAPIClient() as a package-level helper to simplify the constructor.

Fix a pre-existing bug in DeleteFunc where MetaNamespaceKeyFunc(obj) was
called on the original obj which may be a DeletedFinalStateUnknown tombstone
(causing silent event drops). Now uses the extracted pod instead.

No other behavioral changes — pure structural refactoring.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@bdehamer bdehamer force-pushed the bdehamer/refactor-controller-split branch from 8130fd7 to b94bde3 Compare March 30, 2026 20:50
Copy link
Copy Markdown
Contributor

@piceri piceri left a comment

Choose a reason for hiding this comment

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

After the changes to support different "workloads", I wonder if having a workload.go file would make sense with the following:

controller.go

  • New()
  • Run()
  • newAPIClient()
  • createInformerFactory()

handlers.go

  • registerEventHandlers()
  • runWorker()
  • startWorkers()
  • processNextItem()
  • isTerminalPhase()

workload.go

  • getWorkloadRef()
  • resolveJobWorkload()
  • workloadActive()
  • deploymentExists()
  • jobExists()
  • daemonSetExists()
  • statefulSetExists()
  • cronJobExists()
  • getDeploymentName()
  • getJobOwnerName()
  • getDaemonSetName()
  • getStatefulSetName()

event.go

  • processEvent()
  • recordContainer()
  • getCacheKey()

pod.go

  • isNumeric()
  • podToPartialMetadata()
  • getARDeploymentName()
  • getContainerDigest()
  • hasSupportedOwner()

Also wondering about event.go instead of reconcile.go. Very open to push back/other opinions

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.

6 participants