Skip to content

Commit ee4ac99

Browse files
committed
Merged PR 684749: Add support for async publishing to remote in GetCHL and AddOrGetCHL
Publish CHLs to remote for GetCHL and AddOrGetCHL (that results in a GetCHL) calls if the CHLs differ between local and remote. If the CHLs match but the remote is not backed, then pin the CHLs to remote. Related [query](https://dataexplorer.azure.com/clusters/cbuild/databases/CloudBuildCBTest?query=H4sIAAAAAAAAA2WRwW7CMAxA7/sKq+KwSc3UplkhB6YJmLRKjKHBbrukiduGlaRKAxPSPn6lQmyIq+1nP9vT2u7UVMgK57Z83qPxNz/wXaFDWDqUusW13uLKi20DjyBKexuru3PJZKdrlSkYjyFQCUuilCeEJZQSFudIOM8l4RhLpVJBWYTBmZxa57AWXltz4nlCIyxGHcAfkDCa5mRUJJykRao4kyrK6fDIb6w28KWNGmtj0MFauBJ9ZgoL1sCgxsLf//MaOF1Wp8gK27YfeNZYWIXrQ4O9weQjm8/+FN97vz0uha+O+aegcXovPH7OrF+gZ0OamdaLukZ1pBpnNyj91d3Ci07h5eohvIi2WnmnTRnCW4OuT4Tw2rmKEru+1qluzfxw/RDRyl8Q2oGqwAEAAA==) for a successful GetCHL call + publishing scenario.
1 parent a397af2 commit ee4ac99

File tree

5 files changed

+89
-8
lines changed

5 files changed

+89
-8
lines changed

Public/Src/Cache/MemoizationStore/Distributed/Sessions/PublishingCacheSession.cs

+35-6
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,47 @@ public async Task<AddOrGetContentHashListResult> AddOrGetContentHashListAsync(Co
110110
return result;
111111
}
112112

113+
/// <inheritdoc />
114+
public async Task<GetContentHashListResult> GetContentHashListAsync(Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal)
115+
{
116+
var operationContext = TrackShutdown(new OperationContext(context, cts));
117+
var cancellationForPublish = _publishAsynchronously
118+
? ShutdownStartedCancellationToken
119+
: operationContext.Context.Token;
120+
121+
var localResult = await _local.GetContentHashListAsync(context, strongFingerprint, cts, urgencyHint);
122+
if (localResult.Succeeded && localResult.ContentHashListWithDeterminism.ContentHashList is not null)
123+
{
124+
var publishTask = PublishContentHashListAsync(
125+
context,
126+
strongFingerprint,
127+
localResult.ContentHashListWithDeterminism,
128+
cancellationForPublish);
129+
130+
if (_publishAsynchronously)
131+
{
132+
publishTask.FireAndForget(context, traceErrorResult: true, operation: nameof(PublishContentHashListAsync));
133+
}
134+
else
135+
{
136+
var publishingResult = await publishTask;
137+
if (!publishingResult.Succeeded)
138+
{
139+
return new GetContentHashListResult(publishingResult);
140+
}
141+
}
142+
}
143+
144+
return localResult;
145+
}
146+
113147
private async Task<BoolResult> PublishContentHashListAsync(
114148
Context context,
115149
StrongFingerprint strongFingerprint,
116150
ContentHashListWithDeterminism contentHashList,
117151
CancellationToken token)
118152
{
153+
await Task.Yield();
119154
Contract.Assert(!_hasBeenMarkedForShutdown, "Should not queue publish operations after the session has been marked for shutdown");
120155

121156
var publishingOperation = new PublishingOperation
@@ -172,12 +207,6 @@ public IAsyncEnumerable<GetSelectorResult> GetSelectors(Context context, Fingerp
172207
return _local.GetSelectors(context, weakFingerprint, cts, urgencyHint);
173208
}
174209

175-
/// <inheritdoc />
176-
public Task<GetContentHashListResult> GetContentHashListAsync(Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal)
177-
{
178-
return _local.GetContentHashListAsync(context, strongFingerprint, cts, urgencyHint);
179-
}
180-
181210
/// <inheritdoc />
182211
public Task<PinResult> PinAsync(Context context, ContentHash contentHash, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal)
183212
{

Public/Src/Cache/MemoizationStore/DistributedTest/BuildCachePublishingCacheTests.cs

+13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33

44
#if MICROSOFT_INTERNAL
5+
using System;
56
using System.Collections.Generic;
67
using System.IO;
78
using System.Linq;
@@ -96,6 +97,8 @@ public DummyPublisher(bool forceUpdate)
9697
_forceUpdate = forceUpdate;
9798
}
9899

100+
public Guid CacheGuid => Guid.Empty;
101+
99102
protected override Tracer Tracer { get; } = new Tracer(nameof(DummyPublisher));
100103

101104
public Task<AddOrGetContentHashListResult> AddOrGetContentHashListAsync(
@@ -126,6 +129,16 @@ public Task<AddOrGetContentHashListResult> AddOrGetContentHashListAsync(
126129
return Task.FromResult(new AddOrGetContentHashListResult(_storedHashLists[strongFingerprint]));
127130
}
128131

132+
public Task<GetContentHashListResult> GetContentHashListAsync(Context context, StrongFingerprint strongFingerprint, CancellationToken cts, UrgencyHint urgencyHint = UrgencyHint.Nominal)
133+
{
134+
if (_storedHashLists.ContainsKey(strongFingerprint))
135+
{
136+
return Task.FromResult(new GetContentHashListResult(_storedHashLists[strongFingerprint]));
137+
};
138+
139+
return Task.FromResult(new GetContentHashListResult(default(ContentHashListWithDeterminism)));
140+
}
141+
129142
public Task<BoolResult> IncorporateStrongFingerprintsAsync(OperationContext context, IEnumerable<Task<StrongFingerprint>> strongFingerprints)
130143
{
131144
return BoolResult.SuccessTask;

Public/Src/Cache/MemoizationStore/Interfaces/Sessions/IPublishingSession.cs

+39-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ Task<BoolResult> IncorporateStrongFingerprintsAsync(
4343
/// <nodoc />
4444
public interface ICachePublisher : IStartupShutdownSlim
4545
{
46+
/// <summary>
47+
/// Gets the unique GUID for the given cache.
48+
/// </summary>
49+
Guid CacheGuid { get; }
50+
4651
/// <summary>
4752
/// Add a content hash list.
4853
/// </summary>
@@ -76,11 +81,21 @@ public Task<IEnumerable<Task<Indexed<PinResult>>>> PinAsync(
7681
Task<BoolResult> IncorporateStrongFingerprintsAsync(
7782
OperationContext context,
7883
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);
7991
}
8092

8193
/// <nodoc />
8294
public class CacheSessionPublisherWrapper : StartupShutdownSlimBase, ICachePublisher
8395
{
96+
/// <nodoc />
97+
public Guid CacheGuid => _cache.Id;
98+
8499
/// <nodoc />
85100
protected override Tracer Tracer { get; } = new Tracer(nameof(CacheSessionPublisherWrapper));
86101

@@ -134,6 +149,12 @@ public Task<BoolResult> IncorporateStrongFingerprintsAsync(OperationContext cont
134149
{
135150
return _session.IncorporateStrongFingerprintsAsync(context, strongFingerprints, context.Token);
136151
}
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+
}
137158
}
138159

139160
/// <nodoc />
@@ -223,12 +244,27 @@ public Task<BoolResult> PublishContentHashListAsync(
223244
(timeSpentWaiting, gateCount) =>
224245
{
225246
ContentHashList? hashListInRemote = null;
247+
bool publishSkipped = false;
226248
return context.PerformOperationAsync(
227249
Tracer,
228250
async () =>
229251
{
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+
230266
// 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);
232268
if (!fingerprint.Selector.ContentHash.IsZero())
233269
{
234270
hashesToPush.Add(fingerprint.Selector.ContentHash);
@@ -252,7 +288,8 @@ public Task<BoolResult> PublishContentHashListAsync(
252288
},
253289
traceOperationStarted: false,
254290
extraEndMessage: result =>
255-
$"Added=[{result.Succeeded && hashListInRemote is null}], " +
291+
$"Skipped=[{publishSkipped}], " +
292+
$"Added=[{result.Succeeded && hashListInRemote is null && !publishSkipped}], " +
256293
$"StrongFingerprint=[{fingerprint}], " +
257294
$"ContentHashList=[{contentHashList.ToTraceString()}], " +
258295
$"TimeSpentWaiting=[{timeSpentWaiting}], " +

Public/Src/Cache/MemoizationStore/Library/Stores/AzureBlobStoragePublishingSession.cs

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ protected override async Task<ICachePublisher> CreateCachePublisherCoreAsync(
6262
Credentials = credentials,
6363
});
6464

65+
// TODO: Implement force publishing for blob L3
6566
var database = new MetadataStoreMemoizationDatabase(blobMetadataStore);
6667
var memoizationStore = new DatabaseMemoizationStore(database);
6768

Public/Src/Cache/MemoizationStore/Vsts/BuildCachePublishingSession.cs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ protected override async Task<ICachePublisher> CreateCachePublisherCoreAsync(Ope
5656
helper: null,
5757
logger: m => Tracer.Info(context, m));
5858

59+
configuration.BuildCacheConfiguration.ForceUpdateOnAddContentHashList = true;
5960
var cache = BuildCacheCacheFactory.Create(
6061
PassThroughFileSystem.Default,
6162
context.TracingContext.Logger,

0 commit comments

Comments
 (0)