)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0922df9f09111468413176b1e30ef97315ba5d82","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"14779c23_be5de91b","updated":"2026-08-31 09:16:58.000000000","message":"I have a question inline","commit_id":"7117cb743003c598200daaae226e71e0a7d1c763"}],"taskflow/conductors/backends/impl_executor.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0922df9f09111468413176b1e30ef97315ba5d82","unresolved":true,"context_lines":[{"line_number":343,"context_line":"                        self._jobboard.iterjobs(ensure_fresh\u003densure_fresh),"},{"line_number":344,"context_line":"                    )"},{"line_number":345,"context_line":"                    for job in job_it:"},{"line_number":346,"context_line":"                        self._log.debug(\"Trying to claim job: %s\", job)"},{"line_number":347,"context_line":"                        try:"},{"line_number":348,"context_line":"                            self._jobboard.claim(job, self._name)"},{"line_number":349,"context_line":"                        except (excp.UnclaimableJob, excp.NotFound):"},{"line_number":350,"context_line":"                            self._log.debug("},{"line_number":351,"context_line":"                                \"Job already claimed or consumed: %s\", job"},{"line_number":352,"context_line":"                            )"},{"line_number":353,"context_line":"                        else:"},{"line_number":354,"context_line":"                            try:"},{"line_number":355,"context_line":"                                fut \u003d executor.submit(self._dispatch_job, job)"},{"line_number":356,"context_line":"                            except RuntimeError:"},{"line_number":357,"context_line":"                                with excutils.save_and_reraise_exception():"},{"line_number":358,"context_line":"                                    self._log.warn("},{"line_number":359,"context_line":"                                        \"Job dispatch submitting failed: %s\","},{"line_number":360,"context_line":"                                        job,"},{"line_number":361,"context_line":"                                    )"},{"line_number":362,"context_line":"                                    self._try_finish_job(job, False)"},{"line_number":363,"context_line":"                            else:"},{"line_number":364,"context_line":"                                fut.job \u003d job"},{"line_number":365,"context_line":"                                self._dispatched.add(fut)"},{"line_number":366,"context_line":"                                any_dispatched \u003d True"},{"line_number":367,"context_line":"                                fut.add_done_callback("},{"line_number":368,"context_line":"                                    functools.partial(self._on_job_done, job)"},{"line_number":369,"context_line":"                                )"},{"line_number":370,"context_line":"                                total_dispatched \u003d next(dispatch_gen)"},{"line_number":371,"context_line":"                except excp.JobFailure:"},{"line_number":372,"context_line":"                    # A transient job board failure (for example a Redis"},{"line_number":373,"context_line":"                    # Sentinel master failover) can surface while iterating"}],"source_content_type":"text/x-python","patch_set":2,"id":"840dfb97_8920e06c","line":370,"range":{"start_line":346,"start_character":0,"end_line":370,"end_character":69},"updated":"2026-08-31 09:16:58.000000000","message":"There\u0027s already a good deal of error handling here. Is there a reason we can\u0027t extend the existing exception handlers to cover `excp.JobFailure` rather than wrapping the whole loop?","commit_id":"7117cb743003c598200daaae226e71e0a7d1c763"},{"author":{"_account_id":290,"name":"Antony Messerli","email":"antony@mes.ser.li","username":"antonym"},"change_message_id":"fd5fc0c501f111007b6b19d3db7b458f1c792984","unresolved":true,"context_lines":[{"line_number":343,"context_line":"                        self._jobboard.iterjobs(ensure_fresh\u003densure_fresh),"},{"line_number":344,"context_line":"                    )"},{"line_number":345,"context_line":"                    for job in job_it:"},{"line_number":346,"context_line":"                        self._log.debug(\"Trying to claim job: %s\", job)"},{"line_number":347,"context_line":"                        try:"},{"line_number":348,"context_line":"                            self._jobboard.claim(job, self._name)"},{"line_number":349,"context_line":"                        except (excp.UnclaimableJob, excp.NotFound):"},{"line_number":350,"context_line":"                            self._log.debug("},{"line_number":351,"context_line":"                                \"Job already claimed or consumed: %s\", job"},{"line_number":352,"context_line":"                            )"},{"line_number":353,"context_line":"                        else:"},{"line_number":354,"context_line":"                            try:"},{"line_number":355,"context_line":"                                fut \u003d executor.submit(self._dispatch_job, job)"},{"line_number":356,"context_line":"                            except RuntimeError:"},{"line_number":357,"context_line":"                                with excutils.save_and_reraise_exception():"},{"line_number":358,"context_line":"                                    self._log.warn("},{"line_number":359,"context_line":"                                        \"Job dispatch submitting failed: %s\","},{"line_number":360,"context_line":"                                        job,"},{"line_number":361,"context_line":"                                    )"},{"line_number":362,"context_line":"                                    self._try_finish_job(job, False)"},{"line_number":363,"context_line":"                            else:"},{"line_number":364,"context_line":"                                fut.job \u003d job"},{"line_number":365,"context_line":"                                self._dispatched.add(fut)"},{"line_number":366,"context_line":"                                any_dispatched \u003d True"},{"line_number":367,"context_line":"                                fut.add_done_callback("},{"line_number":368,"context_line":"                                    functools.partial(self._on_job_done, job)"},{"line_number":369,"context_line":"                                )"},{"line_number":370,"context_line":"                                total_dispatched \u003d next(dispatch_gen)"},{"line_number":371,"context_line":"                except excp.JobFailure:"},{"line_number":372,"context_line":"                    # A transient job board failure (for example a Redis"},{"line_number":373,"context_line":"                    # Sentinel master failover) can surface while iterating"}],"source_content_type":"text/x-python","patch_set":2,"id":"98147ed7_46ff3a95","line":370,"range":{"start_line":346,"start_character":0,"end_line":370,"end_character":69},"in_reply_to":"840dfb97_8920e06c","updated":"2026-09-03 18:58:44.000000000","message":"No, I don\u0027t think so, the handler at 349 can\u0027t see this one.\n\niterjobs() doesn\u0027t touch the backend. It builds a JobBoardIterator and returns it. The fetch happens later, in __next__, when the for loop asks for the first job. So the ConnectionError from a Redis failover comes out of the for statement itself, a long way from the claim() call. Widening the existing handler leaves the bug open.\n\nThe try does cover a lot of lines, but very little inside it can raise JobFailure. executor.submit\u0027s RuntimeError is re-raised as is, and the max-dispatch StopIteration still gets to the outer handler. _try_finish_job already swallows JobFailure on its own.\n\nIf you want the handler tighter I can pull jobs off with next() in its own try. That costs a second copy of the log call and a loop that has to keep two different StopIterations apart, which is why I went the other way.","commit_id":"7117cb743003c598200daaae226e71e0a7d1c763"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"0922df9f09111468413176b1e30ef97315ba5d82","unresolved":true,"context_lines":[{"line_number":374,"context_line":"                    # or claiming jobs. Log and back off rather than letting"},{"line_number":375,"context_line":"                    # it terminate the conductor, which is meant to run until"},{"line_number":376,"context_line":"                    # stopped; the next cycle reconnects and resumes."},{"line_number":377,"context_line":"                    self._log.warning("},{"line_number":378,"context_line":"                        \"Transient job board failure while iterating jobs;\""},{"line_number":379,"context_line":"                        \" backing off and retrying\","},{"line_number":380,"context_line":"                        exc_info\u003dTrue,"},{"line_number":381,"context_line":"                    )"},{"line_number":382,"context_line":"                if not any_dispatched and not is_stopped():"},{"line_number":383,"context_line":"                    self._wait_timeout.wait()"},{"line_number":384,"context_line":"        except StopIteration:"}],"source_content_type":"text/x-python","patch_set":2,"id":"6a859cf2_01c3c6a3","line":381,"range":{"start_line":377,"start_character":0,"end_line":381,"end_character":21},"updated":"2026-08-31 09:16:58.000000000","message":"Let\u0027s use `logger.exception`, which is the same thing but shorter\n\n```suggestion\n                    self._log.exception(\n                        \"Transient job board failure while iterating jobs; \"\n                        \"backing off and retrying\",\n                    )\n```","commit_id":"7117cb743003c598200daaae226e71e0a7d1c763"}]}
