Skip to content

Be told how a statement is getting on, and stop it - #4

Merged
tamnd merged 1 commit into
mainfrom
progress
Aug 20, 2026
Merged

tamnd merged 1 commit into
mainfrom
progress

Conversation

@tamnd

@tamnd tamnd commented Aug 20, 2026

Copy link
Copy Markdown
Owner

A progress callback is the connection's interrupt and its rows read together, without the thread that would otherwise have to do the polling. It is set once on a connection and covers every statement after it, and a watcher answering false stops the statement exactly as an interrupt would, so a timeout is one line and a progress bar is the same line with a repaint in it.

conn.onProgress(Duration.ofMillis(250), (rows, millis) -> {
  bar.at(rows, millis);
  return millis < 30_000;
});

The stub the engine calls is the same machinery the frame release callback needed, so that machinery moved out into Upcall: an arena and a function pointer, spent onto a queue that the next stub to be made drains, because a stub cannot close the arena it is standing in. The frame release is now one user of that and the progress watcher the other.

A progress stub outlives the call that set it, so the provider holds one per connection and frees it when the arrangement is replaced, taken back, or the connection closes. Freeing it at those three moments is safe because all three are uses of the connection, and a connection in a call of ours is not running a statement.

Nothing may be thrown out of an upcall, so a watcher that throws is logged and answered as a stop. That is the reading that loses least: a callback that threw is a program that has stopped wanting the answer, and running on would only mean throwing the answer away later.

Ten tests, over a nested loop of nine million pairs, because a scan of ten million rows in a frame finishes in ten milliseconds and there is nothing there to report on. They cover the numbers moving forward and never backward, the thread not being the caller's, a stop being an interrupt and the connection carrying on afterwards, a watcher that throws not taking the JVM with it, the arrangement being replaced rather than added to, an interval of zero being refused, an interval longer than the statement saying nothing at all, and a connection closing with a watcher still on it.

Local gate green: 171 tests, no failures.

A progress callback is the connection's interrupt and its rows read
together, without the thread that would otherwise have to do the
polling. It is set once on a connection and covers every statement after
it, and a watcher answering false stops the statement exactly as an
interrupt would, so a timeout is one line and a progress bar is the same
line with a repaint in it.

The stub the engine calls is the same machinery the frame release
callback needed, so that machinery moved out into Upcall: an arena and a
function pointer, spent onto a queue that the next stub to be made
drains, because a stub cannot close the arena it is standing in. The
frame release is now one user of that and the progress watcher the
other.

A progress stub outlives the call that set it, so the provider holds one
per connection and frees it when the arrangement is replaced, taken
back, or the connection closes. Freeing it at those three moments is
safe because all three are uses of the connection, and a connection in a
call of ours is not running a statement.

Nothing may be thrown out of an upcall, so a watcher that throws is
logged and answered as a stop. That is the reading that loses least: a
callback that threw is a program that has stopped wanting the answer,
and running on would only mean throwing the answer away later.

Ten tests, over a nested loop of nine million pairs, because a scan of
ten million rows in a frame finishes in ten milliseconds and there is
nothing there to report on.
@tamnd
tamnd merged commit 9226cdd into main Aug 20, 2026
9 checks passed
@tamnd
tamnd deleted the progress branch August 20, 2026 02:10
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.

1 participant