@@ -43,6 +43,11 @@ Task<BoolResult> IncorporateStrongFingerprintsAsync(
43
43
/// <nodoc />
44
44
public interface ICachePublisher : IStartupShutdownSlim
45
45
{
46
+ /// <summary>
47
+ /// Gets the unique GUID for the given cache.
48
+ /// </summary>
49
+ Guid CacheGuid { get ; }
50
+
46
51
/// <summary>
47
52
/// Add a content hash list.
48
53
/// </summary>
@@ -76,11 +81,21 @@ public Task<IEnumerable<Task<Indexed<PinResult>>>> PinAsync(
76
81
Task < BoolResult > IncorporateStrongFingerprintsAsync (
77
82
OperationContext context ,
78
83
IEnumerable < Task < StrongFingerprint > > strongFingerprints ) ;
84
+
85
+ /// <nodoc />
86
+ Task < GetContentHashListResult > GetContentHashListAsync (
87
+ Context context ,
88
+ StrongFingerprint strongFingerprint ,
89
+ CancellationToken cts ,
90
+ UrgencyHint urgencyHint = UrgencyHint . Nominal ) ;
79
91
}
80
92
81
93
/// <nodoc />
82
94
public class CacheSessionPublisherWrapper : StartupShutdownSlimBase , ICachePublisher
83
95
{
96
+ /// <nodoc />
97
+ public Guid CacheGuid => _cache . Id ;
98
+
84
99
/// <nodoc />
85
100
protected override Tracer Tracer { get ; } = new Tracer ( nameof ( CacheSessionPublisherWrapper ) ) ;
86
101
@@ -134,6 +149,12 @@ public Task<BoolResult> IncorporateStrongFingerprintsAsync(OperationContext cont
134
149
{
135
150
return _session . IncorporateStrongFingerprintsAsync ( context , strongFingerprints , context . Token ) ;
136
151
}
152
+
153
+ /// <nodoc />
154
+ public Task < GetContentHashListResult > GetContentHashListAsync ( Context context , StrongFingerprint strongFingerprint , CancellationToken cts , UrgencyHint urgencyHint = UrgencyHint . Nominal )
155
+ {
156
+ return _session . GetContentHashListAsync ( context , strongFingerprint , cts , urgencyHint ) ;
157
+ }
137
158
}
138
159
139
160
/// <nodoc />
@@ -223,12 +244,27 @@ public Task<BoolResult> PublishContentHashListAsync(
223
244
( timeSpentWaiting , gateCount ) =>
224
245
{
225
246
ContentHashList ? hashListInRemote = null ;
247
+ bool publishSkipped = false ;
226
248
return context . PerformOperationAsync (
227
249
Tracer ,
228
250
async ( ) =>
229
251
{
252
+ var remoteResult = await _cachePublisher . GetContentHashListAsync ( context , fingerprint , context . Token ) ;
253
+ var localContentHashList = contentHashList . ContentHashList ;
254
+ var remoteContentHashList = remoteResult . ContentHashListWithDeterminism . ContentHashList ;
255
+ var isRemoteBacked = remoteResult . Succeeded
256
+ && ( remoteResult . ContentHashListWithDeterminism . Determinism . IsDeterministicTool
257
+ || remoteResult . ContentHashListWithDeterminism . Determinism . EffectiveGuid . Equals ( _cachePublisher . CacheGuid ) ) ;
258
+
259
+ // Skip publishing when local CHL matches remote CHL & the remote is backed.
260
+ if ( localContentHashList . Equals ( remoteContentHashList ) && isRemoteBacked )
261
+ {
262
+ publishSkipped = true ;
263
+ return BoolResult . Success ;
264
+ }
265
+
230
266
// Make sure to push the blob in the selector if it exists.
231
- var hashesToPush = new List < ContentHash > ( contentHashList . ContentHashList . Hashes ) ;
267
+ var hashesToPush = new List < ContentHash > ( localContentHashList . Hashes ) ;
232
268
if ( ! fingerprint . Selector . ContentHash . IsZero ( ) )
233
269
{
234
270
hashesToPush . Add ( fingerprint . Selector . ContentHash ) ;
@@ -252,7 +288,8 @@ public Task<BoolResult> PublishContentHashListAsync(
252
288
} ,
253
289
traceOperationStarted : false ,
254
290
extraEndMessage : result =>
255
- $ "Added=[{ result . Succeeded && hashListInRemote is null } ], " +
291
+ $ "Skipped=[{ publishSkipped } ], " +
292
+ $ "Added=[{ result . Succeeded && hashListInRemote is null && ! publishSkipped } ], " +
256
293
$ "StrongFingerprint=[{ fingerprint } ], " +
257
294
$ "ContentHashList=[{ contentHashList . ToTraceString ( ) } ], " +
258
295
$ "TimeSpentWaiting=[{ timeSpentWaiting } ], " +
0 commit comments