Implement --bes_upload_mode=fully_async.

Unlike NOWAIT_FOR_UPLOAD_COMPLETE, this mode does not block the subsequent build on server-side acknowledgement.

All file uploads should be complete by the time we unblock, so there should not be a risk of a racy read.

In case of server shutdown, we attempt to block on acknowledgement just as in NOWAIT_FOR_UPLOAD_COMPLETE.

RELNOTES: None
PiperOrigin-RevId: 244867998
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceUploader.java b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceUploader.java
index 30f4374..ca3b4e6 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceUploader.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventservice/BuildEventServiceUploader.java
@@ -131,6 +131,8 @@
   @GuardedBy("lock")
   private SettableFuture<Void> closeFuture;
 
+  private final SettableFuture<Void> halfCloseFuture = SettableFuture.create();
+
   /**
    * The thread that calls the lifecycle RPCs and does the build event upload. It's started lazily
    * on the first call to {@link #enqueueEvent(BuildEvent)} or {@link #close()} (which ever comes
@@ -459,6 +461,7 @@
                       lastEvent.getSequenceNumber(), lastEvent.getCreationTime());
               streamContext.sendOverStream(request);
               streamContext.halfCloseStream();
+              halfCloseFuture.set(null);
             }
             break;