I'm using a ProgressBar
for my console command, and allow the command to restart at some point in the middle of the processing:
$itemCount = 1_000_000;
$startItem = 150_000;
$progressBar = new ProgressBar($output, $itemCount);
$progressBar->setFormat(
$progressBar->getFormatDefinition(ProgressBar::FORMAT_DEBUG)
);
$progressBar->start();
if ($startItem !== 0) {
// unfortunately taken into account in ETA calculation
$progressBar->advance($startItem);
}
for ($i = $startItem; $i < $itemCount; $i++) {
usleep(50_000);
$progressBar->advance();
}
The issue is, even though the command processes only ~20 items per second, the ETA is calculated just as if $startItem
items had been processed right at the beginning of the processing:
150038/1000000 [====>-----------------------] 15% 2 secs/13 secs 20.0 MiB
I'm expecting the ETA to be ~12 hours here, not 13 secs.
How can I fix this? Can I somehow give the starting position of the progress bar before starting it, so that the ETA is properly calculated?
This is not supported by the
ProgressBar
helper.The estimated time is calculated by the
ProgressBar#getEstimated()
method, which is very simple:This only takes into account the amount of time since the progress bar has been started (which is set when one calls
ProgressBar#start()
, or on the constructor otherwise), and the total amount of "steps" it's taken so far.There is no distinction between "real" steps, and "fake" steps. Even if one were to modify
ProgresBar#step
before callingstart()
(e.g. on the constructor), the result would be the same, since the calculation for estimated time would work exactly the same way.The class is marked
final
, which I think it's unfortunate for a helper class, so you cannot simply extend it and add your logic (e.g. with an additionalint $resumedAt
property that one could use when calculating the estimated remaining time).If you really, really need this, I'd simply make a copy of the class in your project and add the necessary logic there.
As a simple proof of concept, I'd copied
ProgressBar
intoApp\ProgressBar
, and added this:One would simply use this as: