Skip to content

Commit 5cdb9e1

Browse files
joelebacopybara-github
authored andcommitted
Ensure that pending events in BuildEventStreamer are resolved in FIFO order.
1. `TestAttempt` events would wait for the `TargetCompleteEvent` to be posted before being posted. 2. There was an implicit requirement for the `TestAttempt` events to be posted in a specific order. 3. This didn't break in the noskymeld case because we fulfilled this ordering by using the order of performing the attempts themselves. The sequence would look like: + post `TargetCompleteEvent` -> perform attempt #1 -> post `TestAttempt` #1 -> perform attempt #2 -> post `TestAttempt` #2 4. With skymeld, however, it could happen like this: + defer `TargetCompleteEvent` to wait for `CoverageActionFinishedEvent` + perform attempt #1 -> defer posting `TestAttempt` #1 & wait for `TargetCompleteEvent` + perform attempt #2 -> defer posting `TestAttempt` #2 & wait for `TargetCompleteEvent` + `CoverageActionFinishedEvent` -> release & post `TargetCompleteEvent` + `TargetCompleteEvent` -> release & post `TestAttempt` #2 + `TargetCompleteEvent` -> release & post `TestAttempt` #1 Due to (2), the undefined ordering in (4) would cause an issue. This CL fixes that by ensuring a FIFO ordering of the deferred events. PiperOrigin-RevId: 572165337 Change-Id: Iac4d023d946865b8b81f15b119417192dc4b5c53
1 parent 66ac39c commit 5cdb9e1

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import static com.google.common.base.Strings.nullToEmpty;
1919

2020
import com.google.common.annotations.VisibleForTesting;
21-
import com.google.common.collect.HashMultimap;
2221
import com.google.common.collect.ImmutableList;
2322
import com.google.common.collect.ImmutableMap;
2423
import com.google.common.collect.ImmutableSet;
2524
import com.google.common.collect.Iterables;
26-
import com.google.common.collect.Multimap;
25+
import com.google.common.collect.LinkedHashMultimap;
26+
import com.google.common.collect.SetMultimap;
2727
import com.google.common.collect.Sets;
2828
import com.google.common.eventbus.AllowConcurrentEvents;
2929
import com.google.common.eventbus.Subscribe;
@@ -106,8 +106,11 @@ private enum RetentionDecision {
106106
@GuardedBy("this")
107107
private List<Pair<String, String>> bufferedStdoutStderrPairs = new ArrayList<>();
108108

109+
// Use LinkedHashMultimap to maintain a FIFO ordering of pending events.
110+
// This is important in case of Skymeld, so that the TestAttempt events are resolved in the
111+
// correct order.
109112
@GuardedBy("this")
110-
private final Multimap<BuildEventId, BuildEvent> pendingEvents = HashMultimap.create();
113+
private final SetMultimap<BuildEventId, BuildEvent> pendingEvents = LinkedHashMultimap.create();
111114

112115
@GuardedBy("this")
113116
private int progressCount;
@@ -493,11 +496,11 @@ public void buildEvent(BuildEvent event) {
493496
}
494497

495498
// Reconsider all events blocked by the event just posted.
496-
Collection<BuildEvent> toReconsider;
499+
Set<BuildEvent> blockedEventsFifo;
497500
synchronized (this) {
498-
toReconsider = pendingEvents.removeAll(event.getEventId());
501+
blockedEventsFifo = pendingEvents.removeAll(event.getEventId());
499502
}
500-
for (BuildEvent freedEvent : toReconsider) {
503+
for (BuildEvent freedEvent : blockedEventsFifo) {
501504
buildEvent(freedEvent);
502505
}
503506

@@ -558,14 +561,14 @@ private void maybePostPendingEventsBeforeDiscarding(BuildEvent event) {
558561
// a lot of extra locking e.g. for every ActionExecutedEvent and it's only necessary to
559562
// check for this where events are configured to "post after" events that may be discarded.
560563
BuildEventId eventId = event.getEventId();
561-
Collection<BuildEvent> toReconsider;
564+
Set<BuildEvent> blockedEventsFifo;
562565
synchronized (this) {
563-
toReconsider = pendingEvents.removeAll(eventId);
566+
blockedEventsFifo = pendingEvents.removeAll(eventId);
564567
// Pretend we posted this event so a target summary arriving after this test summary (which
565568
// is common) doesn't get erroneously buffered in bufferUntilPrerequisitesReceived().
566569
postedEvents.add(eventId);
567570
}
568-
for (BuildEvent freedEvent : toReconsider) {
571+
for (BuildEvent freedEvent : blockedEventsFifo) {
569572
buildEvent(freedEvent);
570573
}
571574
}

0 commit comments

Comments
 (0)