eta method
Simulates the remaining work on parallel slots: running jobs keep their slot, queued jobs start on whichever slot frees up first.
Implementation
Duration eta([DateTime? at]) {
final t = at ?? now;
final slots = List<Duration>.filled(math.max(parallel, 1), Duration.zero);
var i = 0;
for (final j in jobs.where((j) => j.state == JobState.running)) {
if (i < slots.length) slots[i++] = j.remaining(t);
}
for (final j in jobs.where((j) => j.state == JobState.queued)) {
var best = 0;
for (var s = 1; s < slots.length; s++) {
if (slots[s] < slots[best]) best = s;
}
slots[best] += j.estimate;
}
return slots.reduce((a, b) => a > b ? a : b);
}