Skip to content

Commit a706994

Browse files
tom-cnopscopybara-github
authored andcommitted
Remove logic that increases delay between progress updates over time
Removes a bit of undocumented behavior that increases the delay between progress updates the longer the build is running. Potentially resolves bazelbuild#16119 Also renamed `MAXIMAL_UPDATE_DELAY_MILLIS` to `MINIMAL_UPDATE_INTERVAL_MILLIS` because it is used as a minimum and doesn't affect the delay between messages. Fixes bazelbuild#16119. Closes bazelbuild#16221. RELNOTES[INC]: Bazel no longer increases the delay between progress updates when there is no cursor control. PiperOrigin-RevId: 484203851 Change-Id: I33f7302ca85b75135744eb6093b618196199a49f
1 parent c9f9b0b commit a706994

File tree

3 files changed

+28
-40
lines changed

3 files changed

+28
-40
lines changed

site/en/docs/user-manual.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,9 @@ The default is 0, that means an incremental algorithm: the first
790790
report will be printed after 10 seconds, then 30 seconds and after
791791
that progress is reported once every minute.
792792

793+
When bazel is using cursor control, as specified by
794+
[`--curses`](#curses), progress is reported every second.
795+
793796
#### `--local_{ram,cpu}_resources {{ "<var>" }}resources or resource expression{{ "</var>" }}` {:#local-resources}
794797

795798
These options specify the amount of local resources (RAM in MB and number of CPU logical cores)
@@ -1129,11 +1132,10 @@ default. When disabled, progress messages are suppressed.
11291132

11301133
#### `--show_progress_rate_limit={{ "<var>" }}n{{ "</var>" }}` {:#show-progress-rate}
11311134

1132-
This option causes bazel to display only
1133-
one progress message per `n` seconds, where {{ "<var>" }}n{{ "</var>" }} is a real number.
1134-
If `n` is -1, all progress messages will be displayed. The default value for
1135-
this option is 0.02, meaning bazel will limit the progress messages to one per every
1136-
0.02 seconds.
1135+
This option causes bazel to display at most one progress message per `n` seconds,
1136+
where {{ "<var>" }}n{{ "</var>" }} is a real number.
1137+
The default value for this option is 0.02, meaning bazel will limit the progress
1138+
messages to one per every 0.02 seconds.
11371139

11381140
#### `--show_result={{ "<var>" }}n{{ "</var>" }}` {:#show-result}
11391141

src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ public class BuildRequestOptions extends OptionsBase {
7373
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
7474
converter = ProgressReportIntervalConverter.class,
7575
help =
76-
"The number of seconds to wait between two reports on still running jobs. The "
77-
+ "default value 0 means to use the default 10:30:60 incremental algorithm.")
76+
"The number of seconds to between reports on still running jobs. The "
77+
+ "default value 0 means the first report will be printed after 10 "
78+
+ "seconds, then 30 seconds and after that progress is reported once every minute. "
79+
+ "When --curses is enabled, progress is reported every second.")
7880
public int progressReportInterval;
7981

8082
@Option(

src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java

+17-33
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,19 @@ public final class UiEventHandler implements EventHandler {
8181

8282
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
8383

84-
/** Latest refresh of the progress bar, if contents other than time changed */
85-
private static final long MAXIMAL_UPDATE_DELAY_MILLIS = 200L;
84+
/** Minimal time between scheduled updates */
85+
private static final long MINIMAL_UPDATE_INTERVAL_MILLIS = 200L;
8686
/** Minimal rate limiting (in ms), if the progress bar cannot be updated in place */
8787
private static final long NO_CURSES_MINIMAL_PROGRESS_RATE_LIMIT = 1000L;
88-
/**
89-
* Minimal rate limiting, as fraction of the request time so far, if the progress bar cannot be
90-
* updated in place
91-
*/
92-
private static final double NO_CURSES_MINIMAL_RELATIVE_PROGRESS_RATE_LMIT = 0.15;
9388
/** Periodic update interval of a time-dependent progress bar if it can be updated in place */
9489
private static final long SHORT_REFRESH_MILLIS = 1000L;
95-
/** Periodic update interval of a time-dependent progress bar if it cannot be updated in place */
96-
private static final long LONG_REFRESH_MILLIS = 20000L;
9790

9891
private static final DateTimeFormatter TIMESTAMP_FORMAT =
9992
DateTimeFormatter.ofPattern("(HH:mm:ss) ");
10093
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
10194

10295
private final boolean cursorControl;
10396
private final Clock clock;
104-
private final long uiStartTimeMillis;
10597
private final AnsiTerminal terminal;
10698
private final boolean debugAllEvents;
10799
private final UiStateTracker stateTracker;
@@ -111,7 +103,7 @@ public final class UiEventHandler implements EventHandler {
111103
private final boolean showTimestamp;
112104
private final OutErr outErr;
113105
private final ImmutableSet<EventKind> filteredEvents;
114-
private long minimalDelayMillis;
106+
private long progressRateLimitMillis;
115107
private long minimalUpdateInterval;
116108
private long lastRefreshMillis;
117109
private long mustRefreshAfterMillis;
@@ -175,7 +167,6 @@ public UiEventHandler(
175167
this.progressInTermTitle = options.progressInTermTitle && options.useCursorControl();
176168
this.showTimestamp = options.showTimestamp;
177169
this.clock = clock;
178-
this.uiStartTimeMillis = clock.currentTimeMillis();
179170
this.debugAllEvents = options.experimentalUiDebugAllEvents;
180171
this.locationPrinter =
181172
new LocationPrinter(options.attemptToPrintRelativePaths, workspacePathFragment);
@@ -200,14 +191,15 @@ public UiEventHandler(
200191
this.stateTracker.setProgressSampleSize(options.uiActionsShown);
201192
this.numLinesProgressBar = 0;
202193
if (this.cursorControl) {
203-
this.minimalDelayMillis = Math.round(options.showProgressRateLimit * 1000);
194+
this.progressRateLimitMillis = Math.round(options.showProgressRateLimit * 1000);
204195
} else {
205-
this.minimalDelayMillis =
196+
this.progressRateLimitMillis =
206197
Math.max(
207198
Math.round(options.showProgressRateLimit * 1000),
208199
NO_CURSES_MINIMAL_PROGRESS_RATE_LIMIT);
209200
}
210-
this.minimalUpdateInterval = Math.max(this.minimalDelayMillis, MAXIMAL_UPDATE_DELAY_MILLIS);
201+
this.minimalUpdateInterval =
202+
Math.max(this.progressRateLimitMillis, MINIMAL_UPDATE_INTERVAL_MILLIS);
211203
this.stdoutLineBuffer = new ByteArrayOutputStream();
212204
this.stderrLineBuffer = new ByteArrayOutputStream();
213205
this.dateShown = false;
@@ -854,7 +846,7 @@ private void doRefresh(boolean fromUpdateThread) {
854846
return;
855847
}
856848
long nowMillis = clock.currentTimeMillis();
857-
if (lastRefreshMillis + minimalDelayMillis < nowMillis) {
849+
if (lastRefreshMillis + progressRateLimitMillis < nowMillis) {
858850
if (updateLock.tryLock()) {
859851
try {
860852
synchronized (this) {
@@ -863,17 +855,6 @@ private void doRefresh(boolean fromUpdateThread) {
863855
clearProgressBar();
864856
addProgressBar();
865857
terminal.flush();
866-
if (!cursorControl) {
867-
// If we can't update the progress bar in place, make sure we increase the update
868-
// interval as time progresses, to avoid too many progress messages in place.
869-
minimalDelayMillis =
870-
Math.max(
871-
minimalDelayMillis,
872-
Math.round(
873-
NO_CURSES_MINIMAL_RELATIVE_PROGRESS_RATE_LMIT
874-
* (clock.currentTimeMillis() - uiStartTimeMillis)));
875-
minimalUpdateInterval = Math.max(minimalDelayMillis, MAXIMAL_UPDATE_DELAY_MILLIS);
876-
}
877858
}
878859
}
879860
} catch (IOException e) {
@@ -901,7 +882,7 @@ private void refreshSoon() {
901882
// a future update scheduled.
902883
long nowMillis = clock.currentTimeMillis();
903884
if (mustRefreshAfterMillis <= lastRefreshMillis) {
904-
mustRefreshAfterMillis = Math.max(nowMillis + minimalUpdateInterval, lastRefreshMillis + 1);
885+
mustRefreshAfterMillis = Math.max(nowMillis + 1, lastRefreshMillis + minimalUpdateInterval);
905886
}
906887
startUpdateThread();
907888
}
@@ -911,22 +892,25 @@ private synchronized boolean timeBasedRefresh() {
911892
if (!stateTracker.progressBarTimeDependent()) {
912893
return false;
913894
}
895+
// Don't do more updates than are requested through events when there is no cursor control.
896+
if (!cursorControl) {
897+
return false;
898+
}
914899
long nowMillis = clock.currentTimeMillis();
915-
long intervalMillis = cursorControl ? SHORT_REFRESH_MILLIS : LONG_REFRESH_MILLIS;
916900
if (lastRefreshMillis < mustRefreshAfterMillis
917-
&& mustRefreshAfterMillis < nowMillis + minimalDelayMillis) {
918-
// Within the small interval from now, an update is scheduled anyway,
901+
&& mustRefreshAfterMillis < nowMillis + progressRateLimitMillis) {
902+
// Within a small interval from now, an update is scheduled anyway,
919903
// so don't do a time-based update of the progress bar now, to avoid
920904
// updates too close to each other.
921905
return false;
922906
}
923-
return lastRefreshMillis + intervalMillis < nowMillis;
907+
return lastRefreshMillis + SHORT_REFRESH_MILLIS < nowMillis;
924908
}
925909

926910
private void ignoreRefreshLimitOnce() {
927911
// Set refresh time variables in a state such that the next progress bar
928912
// update will definitely be written out.
929-
lastRefreshMillis = clock.currentTimeMillis() - minimalDelayMillis - 1;
913+
lastRefreshMillis = clock.currentTimeMillis() - progressRateLimitMillis - 1;
930914
}
931915

932916
private void startUpdateThread() {

0 commit comments

Comments
 (0)