runMultiple<R, P> method
Execute the same function in the least loaded count
isolates.
This guarantees that the function isn't run twice in the same isolate,
so count
is not allowed to exceed length.
The optional load
parameter represents the load that the command
is causing on the isolate where it runs.
The number has no fixed meaning, but should be seen as relative to
other commands run in the same load balancer.
The load
must not be negative.
If timeout
and onTimeout
are provided, they are forwarded to
the runners running the function, which will handle any timeouts
as normal.
Implementation
List<Future<R>> runMultiple<R, P>(
int count, FutureOr<R> Function(P argument) function, P argument,
{Duration? timeout, FutureOr<R> Function()? onTimeout, int load = 100}) {
RangeError.checkValueInInterval(count, 1, _length, 'count');
RangeError.checkNotNegative(load, 'load');
if (count == 1) {
return List<Future<R>>.filled(
1,
run(function, argument,
load: load, timeout: timeout, onTimeout: onTimeout));
}
var result = List<Future<R>>.filled(count, _defaultFuture);
if (count == _length) {
// No need to change the order of entries in the queue.
for (var i = 0; i < _length; i++) {
var entry = _queue[i];
entry.load += load;
result[i] =
entry.run(this, load, function, argument, timeout, onTimeout);
}
} else {
// Remove the [count] least loaded services and run the
// command on each, then add them back to the queue.
for (var i = 0; i < count; i++) {
_removeFirst();
}
// The removed entries are stored in `_queue` in positions from
// `_length` to `_length + count - 1`.
for (var i = 0; i < count; i++) {
var entry = _queue[_length];
entry.load += load;
_addNext();
result[i] =
entry.run(this, load, function, argument, timeout, onTimeout);
}
}
return result;
}