-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Console section is incorrectly updated #35012
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Status: reviewed. This bug is related to the height of the terminal. With ANSI escape codes, we move the cursor up to erase the section content to replace it. It looks like this strategy does not work on the part of the terminal that is "not visible". |
Hey, thanks for your report! |
Just a quick reminder to make a comment on this. If I don't hear anything I'll close this. |
Still an issue with Symfony 5.2.1. |
@fancyweb do you see any solution to this? For me the section overwrite functionality seems fundamentally flawed. The cursor can only be moved within the view port (width: max number of columns or characters, height: max number of lines). So when scrolling up via the |
Hey, thanks for your report! |
Friendly ping? Should this still be open? I will close if I don't hear anything. |
Hey, I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen! |
hello, I re-open this as the issue has not been fixed. I created a standalone reproducer that works outside full stack framework: <?php
use Symfony\Component\Console\Output\ConsoleOutput;
require __DIR__ . '/vendor/autoload.php';
$output = new ConsoleOutput();
$s1 = $output->section();
$s1->writeln('Section #1, line #1.');
$s2 = $output->section();
for ($i = 1; $i <= 5; $i++) {
$s2->writeln("Section #2, line #$i.");
}
$s1->overwrite('Section #1 after first overwrite.');
$s3 = $output->section();
for ($i = 1; $i < ($argv[1] ?? 10); ++$i) {
$s3->writeln("Test line #$i.");
}
// Now the first section will not be updated correctly.
$s1->overwrite('Section #1 after second overwrite.');
increase 10 until the bug occurs I also created another reproducer, more fun (actually, this code I tried to put in production...) :) <?php
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleSectionOutput;
require __DIR__ . '/vendor/autoload.php';
function run(ConsoleSectionOutput $section) {
for ($i=0; $i < 10; $i++) {
$section->writeln(bin2hex(random_bytes(16)));
Fiber::suspend();
}
}
$output = new ConsoleOutput();
// Ensure you screen has at least 20 lines of height
$maxHeight = 5;
$output->section()->writeln('<info>Building for Linux</info>');
$section1 = $output->section();
$section1->setMaxHeight($maxHeight);
$output->section()->writeln('<info>Building for Darwin</info>');
$section2 = $output->section();
$section2->setMaxHeight($maxHeight);
$output->section()->writeln('<info>Building for Windows</info>');
$section3 = $output->section();
$section3->setMaxHeight($maxHeight);
$f1 = new Fiber(fn() => run($section1));
$f2 = new Fiber(fn() => run($section2));
$f3 = new Fiber(fn() => run($section3));
$f1->start();
$f2->start();
$f3->start();
while ($f1->isSuspended() || $f2->isSuspended() || $f3->isSuspended()) {
if ($f1->isSuspended()) {
$f1->resume();
}
if ($f2->isSuspended()) {
$f2->resume();
}
if ($f3->isSuspended()) {
$f3->resume();
}
usleep(100_000);
}
$output->writeln('<info>Done</info>'); |
Resolving this is not easy and it certainly needs a new behavior for sections, let me explain : As an example we have :
In this case we can erase 50 lines max (as we cannot write on a not visible part of the terminal) and output 30 lines of the first section (20 lines added, 10 erased) and then the others section.
so we see 10 lines of the second and 40 lines of the third) -> no problem
History will be bugged and there is no possibility to fix that as the second section will be rewrited again but not in the visible part, then we will have it multiple times in the history Also user will never see the update to the first section as it will always be out of the view part A way to partially fix this would be to reorder session when we write to them, so the last updated section will always be in last in the terminal, it will not fix the history but at least it would allow user to see what happens in last Another solution would be to use the maxHeight parameter of the section and auto adjust their size given the number of sections, and to avoid having lost output we could, when all the sections are Not sure what is wanted here ? (for me the last solution is the best but it should be available as an option) |
IMHO we can close this once #51355 is merged. the issue was closed, whithout activity, and I reopened it with a special use-case, and @joelwurtz fixed it. |
@lyrixx I agree with that. But I opened a documentation issue about better explaining the limitation that your section-based UI can only mutate the visible part of the terminal content |
…ax height (joelwurtz) This PR was merged into the 6.3 branch. Discussion ---------- [Console] fix section output when multiples section with max height | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Partial fix for #35012 | License | MIT | Doc PR | This pr does not fix #35012 However it fixes the second script wrote by `@lyrixx` (#35012 (comment)) with fiber and parallel output. In short when there was multiple sections with max height, it was not taking into account the max height of other sections when doing a full rewrite, leading to erase more lines than intended. Commits ------- 28e9da6 fix(console): fix section output when multiples section with max height
Symfony version(s) affected: 4.3.9, 4.4.1
PHP version: 7.3.12
Description
During alternating updates of individual sections, those previously displayed are incorrectly updated. This is somehow related to the number of lines displayed in between. Change
54
to53
and then to52
in for-loop to see the difference.Invalid output
How to reproduce
The text was updated successfully, but these errors were encountered: