# Buggy code
def report_record_done(self, count, err_msg=""):
    """
    Report the number of records in the latest processed batch,
    so TaskDataService knows if some pending tasks are finished
    and report_task_result to the master.
    Return True if there are some finished tasks, False otherwise.
    """
    self._reported_record_count += count
    if err_msg:
        self._failed_record_count += count

    task = self._pending_tasks[0]
    total_record_num = task.end - task.start
    if self._reported_record_count >= total_record_num:
        if err_msg:
            self._log_fail_records(task, err_msg)

        # Keep popping tasks until the reported record count is less
        # than the size of the current data since `batch_size` may be
        # larger than `task.end - task.start`
        with self._lock:
            while self._pending_tasks and self._reported_record_count >= (
                self._pending_tasks[0].end - self._pending_tasks[0].start
            ):
                task = self._pending_tasks[0]
                self._reported_record_count -= task.end - task.start
                self._pending_tasks.popleft()
                self._do_report_task(task, err_msg)
                self._failed_record_count = 0
            if self._pending_tasks:
                self._current_task = self._pending_tasks[0]
        return True
    return False


# Traceback (IndexError)
2020-03-12 22:03:32.300671: W tensorflow/core/kernels/data/generator_dataset_op.cc:103] Error occurred when finalizing GeneratorDataset iterator: Cancelled: Operation was cancelled
Traceback (most recent call last):
File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/elasticdl/python/worker/main.py", line 44, in <module>
main()
File "/elasticdl/python/worker/main.py", line 40, in main
worker.run()
File "/elasticdl/python/worker/worker.py", line 1144, in run
self._train_and_evaluate()
File "/elasticdl/python/worker/worker.py", line 1074, in _train_and_evaluate
self._minibatch_size, err_msg
File "/elasticdl/python/worker/task_data_service.py", line 86, in report_record_done
task = self._pending_tasks[0]
IndexError: deque index out of range

# Fixed code
def report_record_done(self, count, err_msg=""):
    """
    Report the number of records in the latest processed batch,
    so TaskDataService knows if some pending tasks are finished
    and report_task_result to the master.
    Return True if there are some finished tasks, False otherwise.
    """
    self._reported_record_count += count
    if err_msg:
        self._failed_record_count += count

    # TODO(qijun) This is a workaround for #1829
    if not self._pending_tasks:
        return False
    task = self._pending_tasks[0]
    total_record_num = task.end - task.start
    if self._reported_record_count >= total_record_num:
        if err_msg:
            self._log_fail_records(task, err_msg)

        # Keep popping tasks until the reported record count is less
        # than the size of the current data since `batch_size` may be
        # larger than `task.end - task.start`
        with self._lock:
            while self._pending_tasks and self._reported_record_count >= (
                self._pending_tasks[0].end - self._pending_tasks[0].start
            ):
                task = self._pending_tasks[0]
                self._reported_record_count -= task.end - task.start
                self._pending_tasks.popleft()
                self._do_report_task(task, err_msg)
                self._failed_record_count = 0
            if self._pending_tasks:
                self._current_task = self._pending_tasks[0]
        return True
    return False