Как правильно в Clojure выполнять параллельную обработку, когда каждое задание обработки может выполняться в полной изоляции и может генерировать список дополнительных заданий, которые необходимо оценить?
Моя настоящая проблема - это проблема расчета питательности, но я обозначу ее в форме шахмат, которая имеет те же черты пробела, что и мои вычисления.
Предположим, например, что я пытаюсь найти все ходы для шаха в игре в шахматы. При поиске по состояниям доски я начинал с 20 возможных состояний, каждое из которых представляло различный возможный ход открытия. Каждое из них необходимо будет оценить, принять или отклонить, а затем для каждого принятого хода будет создан новый список заданий, представляющий все возможные последующие шаги. Работа будет выглядеть так:
initial: '([] proposed-move)
accepted: '([move] proposed-response)
'([move move] proposed-response)
Количество состояний для оценки увеличивается в результате каждого вычисления, и каждое состояние может оцениваться в полной изоляции от всех остальных.
Решение, с которым я играю, выглядит так:
; a list of all final solutions, each of which is a sequence of moves
(def solutions (agent []))
; a list of all jobs pending evaluation
(def jobs (agent []))
С учетом этих определений у меня будет пул потоков Java, и каждый поток будет запрашивать задание у агента заданий (и ожидать выполнения этого запроса). Затем он запустит расчет, сгенерирует список решений и возможных решений. Наконец, он отправляет решения агенту решений, а возможные решения агенту заданий.
Является ли использование комбинации агентов и потоков наиболее идиоматичным способом в этом случае? Могу ли я даже получить данные из очереди заданий так, как я предлагаю?
Или мои задания должны быть java.util.concurrent.LinkedBlockingQueue, как описано в Производитель-потребитель с квалификацией ?