def METHOD_NAME(self, id, problem, language, source, judge_id, priority, banned_judges=[]):
    with self.lock:
        if id in self.submission_map or id in self.node_map:
            # Already judging, don't queue again. This can happen during batch rejudges, rejudges should be
            # idempotent.
            return
        candidates = [
            METHOD_NAME for METHOD_NAME in self.judges
            if METHOD_NAME.name not in banned_judges and
            METHOD_NAME.can_judge(problem, language, judge_id)
        ]
        available = [METHOD_NAME for METHOD_NAME in candidates if not METHOD_NAME.working and not METHOD_NAME.is_disabled]
        if judge_id:
            logger.info('Specified judge %s is%savailable', judge_id, ' ' if available else ' not ')
        else:
            logger.info('Free judges: %d', len(available))
        if len(candidates) > 1 and len(available) == 1 and priority >= REJUDGE_PRIORITY:
            available = []
        if available:
            # Schedule the submission on the judge reporting least load.
            METHOD_NAME = min(available, key=lambda METHOD_NAME: (METHOD_NAME.load, random()))
            logger.info('Dispatched submission %d to: %s', id, METHOD_NAME.name)
            self.submission_map[id] = METHOD_NAME
            try:
                METHOD_NAME.submit(id, problem, language, source)
            except Exception:
                logger.exception('Failed to dispatch %d (%s, %s) to %s', id, problem, language, METHOD_NAME.name)
                self.judges.discard(METHOD_NAME)
                return self.METHOD_NAME(id, problem, language, source, judge_id, priority, banned_judges)
        else:
            self.node_map[id] = self.queue.insert(
                (id, problem, language, source, judge_id, banned_judges),
                self.priority[priority],
            )
            logger.info('Queued submission: %d', id)