@@ -39,6 +39,20 @@ const (
3939
4040var jobInfoMap sync.Map
4141
42+ // Simple worker pool for job info updates
43+ var jobInfoChan = make (chan func (), 300 ) // Unbuffered channel with unlimited capacity
44+
45+ func init () {
46+ // Start 10 worker goroutines that will live for the entire program
47+ for i := 0 ; i < 100 ; i ++ {
48+ go func () {
49+ for task := range jobInfoChan {
50+ task () // Execute the function
51+ }
52+ }()
53+ }
54+ }
55+
4256// RayJobReconciler reconciles a RayJob object
4357type RayJobReconciler struct {
4458 client.Client
@@ -306,7 +320,9 @@ func (r *RayJobReconciler) Reconcile(ctx context.Context, request ctrl.Request)
306320 reason = rayv1 .AppFailed
307321 }
308322 } else {
309- go func () {
323+ // Submit to simple worker pool instead of creating new goroutine
324+ select {
325+ case jobInfoChan <- func () {
310326 rayDashboardClient , err := r .dashboardClientFunc (rayClusterInstance , rayJobInstance .Status .DashboardURL )
311327 if err != nil {
312328 logger .Error (err , "Failed to get Job client" , "JobId" , rayJobInstance .Status .JobId )
@@ -318,7 +334,12 @@ func (r *RayJobReconciler) Reconcile(ctx context.Context, request ctrl.Request)
318334 return
319335 }
320336 jobInfoMap .Store (rayJobInstance .Name , * jobInfo )
321- }()
337+ }:
338+ // Task submitted successfully
339+ default :
340+ // Channel full, skip this update
341+ logger .V (1 ).Info ("Worker pool busy, skipping job info update" )
342+ }
322343 }
323344
324345 // Always update RayClusterStatus along with JobStatus and JobDeploymentStatus updates.
0 commit comments