@@ -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
@@ -312,7 +326,9 @@ func (r *RayJobReconciler) Reconcile(ctx context.Context, request ctrl.Request)
312326 reason = rayv1 .AppFailed
313327 }
314328 } else {
315- go func () {
329+ // Submit to simple worker pool instead of creating new goroutine
330+ select {
331+ case jobInfoChan <- func () {
316332 rayDashboardClient , err := r .dashboardClientFunc (rayClusterInstance , rayJobInstance .Status .DashboardURL )
317333 if err != nil {
318334 logger .Error (err , "Failed to get Job client" , "JobId" , rayJobInstance .Status .JobId )
@@ -324,7 +340,12 @@ func (r *RayJobReconciler) Reconcile(ctx context.Context, request ctrl.Request)
324340 return
325341 }
326342 jobInfoMap .Store (rayJobInstance .Name , * jobInfo )
327- }()
343+ }:
344+ // Task submitted successfully
345+ default :
346+ // Channel full, skip this update
347+ logger .V (1 ).Info ("Worker pool busy, skipping job info update" )
348+ }
328349 }
329350
330351 // Always update RayClusterStatus along with JobStatus and JobDeploymentStatus updates.
0 commit comments