# Buggy code
def _grading_thread_main(
    self, ipc_ready_signal: threading.Event, submission: Submission, report
) -> None:
    try:
        report(
            ansi_style(
                "Start grading #ansi[%s](yellow)/#ansi[%s](green|bold) in %s..."
                % (submission.problem_id, submission.id, submission.language)
            )
        )

        self.current_judge_worker = JudgeWorker(submission)

        ipc_handler_dispatch: Dict[IPC, Callable] = {
            IPC.HELLO: lambda _report: ipc_ready_signal.set(),
            IPC.COMPILE_ERROR: self._ipc_compile_error,
            IPC.COMPILE_MESSAGE: self._ipc_compile_message,
            IPC.GRADING_BEGIN: self._ipc_grading_begin,
            IPC.GRADING_END: self._ipc_grading_end,
            IPC.GRADING_ABORTED: self._ipc_grading_aborted,
            IPC.BATCH_BEGIN: self._ipc_batch_begin,
            IPC.BATCH_END: self._ipc_batch_end,
            IPC.RESULT: self._ipc_result,
            IPC.UNHANDLED_EXCEPTION: self._ipc_unhandled_exception,
        }

        for ipc_type, data in self.current_judge_worker.communicate():
            try:
                handler_func = ipc_handler_dispatch[ipc_type]
            except KeyError:
                raise RuntimeError(
                    "judge got unexpected IPC message from worker: %s"
                    % ((ipc_type, data),)
                ) from None

            handler_func(report, *data)

        report(
            ansi_style(
                "Done grading #ansi[%s](yellow)/#ansi[%s](green|bold).\n"
                % (submission.problem_id, submission.id)
            )
        )
    except Exception:  # noqa: E722, we want to catch everything
        self.log_internal_error()
    finally:
        if self.current_judge_worker is not None:
            self.current_judge_worker.stop()

        self.current_submission = None
        self.current_judge_worker = None

        # Might not have been set if an exception was encountered before HELLO message, so signal here to keep the
        # other side from waiting forever.
        ipc_ready_signal.set()


# Traceback (ConnectionResetError)
INFO 2020-07-04 08:30:53,248 54 judge Start grading atimesb/262720 in CPP11...
INFO 2020-07-04 08:30:53,261 54 packet Accept submission: 262720: executor: CPP11, code: atimesb
ERROR 2020-07-04 08:30:54,083 26503 judge Judge unexpectedly hung up!
Traceback (most recent call last):
File "/judge/dmoj/judge.py", line 350, in _ipc_recv_thread_main
ipc_type, data = judge_process_conn.recv()
File "/usr/lib/python3.8/multiprocessing/connection.py", line 250, in recv
buf = self._recv_bytes()
File "/usr/lib/python3.8/multiprocessing/connection.py", line 414, in _recv_bytes
buf = self._recv(4)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 379, in _recv
chunk = read(handle, remaining)
ConnectionResetError: [Errno 104] Connection reset by peer
WARNING 2020-07-04 08:30:54,122 26503 tracer Skipping the killing of process because it already exited: 26515
ERROR 2020-07-04 08:30:54,122 54 judge Traceback (most recent call last):
File "/judge/dmoj/judge.py", line 151, in _grading_thread_main
handler_func(report, *data)
File "/judge/dmoj/judge.py", line 177, in _ipc_compile_message
self.packet_manager.compile_message_packet(compile_message)
File "/judge/dmoj/packet.py", line 324, in compile_message_packet
log.debug('Compile message: %d', self.judge.current_submission.id)
AttributeError: 'NoneType' object has no attribute 'id'
ERROR 2020-07-04 08:30:54,122 54 judge Error encountered while reporting error to site!
Traceback (most recent call last):
File "/judge/dmoj/judge.py", line 151, in _grading_thread_main
handler_func(report, *data)
File "/judge/dmoj/judge.py", line 177, in _ipc_compile_message
self.packet_manager.compile_message_packet(compile_message)
File "/judge/dmoj/packet.py", line 324, in compile_message_packet
log.debug('Compile message: %d', self.judge.current_submission.id)
AttributeError: 'NoneType' object has no attribute 'id'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/judge/dmoj/judge.py", line 267, in log_internal_error
self.packet_manager.internal_error_packet(strip_ansi(message))
File "/judge/dmoj/packet.py", line 330, in internal_error_packet
log.debug('Internal error: %d', self.judge.current_submission.id)
AttributeError: 'NoneType' object has no attribute 'id'
Process DMOJ Judge Handler for atimesb/262720:
Traceback (most recent call last):
File "/usr/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
self.run()
File "/usr/lib/python3.8/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/judge/dmoj/judge.py", line 371, in _worker_process_main
judge_process_conn.send(ipc_msg)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/usr/lib/python3.8/multiprocessing/connection.py", line 411, in _send_bytes
self._send(header + buf)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 368, in _send
n = write(self._handle, buf)
BrokenPipeError: [Errno 32] Broken pipe

# Fixed code
def _grading_thread_main(
    self, ipc_ready_signal: threading.Event, submission: Submission, report
) -> None:
    try:
        report(
            ansi_style(
                "Start grading #ansi[%s](yellow)/#ansi[%s](green|bold) in %s..."
                % (submission.problem_id, submission.id, submission.language)
            )
        )

        self.current_judge_worker = JudgeWorker(submission)

        ipc_handler_dispatch: Dict[IPC, Callable] = {
            IPC.HELLO: lambda _report: ipc_ready_signal.set(),
            IPC.COMPILE_ERROR: self._ipc_compile_error,
            IPC.COMPILE_MESSAGE: self._ipc_compile_message,
            IPC.GRADING_BEGIN: self._ipc_grading_begin,
            IPC.GRADING_END: self._ipc_grading_end,
            IPC.GRADING_ABORTED: self._ipc_grading_aborted,
            IPC.BATCH_BEGIN: self._ipc_batch_begin,
            IPC.BATCH_END: self._ipc_batch_end,
            IPC.RESULT: self._ipc_result,
            IPC.UNHANDLED_EXCEPTION: self._ipc_unhandled_exception,
        }

        for ipc_type, data in self.current_judge_worker.communicate():
            try:
                handler_func = ipc_handler_dispatch[ipc_type]
            except KeyError:
                raise RuntimeError(
                    "judge got unexpected IPC message from worker: %s"
                    % ((ipc_type, data),)
                ) from None

            handler_func(report, *data)

        report(
            ansi_style(
                "Done grading #ansi[%s](yellow)/#ansi[%s](green|bold).\n"
                % (submission.problem_id, submission.id)
            )
        )
    except Exception:  # noqa: E722, we want to catch everything
        self.log_internal_error()
    finally:
        if self.current_judge_worker is not None:
            self.current_judge_worker.stop()

        self.current_submission = None
        self.current_judge_worker = None

        # Might not have been set if an exception was encountered before HELLO message, so signal here to keep the
        # other side from waiting forever.
        ipc_ready_signal.set()

        self._grading_lock.release()