# Buggy code
def abort_grading(self) -> None:
    """
    Forcefully terminates the current submission. Not necessarily safe.
    """
    # Grab a local copy since it might get set to None after we do our None check.
    worker = self.current_judge_worker
    if worker:
        worker.abort_grading()


# Traceback (AttributeError)
INFO 2020-07-15 17:02:08,535 56 judge Start grading boi2019p3/2205852 in CPP11...
INFO 2020-07-15 17:02:08,540 56 packet Accept submission: 2205852: executor: CPP11, code: boi2019p3
INFO 2020-07-15 17:02:09,336 56 judge Batch #1
INFO 2020-07-15 17:02:09,346 56 judge   Test case  1 AC [0.002s (0.003s) | 5668kb]
INFO 2020-07-15 17:02:09,356 56 judge   Test case  2 AC [0.003s (0.004s) | 5348kb]
INFO 2020-07-15 17:02:09,357 56 judge Batch #2
INFO 2020-07-15 17:02:09,376 56 judge   Test case  3 AC [0.011s (0.012s) | 5672kb]
INFO 2020-07-15 17:02:09,395 56 judge   Test case  4 WA [0.011s (0.012s) | 5104kb]
INFO 2020-07-15 17:02:09,395 56 judge   Test case  5 --
INFO 2020-07-15 17:02:09,395 56 judge   Test case  6 --
INFO 2020-07-15 17:02:09,396 56 judge Batch #3
INFO 2020-07-15 17:02:09,409 56 judge   Test case  7 WA [0.006s (0.008s) | 5860kb]
INFO 2020-07-15 17:02:09,409 56 judge   Test case  8 --
INFO 2020-07-15 17:02:09,410 56 judge   Test case  9 --
INFO 2020-07-15 17:02:09,410 56 judge   Test case 10 --
INFO 2020-07-15 17:02:09,425 56 judge   Test case 11 --
INFO 2020-07-15 17:02:09,425 56 judge   Test case 12 --
INFO 2020-07-15 17:02:09,426 56 judge   Test case 13 --
INFO 2020-07-15 17:02:09,426 56 judge   Test case 14 --
INFO 2020-07-15 17:02:09,426 56 judge   Test case 15 --
INFO 2020-07-15 17:02:09,426 56 judge   Test case 16 --
INFO 2020-07-15 17:02:09,426 56 judge Batch #4
WARNING 2020-07-15 17:02:14,456 19004 tracer Shocker activated and killed 19036
WARNING 2020-07-15 17:02:14,456 19004 tracer Request the killing of process: 19036
INFO 2020-07-15 17:02:14,458 56 judge   Test case 17 TLE [5.000s (5.001s) | 12368kb] {RTE, WA}
INFO 2020-07-15 17:02:14,458 56 judge   Test case 18 --
INFO 2020-07-15 17:02:14,461 56 judge   Test case 19 --
INFO 2020-07-15 17:02:14,462 56 judge   Test case 20 --
INFO 2020-07-15 17:02:14,465 56 judge   Test case 21 --
INFO 2020-07-15 17:02:14,466 56 judge   Test case 22 --
INFO 2020-07-15 17:02:14,471 56 judge Batch #5
INFO 2020-07-15 17:02:14,478 56 packet Received abortion request for 2205852
WARNING 2020-07-15 17:02:14,479 19004 tracer Skipping the killing of process because it already exited: 19036
ERROR 2020-07-15 17:02:19,481 56 judge Worker is still alive, sending SIGKILL!
ERROR 2020-07-15 17:02:19,484 56 judge Failed to read IPC message from worker!
ERROR 2020-07-15 17:02:19,497 56 judge Traceback (most recent call last):
File "/judge/dmoj/judge.py", line 152, in _grading_thread_main
for ipc_type, data in self.current_judge_worker.communicate():
File "/judge/dmoj/judge.py", line 306, in communicate
ipc_type, data = self.worker_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 383, in _recv
raise EOFError
EOFError

ERROR 2020-07-15 17:02:19,628 56 packet Exception while reading packet from site, will not attempt to reconnect! Quitting judge.
Traceback (most recent call last):
File "/judge/dmoj/packet.py", line 156, in _read_forever
self._receive_packet(self._read_single())
File "/judge/dmoj/packet.py", line 276, in _receive_packet
log.info('Received abortion request for %s', self.judge.current_submission.id)
AttributeError: 'NoneType' object has no attribute 'id'

# Fixed code
def abort_grading(self) -> None:
    """
    Forcefully terminates the current submission. Not necessarily safe.
    """
    with self._current_submission_lock:
        if self.current_judge_worker:
            logger.info("Received abortion request for %d", self.current_submission.id)
            self.current_judge_worker.abort_grading()
        else:
            # This can happen because message delivery is async; the user may have pressed "Abort" before we
            # finished grading, but by the time the message reached us we may have finished grading already.
            logger.info("Received abortion request, but nothing is running")