Skip to content

refactor: replace unstructured informers with typed informers in work…#297

Open
klprakhar wants to merge 4 commits intovolcano-sh:mainfrom
klprakhar:refactor/typed-informers-workloadmanager
Open

refactor: replace unstructured informers with typed informers in work…#297
klprakhar wants to merge 4 commits intovolcano-sh:mainfrom
klprakhar:refactor/typed-informers-workloadmanager

Conversation

@klprakhar
Copy link
Copy Markdown

What type of PR is this?
/kind cleanup

What this PR does / why we need it:
This PR refactors the workloadmanager to use typed informers and listers instead of generic unstructured dynamic informers for AgentRuntime and CodeInterpreter resources.

Key improvements:

  • Type Safety: Replaces manual type assertions with typed code, catching errors at compile-time.
  • Maintainability: Addresses technical debt explicitly marked with TODO(hzxuzhonghu) in the codebase.
  • Cleanliness: Removes boiler-plate code used for unstructured to typed object conversion.
  • Robustness: Implements proper apierrors.IsNotFound checks for resource retrieval.

Special notes for your reviewer:
The refactor covers the initialization of the AgentCube clientset in k8s_client.go, the informer setup in informers.go, and the logic updates in workload_builder.go.

Refactored AgentCube workload manager to use typed informers for improved type safety and maintainability.

Copilot AI review requested due to automatic review settings April 26, 2026 12:34
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

Welcome @klprakhar! It looks like this is your first PR to volcano-sh/agentcube 🎉

…load manager

Signed-off-by: klprakhar <prakharkulshrestha939@gmail.com>
@klprakhar klprakhar force-pushed the refactor/typed-informers-workloadmanager branch from 3908c0f to dc600c6 Compare April 26, 2026 12:35
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

This PR refactors the Workload Manager’s handling of AgentRuntime and CodeInterpreter resources to use typed client-go informers/listers instead of dynamic/unstructured informers, improving type safety and reducing manual conversions.

Changes:

  • Switch AgentRuntime / CodeInterpreter lookups in workload_builder.go to use typed informer listers with apierrors.IsNotFound handling.
  • Add an AgentCube typed clientset + shared informer factory initialization in k8s_client.go.
  • Update the Informers wiring in informers.go to use typed informer interfaces and updated cache sync/run logic.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
pkg/workloadmanager/workload_builder.go Replaces unstructured cache access + conversions with typed lister Get() calls and NotFound mapping.
pkg/workloadmanager/k8s_client.go Initializes the AgentCube typed clientset and informer factory for runtime CRDs.
pkg/workloadmanager/informers.go Switches Informers fields to typed informers and updates run/sync to use .Informer() methods.

Comment on lines 54 to 57
type Informers struct {
AgentRuntimeInformer cache.SharedIndexInformer
CodeInterpreterInformer cache.SharedIndexInformer
AgentRuntimeInformer agentruntimev1alpha1.AgentRuntimeInformer
CodeInterpreterInformer agentruntimev1alpha1.CodeInterpreterInformer
PodInformer cache.SharedIndexInformer
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

Changing Informers.AgentRuntimeInformer / CodeInterpreterInformer from cache.SharedIndexInformer to the typed informer interfaces breaks tests and any code that constructs Informers with fake SharedIndexInformers (e.g. pkg/workloadmanager/informers_test.go currently assigns cache.SharedIndexInformer and will no longer compile). Update tests to use a generated fake AgentCube clientset+SharedInformerFactory or provide small test fakes that implement the typed informer interfaces (exposing Informer() + Lister()).

Copilot uses AI. Check for mistakes.
Comment thread pkg/workloadmanager/workload_builder.go Outdated
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

k8s.io/apimachinery/pkg/runtime is no longer referenced in this file after switching to typed listers. This will cause an unused import compile error; please remove the import (or reintroduce a usage if still needed).

Suggested change
"k8s.io/apimachinery/pkg/runtime"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the workload manager to use typed informers and listers for AgentCube resources, eliminating manual type conversions from unstructured objects. The review feedback suggests improving lifecycle management by incorporating the AgentCube informer factory into the Informers struct and using its Start method to manage informers consistently.

Comment on lines 24 to 29
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/informers"
"k8s.io/client-go/tools/cache"

agentruntimev1alpha1 "github.com/volcano-sh/agentcube/client-go/informers/externalversions/runtime/v1alpha1"
)
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.

medium

To support including the SharedInformerFactory for AgentCube resources in the Informers struct, add the corresponding package to the imports.

Suggested change
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/informers"
"k8s.io/client-go/tools/cache"
agentruntimev1alpha1 "github.com/volcano-sh/agentcube/client-go/informers/externalversions/runtime/v1alpha1"
)
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/informers"
"k8s.io/client-go/tools/cache"
agentcubeinformers "github.com/volcano-sh/agentcube/client-go/informers/externalversions"
agentruntimev1alpha1 "github.com/volcano-sh/agentcube/client-go/informers/externalversions/runtime/v1alpha1"
)

Comment on lines 54 to 67
type Informers struct {
AgentRuntimeInformer cache.SharedIndexInformer
CodeInterpreterInformer cache.SharedIndexInformer
AgentRuntimeInformer agentruntimev1alpha1.AgentRuntimeInformer
CodeInterpreterInformer agentruntimev1alpha1.CodeInterpreterInformer
PodInformer cache.SharedIndexInformer
informerFactory informers.SharedInformerFactory
}

func NewInformers(k8sClient *K8sClient) *Informers {
return &Informers{
AgentRuntimeInformer: k8sClient.dynamicInformer.ForResource(AgentRuntimeGVR).Informer(),
CodeInterpreterInformer: k8sClient.dynamicInformer.ForResource(CodeInterpreterGVR).Informer(),
AgentRuntimeInformer: k8sClient.agentcubeInformer.Runtime().V1alpha1().AgentRuntimes(),
CodeInterpreterInformer: k8sClient.agentcubeInformer.Runtime().V1alpha1().CodeInterpreters(),
PodInformer: k8sClient.podInformer,
informerFactory: k8sClient.informerFactory,
}
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.

medium

It is recommended to include the agentcubeInformer factory in the Informers struct. This allows for more consistent and robust lifecycle management of the informers (e.g., using the factory's Start method) rather than manually running individual informers in goroutines.

type Informers struct {
	AgentRuntimeInformer    agentruntimev1alpha1.AgentRuntimeInformer
	CodeInterpreterInformer agentruntimev1alpha1.CodeInterpreterInformer
	PodInformer             cache.SharedIndexInformer
	informerFactory         informers.SharedInformerFactory
	agentcubeInformer       agentcubeinformers.SharedInformerFactory
}

func NewInformers(k8sClient *K8sClient) *Informers {
	return &Informers{
		AgentRuntimeInformer:    k8sClient.agentcubeInformer.Runtime().V1alpha1().AgentRuntimes(),
		CodeInterpreterInformer: k8sClient.agentcubeInformer.Runtime().V1alpha1().CodeInterpreters(),
		PodInformer:             k8sClient.podInformer,
		informerFactory:         k8sClient.informerFactory,
		agentcubeInformer:       k8sClient.agentcubeInformer,
	}
}

Comment on lines 80 to 84
func (ifm *Informers) run(stopCh <-chan struct{}) {
ifm.informerFactory.Start(stopCh)
go ifm.AgentRuntimeInformer.Run(stopCh)
go ifm.CodeInterpreterInformer.Run(stopCh)
go ifm.AgentRuntimeInformer.Informer().Run(stopCh)
go ifm.CodeInterpreterInformer.Informer().Run(stopCh)
}
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.

medium

Use the agentcubeInformer.Start method to start the informers managed by the AgentCube factory. This is more consistent with how the core informerFactory is handled and avoids manual goroutine management for individual informers.

func (ifm *Informers) run(stopCh <-chan struct{}) {
	ifm.informerFactory.Start(stopCh)
	ifm.agentcubeInformer.Start(stopCh)
}

Signed-off-by: klprakhar <prakharkulshrestha939@gmail.com>
Signed-off-by: klprakhar <prakharkulshrestha939@gmail.com>
Copilot AI review requested due to automatic review settings April 26, 2026 12:54
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

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

@@ -77,18 +82,17 @@ func (ifm *Informers) RunAndWaitForCacheSync(ctx context.Context) error {

func (ifm *Informers) run(stopCh <-chan struct{}) {
ifm.informerFactory.Start(stopCh)
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

agentcubeInformer.Start(stopCh) is called before any AgentCube typed informers are instantiated via .Informer(). In the generated informer code, AgentRuntimes()/CodeInterpreters() are lazy and only register the underlying SharedIndexInformer with the factory when .Informer() (or .Lister()) is invoked; Start() only starts informers already present in the factory map. As a result, the AgentRuntime/CodeInterpreter informers may never be started and waitForCacheSync can time out in production. Instantiate the informers (e.g., call ifm.AgentRuntimeInformer.Informer() and ifm.CodeInterpreterInformer.Informer()) before calling ifm.agentcubeInformer.Start(stopCh) (either in NewInformers or at the top of run).

Suggested change
ifm.informerFactory.Start(stopCh)
ifm.informerFactory.Start(stopCh)
ifm.AgentRuntimeInformer.Informer()
ifm.CodeInterpreterInformer.Informer()

Copilot uses AI. Check for mistakes.
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 26, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 16.12903% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.72%. Comparing base (57f6d84) to head (e197c46).
⚠️ Report is 70 commits behind head on main.

Files with missing lines Patch % Lines
pkg/workloadmanager/k8s_client.go 0.00% 14 Missing ⚠️
pkg/workloadmanager/workload_builder.go 0.00% 9 Missing ⚠️
pkg/workloadmanager/informers.go 62.50% 3 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #297      +/-   ##
==========================================
+ Coverage   43.37%   47.72%   +4.35%     
==========================================
  Files          30       30              
  Lines        2610     2812     +202     
==========================================
+ Hits         1132     1342     +210     
+ Misses       1355     1330      -25     
- Partials      123      140      +17     
Flag Coverage Δ
unittests 47.72% <16.12%> (+4.35%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

// TODO(hzxuzhonghu): make use of typed informer, so we don't need to do type conversion below
runtimeObj, exists, err := informer.CodeInterpreterInformer.GetStore().GetByKey(codeInterpreterKey)
// Use typed informer lister to get CodeInterpreter
codeInterpreterObj, err := informer.CodeInterpreterInformer.Lister().CodeInterpreters(namespace).Get(codeInterpreterName)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we set the warm-pool OwnerReference APIVersion/Kind explicitly instead of reading them from codeInterpreterObj.TypeMeta? Typed informer objects can have empty TypeMeta, and the current E2E run rejects every warm-pool SandboxClaim with empty ownerReferences.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed it. You are right the objects retrieved from typed informers often have empty TypeMeta. I have updated the code to explicitly set the APIVersion and Kind in the OwnerReference using runtimev1alpha1.SchemeGroupVersion and runtimev1alpha1.CodeInterpreterKind constants, ensuring that SandboxClaims are correctly populated and accepted by the API.

Signed-off-by: klprakhar <prakharkulshrestha939@gmail.com>
@klprakhar klprakhar force-pushed the refactor/typed-informers-workloadmanager branch from e197c46 to 34c366d Compare April 28, 2026 10:51
Copilot AI review requested due to automatic review settings April 28, 2026 10:51
@klprakhar
Copy link
Copy Markdown
Author

klprakhar commented Apr 28, 2026

Hi @acsoto, I have fixed the change you mentioned, please let me know if any more tweaks are required happy to resolve them!

The CI is also green and the PR overview by copilot is also good.

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

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Copy link
Copy Markdown
Member

@acsoto acsoto left a comment

Choose a reason for hiding this comment

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

Thanks. LGTM

@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: acsoto
Once this PR has been reviewed and has the lgtm label, please assign yaozengzeng for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Comment on lines +86 to +87
ifm.AgentRuntimeInformer.Informer()
ifm.CodeInterpreterInformer.Informer()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can change these two types to informer

Copy link
Copy Markdown
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

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

Genrally lg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants