Skip to content

Commit ab4fdb2

Browse files
committed
feature flag
1 parent c947670 commit ab4fdb2

2 files changed

Lines changed: 17 additions & 10 deletions

File tree

kubelink/config/GlobalConfig.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ type HelmReleaseConfig struct {
2626
RunHelmInstallInAsyncMode bool `env:"RUN_HELM_INSTALL_IN_ASYNC_MODE" envDefault:"false" description:"Run helm install/ upgrade in async mode" deprecated:"false" example:"false"`
2727
ChartWorkingDirectory string `env:"CHART_WORKING_DIRECTORY" envDefault:"/home/devtron/devtroncd/charts/" description:"Helm charts working directory" deprecated:"false" example:"/home/devtron/devtroncd/charts/"`
2828
BuildNodesBatchSize int `env:"BUILD_NODES_BATCH_SIZE" envDefault:"10" description:"Resource tree build nodes parallelism batch size; controls depth-1 worker pool size and the shared semaphore size for all deeper levels" deprecated:"false" example:"10"`
29-
FeatChildChildObjectListingPaginationEnable bool `env:"FEAT_CHILD_OBJECT_LISTING_PAGINATION" envDefault:"true" description:"use pagination in listing all the dependent child objects. use 'CHILD_OBJECT_LISTING_PAGE_SIZE' to set the page size." deprecated:"false" example:"true"`
29+
FeatChildChildObjectListingPaginationEnable bool `env:"FEAT_CHILD_OBJECT_LISTING_PAGINATION" envDefault:"true" description:"use pagination in listing all the dependent child objects. use 'CHILD_OBJECT_LISTING_PAGE_SIZE' to set the page size." deprecated:"false" example:"true"`
30+
FeatAllDepthChildNodeBuildParallelism bool `env:"FEAT_ALL_DEPTH_CHILD_NODE_BUILD_PARALLELISM" envDefault:"false" description:"enable semaphore-bounded parallelism for child node building at all recursion depths (depth-2+); when disabled only depth-1 parallelism via worker pool is active" deprecated:"false" example:"false"`
3031
}
3132

3233
func GetHelmReleaseConfig() (*HelmReleaseConfig, error) {

kubelink/pkg/service/commonHelmService/resourceTreeService.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,22 @@ func sanitizeParentObjects(parentObjects []*client.ObjectIdentifier) []*client.O
7575
func (impl *ResourceTreeServiceImpl) BuildResourceTreeUsingK8s(ctx context.Context, appDetailRequest *client.AppDetailRequest, conf *rest.Config, parentObjects []*client.ObjectIdentifier) (*bean.ResourceTreeResponse, error) {
7676
liveManifests := impl.getLiveManifestsForGVKList(conf, parentObjects)
7777

78-
// shared semaphore limits total concurrent K8s calls for child node building across all recursion depths;
79-
// sized to BuildNodesBatchSize so the combined in-flight calls (parent batch + child sem) stay within safe API server limits
80-
semSize := impl.helmReleaseConfig.BuildNodesBatchSize
81-
if semSize <= 0 {
82-
semSize = 1
78+
// when FeatAllDepthChildNodeBuildParallelism is enabled, create a shared semaphore that bounds
79+
// concurrent K8s calls across all recursion depths (depth-2+); a nil semaphore makes
80+
// buildChildNodesInBatch fall back to the previous depth-1-only parallel behaviour
81+
var sem chan struct{}
82+
if impl.helmReleaseConfig.FeatAllDepthChildNodeBuildParallelism {
83+
semSize := impl.helmReleaseConfig.BuildNodesBatchSize
84+
if semSize <= 0 {
85+
semSize = 1
86+
}
87+
sem = make(chan struct{}, semSize)
8388
}
84-
sem := make(chan struct{}, semSize)
8589

8690
// build resource Nodes
8791
req := NewBuildNodesRequest(NewBuildNodesConfig(conf).
8892
WithReleaseNamespace(appDetailRequest.Namespace).
89-
WithSemaphore(sem)).
93+
WithSemaphore(sem)). // nil when flag is off → depth-2+ falls back to sequential
9094
WithDesiredOrLiveManifests(liveManifests...).
9195
WithBatchWorker(impl.helmReleaseConfig.BuildNodesBatchSize, impl.logger)
9296
buildNodesResponse, err := impl.BuildNodes(req)
@@ -300,8 +304,8 @@ func (impl *ResourceTreeServiceImpl) buildChildNodesWithSemaphore(sem chan struc
300304
// slot acquired — run in a goroutine
301305
wg.Add(1)
302306
go func(r *BuildNodesConfig) {
303-
defer wg.Done()
304-
defer func() { <-sem }() // release slot when done
307+
defer func() { <-sem }() // release slot after wg.Done so the semaphore bound stays tight
308+
defer wg.Done() // signal completion first (LIFO: wg.Done runs before <-sem)
305309
childResp, err := impl.BuildNodes(r)
306310
if err != nil {
307311
impl.logger.Errorw("error in building child Nodes", "ReleaseNamespace", r.ReleaseNamespace, "parentResource", r.ParentResourceRef.GetGvk(), "err", err)
@@ -323,7 +327,9 @@ func (impl *ResourceTreeServiceImpl) buildChildNodesWithSemaphore(sem chan struc
323327
wg.Wait()
324328
return response, err
325329
}
330+
mu.Lock()
326331
response.WithNodes(childResp.Nodes).WithHealthStatusArray(childResp.HealthStatusArray)
332+
mu.Unlock()
327333
}
328334
}
329335
wg.Wait()

0 commit comments

Comments
 (0)