Только вы знаете, что такое «лучший», но есть общие правила, как это сделать, и, возможно, это ваш настоящий вопрос.
Обычно вам нужна очередь, скажем, массив, в котором хранятся все еще не отправленные запросы:
my @queue;
затем, каждый раз, когда вы хотите выполнить запрос, вы сначала помещаете данные в очередь, а затем вызываете функцию «планировщика»:
sub do_req {
my ($ data, $ cb) = @_;
push @queue, [$ data, $ cb];
планировщик;
}
Цель функции расписания - выбрать работника и уволить
следующий запрос:
sub scheduler {
@queue или возврат; # ничего не делать с пустой очередью
for my $worker (@workers) {
if ("$worker is free") {
my ($data, $cb) = @{ shift @queue };
$worker->doit (sub {
&scheduler;
$cb->(@_); # call original callback
});
return;
}
}
}
Для этого нужно найти свободного работника, отправить ему запрос («doit») и
когда он заканчивается, он снова вызывает планировщик.
От вас зависит, как вы решите, свободен ли работник. Например, вы
всегда мог выбрать работника с наименьшим количеством невыполненных запросов.
Или вы можете выбрать работника, у которого, скажем, менее 5 невыполненных запросов.
Или какой путь лучше.
Важно то, что когда работник может стать свободным (потому что работа
завершается), вы снова вызываете планировщик, чтобы поставить в очередь следующее задание.
Таким образом, вы можете наложить произвольные ограничения на работников, не забывая при этом
о работах, которые вы должны выполнить, но не можете отправить из-за этих ограничений.
В этой технике много вариатов, но основная идея всегда
то же самое: сначала вещи в очереди, затем есть функция, которую вы вызываете после
в очереди и после выполнения задания, которое затем следует распределить в очереди
работа.
Во время разговора, есть два события, когда вам может понадобиться отправить
запрос: когда новая работа / запрос создается / ставится в очередь, и когда невыполненный
работа выполнена.