Skip to content

pool: honor CleanOnFinish - #249

Merged
cheggaaa merged 3 commits into
masterfrom
fix-pool-clean-on-finish
Nov 5, 2026
Merged

cheggaaa merged 3 commits into
masterfrom
fix-pool-clean-on-finish

Conversation

@cheggaaa

@cheggaaa cheggaaa commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

A pool renders every bar on every frame, so a finished CleanOnFinish bar stays on screen. A bar started before Pool.Add (pb.StartNew) also keeps its own writer and prints into the pool's frame.

  • The pool hides finished CleanOnFinish bars and erases their lines when the frame shrinks (\r\033[J on unix, blank lines plus cursor rollback on windows). Hidden bars stay in the pool, so a bar that is Finished and Started again shows up again. The terminal-height clamp skips hidden bars, so they don't take rows from live ones; the finished check counts every bar that isn't hidden, including bars clipped by the terminal height.
  • Pool.Add stops the own writer of an already started bar and wipes its line; the bar is no longer IsStarted(), and its start time and speed stats are kept. The bar's finish channel now carries whether the writer draws the final state (Finish) or wipes the line (Add), each writer owns its ticker, Finish and Add take turns on the writer handshake, and the bar stays IsStarted() until its writer is gone, so a racing Start sees a running bar and does nothing while the writer is still drawing. Add detaches bars before taking the pool lock, so a bar blocked on its output can't stall the pool.
  • An empty frame doesn't emit \033[0A, which terminals treat as one line up.
  • Bar selection is shared between the unix and windows printers; the unix frame is built by render(first, rows, cols), which the tests drive with a fixed terminal size.

Behavior change: IsStarted() reports false for a started bar once it is added to a pool, and such a bar's Finish() writes nothing on its own; the pool draws its final state.

Verified with the repro from #223 in a 100x24 terminal: only the root bar remains, output printed before the pool is intact when every bar is cleaned, and a started bar that finishes before the pool's next frame leaves no orphan line. The windows printer is compile-checked only.

Fixes #223

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bju1BfF4mCjLwfxG8Zm92u

The pool hides finished CleanOnFinish bars and erases their lines when
the frame shrinks. Hidden bars stay in the pool, so a restarted bar
shows up again; the height clamp and the finished check only count
visible bars.

Pool.Add stops the own writer of an already started bar and wipes its
line, so a pb.StartNew bar no longer writes into the pool's frame. The
bar's finish channel carries whether the writer draws the final state
or wipes, and each writer owns its ticker, so Start and Finish racing
Add can't share state with a dying writer. Add detaches bars before
taking the pool lock.

An empty frame doesn't move the cursor.

Fixes #223

Claude-Session: https://claude.ai/code/session_01Bju1BfF4mCjLwfxG8Zm92u
Pool.Add stops a started bar's writer. A Start or Finish racing it saw
no writer and ran while the writer was still drawing: Start reset the
render state under it, Finish returned before the last write. A mutex
makes the three take turns on the handshake, and the bar stays
IsStarted until its writer is gone.
The bar stays IsStarted until its writer acks, so Start already returns
early while Finish or stopWriter waits on the handshake. Holding the
lock there only blocks Start during a Finish, which then restarts the
bar instead of staying a no-op, and deadlocks a Start issued from the
bar's own output writer.
@cheggaaa
cheggaaa merged commit babe5a9 into master Nov 5, 2026
1 check passed
@cheggaaa
cheggaaa deleted the fix-pool-clean-on-finish branch November 5, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CleanOnFinish doesn't work as intended in pool

1 participant