1414package com .google .devtools .build .lib .remote ;
1515
1616import static com .google .common .base .Preconditions .checkState ;
17+ import static com .google .common .util .concurrent .Futures .addCallback ;
1718import static com .google .common .util .concurrent .MoreExecutors .directExecutor ;
1819import static com .google .devtools .build .lib .remote .util .RxFutures .toCompletable ;
1920import static com .google .devtools .build .lib .remote .util .RxFutures .toListenableFuture ;
2627import com .google .common .collect .ImmutableSet ;
2728import com .google .common .collect .Sets ;
2829import com .google .common .flogger .GoogleLogger ;
30+ import com .google .common .util .concurrent .FutureCallback ;
2931import com .google .common .util .concurrent .ListenableFuture ;
3032import com .google .devtools .build .lib .actions .Action ;
3133import com .google .devtools .build .lib .actions .ActionInput ;
3739import com .google .devtools .build .lib .actions .MetadataProvider ;
3840import com .google .devtools .build .lib .actions .cache .MetadataHandler ;
3941import com .google .devtools .build .lib .actions .cache .VirtualActionInput ;
42+ import com .google .devtools .build .lib .events .Event ;
43+ import com .google .devtools .build .lib .events .ExtendedEventHandler .Postable ;
44+ import com .google .devtools .build .lib .events .Reporter ;
4045import com .google .devtools .build .lib .remote .util .AsyncTaskCache ;
4146import com .google .devtools .build .lib .remote .util .RxUtils .TransferResult ;
4247import com .google .devtools .build .lib .remote .util .TempPathGenerator ;
6368public abstract class AbstractActionInputPrefetcher implements ActionInputPrefetcher {
6469 private static final GoogleLogger logger = GoogleLogger .forEnclosingClass ();
6570
71+ private final Reporter reporter ;
6672 private final AsyncTaskCache .NoResult <Path > downloadCache = AsyncTaskCache .NoResult .create ();
6773 private final TempPathGenerator tempPathGenerator ;
6874 protected final Set <Artifact > outputsAreInputs = Sets .newConcurrentHashSet ();
@@ -109,9 +115,11 @@ protected enum Priority {
109115 }
110116
111117 protected AbstractActionInputPrefetcher (
118+ Reporter reporter ,
112119 Path execRoot ,
113120 TempPathGenerator tempPathGenerator ,
114121 ImmutableList <Pattern > patternsToDownload ) {
122+ this .reporter = reporter ;
115123 this .execRoot = execRoot ;
116124 this .tempPathGenerator = tempPathGenerator ;
117125 this .patternsToDownload = patternsToDownload ;
@@ -538,17 +546,33 @@ public void shutdown() {
538546 }
539547 }
540548
549+ /** Event which is fired when inputs for local action are eagerly prefetched. */
550+ public static class InputsEagerlyPrefetched implements Postable {
551+ private final List <Artifact > artifacts ;
552+
553+ public InputsEagerlyPrefetched (List <Artifact > artifacts ) {
554+ this .artifacts = artifacts ;
555+ }
556+
557+ public List <Artifact > getArtifacts () {
558+ return artifacts ;
559+ }
560+ }
561+
541562 @ SuppressWarnings ({"CheckReturnValue" , "FutureReturnValueIgnored" })
542563 public void finalizeAction (Action action , MetadataHandler metadataHandler ) {
543564 List <Artifact > inputsToDownload = new ArrayList <>();
544565 List <Artifact > outputsToDownload = new ArrayList <>();
545566
546567 for (Artifact output : action .getOutputs ()) {
547568 if (outputsAreInputs .remove (output )) {
548- inputsToDownload .add (output );
549- }
550-
551- if (output .isTreeArtifact ()) {
569+ if (output .isTreeArtifact ()) {
570+ var children = metadataHandler .getTreeArtifactChildren ((SpecialArtifact ) output );
571+ inputsToDownload .addAll (children );
572+ } else {
573+ inputsToDownload .add (output );
574+ }
575+ } else if (output .isTreeArtifact ()) {
552576 var children = metadataHandler .getTreeArtifactChildren ((SpecialArtifact ) output );
553577 for (var file : children ) {
554578 if (outputMatchesPattern (file )) {
@@ -561,11 +585,42 @@ public void finalizeAction(Action action, MetadataHandler metadataHandler) {
561585 }
562586
563587 if (!inputsToDownload .isEmpty ()) {
564- prefetchFiles (inputsToDownload , metadataHandler , Priority .HIGH );
588+ var future = prefetchFiles (inputsToDownload , metadataHandler , Priority .HIGH );
589+ addCallback (
590+ future ,
591+ new FutureCallback <Void >() {
592+ @ Override
593+ public void onSuccess (Void unused ) {
594+ reporter .post (new InputsEagerlyPrefetched (inputsToDownload ));
595+ }
596+
597+ @ Override
598+ public void onFailure (Throwable throwable ) {
599+ reporter .handle (
600+ Event .warn (
601+ String .format (
602+ "Failed to eagerly prefetch inputs: %s" , throwable .getMessage ())));
603+ }
604+ },
605+ directExecutor ());
565606 }
566607
567608 if (!outputsToDownload .isEmpty ()) {
568- prefetchFiles (outputsToDownload , metadataHandler , Priority .LOW );
609+ var future = prefetchFiles (outputsToDownload , metadataHandler , Priority .LOW );
610+ addCallback (
611+ future ,
612+ new FutureCallback <Void >() {
613+ @ Override
614+ public void onSuccess (Void unused ) {}
615+
616+ @ Override
617+ public void onFailure (Throwable throwable ) {
618+ reporter .handle (
619+ Event .warn (
620+ String .format ("Failed to download outputs: %s" , throwable .getMessage ())));
621+ }
622+ },
623+ directExecutor ());
569624 }
570625 }
571626
0 commit comments