aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Jakob Buchgraber <buchgr@google.com>2017-02-28 18:49:50 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2017-02-28 18:57:13 +0000
commit8c3a4efce2882a8823df06b369e5d079765bed5b (patch)
treefed7bba6f7666d73087ead7aaa9f8b540f21bede /src/main/java/com/google/devtools
parent6525e389b854b2bb4e84a4145c0a3945d7e195bd (diff)
BEP: Add BuildFinished event.
The build event protocol now emits a BuildFinished event at the end of a build. The event is a child of the BuildStarted event. The code changes were larger than expected, due to some refactoring in BuildEventStreamer. This was necessary as the BuildCompleteEvent now implements the BuildEvent interface and Guava's EventBus always invokes the most specialized subscriber method. Thus, the buildEvent(BuildEvent) and buildCompleted(BuildCompletedEvent) methods had to be merged. -- Change-Id: Id0c2bd7220dc8ce03128b7126587e212ee8ce836 Reviewed-on: https://cr.bazel.build/9053 PiperOrigin-RevId: 148788582 MOS_MIGRATED_REVID=148788582
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto18
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildCompleteEvent.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java61
5 files changed, 96 insertions, 29 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
index 360dfdb15c..467d6f2b20 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
@@ -130,4 +130,11 @@ public final class BuildEventId implements Serializable {
return new BuildEventId(
BuildEventStreamProtos.BuildEventId.newBuilder().setTestSummary(summaryId).build());
}
+
+ public static BuildEventId buildFinished() {
+ BuildEventStreamProtos.BuildEventId.BuildFinishedId finishedId =
+ BuildEventStreamProtos.BuildEventId.BuildFinishedId.getDefaultInstance();
+ return new BuildEventId(
+ BuildEventStreamProtos.BuildEventId.newBuilder().setBuildFinished(finishedId).build());
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
index f70c715781..1ff9d6a021 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
@@ -85,6 +85,10 @@ message BuildEventId {
string label = 1;
}
+ // Identifier of the BuildFinished event, indicating the end of a build.
+ message BuildFinishedId {
+ }
+
oneof id {
UnknownBuildEventId unknown = 1;
ProgressId progress = 2;
@@ -94,6 +98,7 @@ message BuildEventId {
ActionCompletedId action_completed = 6;
TestResultId test_result = 8;
TestSummaryId test_summary = 7;
+ BuildFinishedId build_finished = 9;
}
}
@@ -139,6 +144,8 @@ message BuildStarted {
string uuid = 1;
// Start of the build in ms since the epoche.
+ // TODO(buchgr): Use google.protobuf.TimeStamp once bazel's protoc supports
+ // it.
int64 start_time_millis = 2;
// Version of the build tool that is running.
@@ -245,6 +252,16 @@ message TestSummary {
repeated File failed = 4;
}
+// Event indicating the end of a build.
+message BuildFinished {
+ // If the build succeeded or failed.
+ bool overall_success = 1;
+ // Time in milliseconds since the epoch.
+ // TODO(buchgr): Use google.protobuf.Timestamp once bazel's protoc supports
+ // it.
+ int64 finish_time_millis = 2;
+}
+
// Message describing a build event. Events will have an identifier that
// is unique within a given build invocation; they also announce follow-up
// events as children. More details, which are specific to the kind of event
@@ -262,5 +279,6 @@ message BuildEvent {
TargetComplete completed = 8;
TestResult test_result = 10;
TestSummary test_summary = 9;
+ BuildFinished finished = 14;
};
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildCompleteEvent.java b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildCompleteEvent.java
index 93416ba7ea..2412221513 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildCompleteEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildCompleteEvent.java
@@ -14,19 +14,31 @@
package com.google.devtools.build.lib.buildtool.buildevent;
+import static com.google.devtools.build.lib.util.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.buildeventstream.BuildEvent;
+import com.google.devtools.build.lib.buildeventstream.BuildEventId;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildFinished;
+import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
+import com.google.devtools.build.lib.buildeventstream.PathConverter;
import com.google.devtools.build.lib.buildtool.BuildResult;
+import java.util.Collection;
/**
* This event is fired from BuildTool#stopRequest().
+ *
+ * <p>This class also implements the {@link BuildFinished} event of the build event protocol (BEP).
*/
-public final class BuildCompleteEvent {
+public final class BuildCompleteEvent implements BuildEvent {
private final BuildResult result;
/**
* Construct the BuildCompleteEvent.
*/
public BuildCompleteEvent(BuildResult result) {
- this.result = result;
+ this.result = checkNotNull(result);
}
/**
@@ -35,4 +47,24 @@ public final class BuildCompleteEvent {
public BuildResult getResult() {
return result;
}
+
+ @Override
+ public BuildEventId getEventId() {
+ return BuildEventId.buildFinished();
+ }
+
+ @Override
+ public Collection<BuildEventId> getChildrenEvents() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ public BuildEventStreamProtos.BuildEvent asStreamProto(PathConverter pathConverter) {
+ BuildFinished finished =
+ BuildFinished.newBuilder()
+ .setOverallSuccess(result.getSuccess())
+ .setFinishTimeMillis(result.getStopTime())
+ .build();
+ return GenericBuildEvent.protoChaining(this).setFinished(finished).build();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
index 3eff203b8d..71f7b0ca07 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java
@@ -82,7 +82,8 @@ public final class BuildStartingEvent implements BuildEvent {
public Collection<BuildEventId> getChildrenEvents() {
return ImmutableList.of(
ProgressEvent.INITIAL_PROGRESS_UPDATE,
- BuildEventId.targetPatternExpanded(request.getTargets()));
+ BuildEventId.targetPatternExpanded(request.getTargets()),
+ BuildEventId.buildFinished());
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
index 8f5292f83b..c0c50958b5 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
@@ -47,7 +47,7 @@ public class BuildEventStreamer implements EventHandler {
private final Multimap<BuildEventId, BuildEvent> pendingEvents;
private int progressCount;
private AbortReason abortReason = AbortReason.UNKNOWN;
- private static final Logger LOG = Logger.getLogger(BuildEventStreamer.class.getName());
+ private static final Logger log = Logger.getLogger(BuildEventStreamer.class.getName());
public BuildEventStreamer(Collection<BuildEventTransport> transports) {
this.transports = transports;
@@ -98,7 +98,7 @@ public class BuildEventStreamer implements EventHandler {
transport.sendBuildEvent(event);
} catch (IOException e) {
// TODO(aehlig): signal that the build ought to be aborted
- LOG.severe("Failed to write to build event transport: " + e);
+ log.severe("Failed to write to build event transport: " + e);
}
}
}
@@ -135,7 +135,7 @@ public class BuildEventStreamer implements EventHandler {
transport.close();
} catch (IOException e) {
// TODO(aehlig): signal that the build ought to be aborted
- LOG.warning("Failure while closing build event transport: " + e);
+ log.warning("Failure while closing build event transport: " + e);
}
}
}
@@ -151,33 +151,12 @@ public class BuildEventStreamer implements EventHandler {
@Subscribe
public void buildInterrupted(BuildInterruptedEvent event) {
abortReason = AbortReason.USER_INTERRUPTED;
- };
-
- @Subscribe
- public void buildComplete(BuildCompleteEvent event) {
- clearPendingEvents();
- post(ProgressEvent.finalProgressUpdate(progressCount));
- clearAnnouncedEvents();
- close();
}
@Subscribe
public void buildEvent(BuildEvent event) {
- if (event instanceof ActionExecutedEvent) {
- // We ignore events about action executions if the execution succeeded.
- if (((ActionExecutedEvent) event).getException() == null) {
- return;
- }
- }
-
- if (event instanceof BuildEventWithOrderConstraint) {
- // Check if all prerequisit events are posted already.
- for (BuildEventId prerequisiteId : ((BuildEventWithOrderConstraint) event).postedAfter()) {
- if (!postedEvents.contains(prerequisiteId)) {
- pendingEvents.put(prerequisiteId, event);
- return;
- }
- }
+ if (isActionWithoutError(event) || bufferUntilPrerequisitesReceived(event)) {
+ return;
}
post(event);
@@ -187,10 +166,40 @@ public class BuildEventStreamer implements EventHandler {
for (BuildEvent freedEvent : toReconsider) {
buildEvent(freedEvent);
}
+
+ if (event instanceof BuildCompleteEvent) {
+ buildComplete();
+ }
}
@VisibleForTesting
ImmutableSet<BuildEventTransport> getTransports() {
return ImmutableSet.copyOf(transports);
}
+
+ private void buildComplete() {
+ clearPendingEvents();
+ post(ProgressEvent.finalProgressUpdate(progressCount));
+ clearAnnouncedEvents();
+ close();
+ }
+
+ private static boolean isActionWithoutError(BuildEvent event) {
+ return event instanceof ActionExecutedEvent
+ && ((ActionExecutedEvent) event).getException() == null;
+ }
+
+ private boolean bufferUntilPrerequisitesReceived(BuildEvent event) {
+ if (!(event instanceof BuildEventWithOrderConstraint)) {
+ return false;
+ }
+ // Check if all prerequisite events are posted already.
+ for (BuildEventId prerequisiteId : ((BuildEventWithOrderConstraint) event).postedAfter()) {
+ if (!postedEvents.contains(prerequisiteId)) {
+ pendingEvents.put(prerequisiteId, event);
+ return true;
+ }
+ }
+ return false;
+ }
}