14
14
package com .google .devtools .build .lib .remote ;
15
15
16
16
import static com .google .common .base .Preconditions .checkState ;
17
+ import static com .google .common .util .concurrent .Futures .addCallback ;
17
18
import static com .google .common .util .concurrent .MoreExecutors .directExecutor ;
18
19
import static com .google .devtools .build .lib .remote .util .RxFutures .toCompletable ;
19
20
import static com .google .devtools .build .lib .remote .util .RxFutures .toListenableFuture ;
26
27
import com .google .common .collect .ImmutableSet ;
27
28
import com .google .common .collect .Sets ;
28
29
import com .google .common .flogger .GoogleLogger ;
30
+ import com .google .common .util .concurrent .FutureCallback ;
29
31
import com .google .common .util .concurrent .ListenableFuture ;
30
32
import com .google .devtools .build .lib .actions .Action ;
31
33
import com .google .devtools .build .lib .actions .ActionInput ;
37
39
import com .google .devtools .build .lib .actions .MetadataProvider ;
38
40
import com .google .devtools .build .lib .actions .cache .MetadataHandler ;
39
41
import 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 ;
40
45
import com .google .devtools .build .lib .remote .util .AsyncTaskCache ;
41
46
import com .google .devtools .build .lib .remote .util .RxUtils .TransferResult ;
42
47
import com .google .devtools .build .lib .remote .util .TempPathGenerator ;
63
68
public abstract class AbstractActionInputPrefetcher implements ActionInputPrefetcher {
64
69
private static final GoogleLogger logger = GoogleLogger .forEnclosingClass ();
65
70
71
+ private final Reporter reporter ;
66
72
private final AsyncTaskCache .NoResult <Path > downloadCache = AsyncTaskCache .NoResult .create ();
67
73
private final TempPathGenerator tempPathGenerator ;
68
74
protected final Set <Artifact > outputsAreInputs = Sets .newConcurrentHashSet ();
@@ -109,9 +115,11 @@ protected enum Priority {
109
115
}
110
116
111
117
protected AbstractActionInputPrefetcher (
118
+ Reporter reporter ,
112
119
Path execRoot ,
113
120
TempPathGenerator tempPathGenerator ,
114
121
ImmutableList <Pattern > patternsToDownload ) {
122
+ this .reporter = reporter ;
115
123
this .execRoot = execRoot ;
116
124
this .tempPathGenerator = tempPathGenerator ;
117
125
this .patternsToDownload = patternsToDownload ;
@@ -538,17 +546,33 @@ public void shutdown() {
538
546
}
539
547
}
540
548
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
+
541
562
@ SuppressWarnings ({"CheckReturnValue" , "FutureReturnValueIgnored" })
542
563
public void finalizeAction (Action action , MetadataHandler metadataHandler ) {
543
564
List <Artifact > inputsToDownload = new ArrayList <>();
544
565
List <Artifact > outputsToDownload = new ArrayList <>();
545
566
546
567
for (Artifact output : action .getOutputs ()) {
547
568
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 ()) {
552
576
var children = metadataHandler .getTreeArtifactChildren ((SpecialArtifact ) output );
553
577
for (var file : children ) {
554
578
if (outputMatchesPattern (file )) {
@@ -561,11 +585,42 @@ public void finalizeAction(Action action, MetadataHandler metadataHandler) {
561
585
}
562
586
563
587
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 ());
565
606
}
566
607
567
608
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 ());
569
624
}
570
625
}
571
626
0 commit comments