@@ -62,9 +62,11 @@ class QueueJobBatch(models.Model):
6262 compute = "_compute_job_count" ,
6363 )
6464
65- def _get_state (self ):
66- self .ensure_one ()
67- job_states = set (self .job_ids .grouped ("state" ).keys ())
65+ def _get_state (self , job_states ):
66+ """Determine the batch state from a set of job states.
67+
68+ :param job_states: set of state strings for all jobs in this batch
69+ """
6870 if all (state in ("done" , "cancelled" , "failed" ) for state in job_states ):
6971 return "finished"
7072 elif {"done" , "started" } & job_states :
@@ -74,8 +76,20 @@ def _get_state(self):
7476 return "pending"
7577
7678 def check_state (self ):
79+ grouped = self .env ["queue.job" ].read_group (
80+ [("job_batch_id" , "in" , self .ids )],
81+ ["job_batch_id" , "state" ],
82+ ["job_batch_id" , "state" ],
83+ lazy = False ,
84+ )
85+ states_by_batch = {}
86+ for g in grouped :
87+ batch_id = g ["job_batch_id" ][0 ]
88+ states_by_batch .setdefault (batch_id , set ()).add (g ["state" ])
89+
7790 for rec in self :
78- if (state := rec ._get_state ()) != rec .state :
91+ job_states = states_by_batch .get (rec .id , set ())
92+ if (state := rec ._get_state (job_states )) != rec .state :
7993 rec .state = state
8094
8195 def set_read (self ):
@@ -101,13 +115,29 @@ def get_new_batch(self, name, **kwargs):
101115
102116 @api .depends ("job_ids.state" )
103117 def _compute_job_count (self ):
118+ grouped = self .env ["queue.job" ].read_group (
119+ [("job_batch_id" , "in" , self .ids )],
120+ ["job_batch_id" , "state" ],
121+ ["job_batch_id" , "state" ],
122+ lazy = False ,
123+ )
124+ counts = {}
125+ for g in grouped :
126+ batch_id = g ["job_batch_id" ][0 ]
127+ counts .setdefault (batch_id , {})
128+ counts [batch_id ][g ["state" ]] = g ["__count" ]
129+
104130 for rec in self :
105- jobs_by_state = rec .job_ids .grouped ("state" )
106- rec .job_count = len (rec .job_ids )
107- rec .failed_job_count = len (jobs_by_state .get ("failed" , []))
108- rec .finished_job_count = len (jobs_by_state .get ("done" , []))
109- rec .completeness = rec .finished_job_count / max (1 , rec .job_count )
110- rec .failed_percentage = rec .failed_job_count / max (1 , rec .job_count )
131+ by_state = counts .get (rec .id , {})
132+ total = sum (by_state .values ())
133+ done = by_state .get ("done" , 0 )
134+ failed = by_state .get ("failed" , 0 )
135+
136+ rec .job_count = total
137+ rec .failed_job_count = failed
138+ rec .finished_job_count = done
139+ rec .completeness = done / max (1 , total )
140+ rec .failed_percentage = failed / max (1 , total )
111141
112142 @api .model
113143 def _to_store_fnames (self ):
0 commit comments