Skip to content

Commit c3a1efe

Browse files
committed
RandomlyForceCacheMissPercentage
1 parent 42baa9a commit c3a1efe

File tree

6 files changed

+29
-2
lines changed

6 files changed

+29
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ These settings are common across all plugins, although different implementations
5959
| `$(MSBuildCacheMaxConcurrentCacheContentOperations)` | `int` | 64 | The maximum number of cache operations to perform concurrently |
6060
| `$(MSBuildCacheLocalCacheRootPath)` | `string` | "\MSBuildCache" (in repo's drive root) | Base directory to use for the local cache. |
6161
| `$(MSBuildCacheLocalCacheSizeInMegabytes)` | `int` | 102400 (100 GB) | The maximum size in megabytes of the local cache |
62+
| `$(MSBuildCacheRandomlyForceCacheMissPercentage)` | `int` | 0 | The percentage of cache hits to force to be treated as cache misses. Useful for testing. |
6263
| `$(MSBuildCacheIgnoredInputPatterns)` | `Glob[]` | | Files which are part of the repo which should be ignored for cache invalidation |
6364
| `$(MSBuildCacheIgnoredOutputPatterns)` | `Glob[]` | `*.assets.cache; *assemblyreference.cache` | Files to ignore for output collection into the cache. Note that if output are ignored, the replayed cache entry will not have these files. This should be used for intermediate outputs which are not properly portable |
6465
| `$(MSBuildCacheIdenticalDuplicateOutputPatterns)` | `Glob[]` | | Files to allow duplicate outputs, with identical content, across projects. Projects which produce files at the same path with differing content will still produce an error. Note: this setting should be used sparingly as it impacts performance |

src/Common.Tests/PluginSettingsTests.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ public void LocalCacheSizeInMegabytesSetting()
9494
pluginSettings => pluginSettings.LocalCacheSizeInMegabytes,
9595
new[] { 123u, 456u, 789u });
9696

97+
[TestMethod]
98+
public void RandomlyForceCacheMissPercentageSetting()
99+
=> TestBasicSetting(
100+
nameof(PluginSettings.RandomlyForceCacheMissPercentage),
101+
pluginSettings => pluginSettings.RandomlyForceCacheMissPercentage,
102+
new[] { 0u, 10u, 100u });
103+
97104
private static IEnumerable<object[]> GlobTestData
98105
{
99106
get

src/Common/MSBuildCachePluginBase.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.IO;
1212
using System.Linq;
1313
using System.Reflection;
14+
using System.Security.Cryptography;
1415
using System.Text;
1516
using System.Text.Json;
1617
using System.Threading;
@@ -102,7 +103,8 @@ static MSBuildCachePluginBase() =>
102103
nameof(_fileAccessRepository),
103104
nameof(_cacheClient),
104105
nameof(_ignoredOutputPatterns),
105-
nameof(_identicalDuplicateOutputPatterns)
106+
nameof(_identicalDuplicateOutputPatterns),
107+
nameof(Settings)
106108
)]
107109
protected bool Initialized { get; private set; }
108110

@@ -347,6 +349,20 @@ private async Task<CacheResult> GetCacheResultInnerAsync(BuildRequestData buildR
347349
return CacheResult.IndicateNonCacheHit(CacheResultType.CacheMiss);
348350
}
349351

352+
if (Settings.RandomlyForceCacheMissPercentage > 0)
353+
{
354+
// use a hash of the project id so that it is repeatable
355+
#pragma warning disable CA1850 // ComputeHash is not in net472
356+
using SHA256 hasher = SHA256.Create();
357+
byte[] projectHash = hasher.ComputeHash(Encoding.UTF8.GetBytes(nodeContext.Id));
358+
#pragma warning restore CA1850
359+
if (BitConverter.ToUInt32(projectHash, 0) % 100 < Settings.RandomlyForceCacheMissPercentage)
360+
{
361+
Interlocked.Increment(ref _cacheMissCount);
362+
return CacheResult.IndicateNonCacheHit(CacheResultType.CacheMiss);
363+
}
364+
}
365+
350366
CheckForDuplicateOutputs(logger, nodeBuildResult.Outputs, nodeContext);
351367

352368
await FinishNodeAsync(logger, nodeContext, pathSet, nodeBuildResult);

src/Common/PluginSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ public string LocalCacheRootPath
8181

8282
public uint LocalCacheSizeInMegabytes { get; init; } = 102400; // 100GB
8383

84+
public uint RandomlyForceCacheMissPercentage { get; init; }
85+
8486
public IReadOnlyCollection<Glob> IgnoredInputPatterns { get; init; } = Array.Empty<Glob>();
8587

8688
public IReadOnlyCollection<Glob> IgnoredOutputPatterns { get; init; } = Array.Empty<Glob>();

src/Common/build/Microsoft.MSBuildCache.Common.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheMaxConcurrentCacheContentOperations</MSBuildCacheGlobalPropertiesToIgnore>
1111
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheLocalCacheRootPath</MSBuildCacheGlobalPropertiesToIgnore>
1212
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheLocalCacheSizeInMegabytes</MSBuildCacheGlobalPropertiesToIgnore>
13+
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheRandomlyForceCacheMissPercentage</MSBuildCacheGlobalPropertiesToIgnore>
1314
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheIgnoredInputPatterns</MSBuildCacheGlobalPropertiesToIgnore>
1415
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheIgnoredOutputPatterns</MSBuildCacheGlobalPropertiesToIgnore>
1516
<MSBuildCacheGlobalPropertiesToIgnore>$(MSBuildCacheGlobalPropertiesToIgnore);MSBuildCacheIdenticalDuplicateOutputPatterns</MSBuildCacheGlobalPropertiesToIgnore>
@@ -29,6 +30,7 @@
2930
<MaxConcurrentCacheContentOperations>$(MSBuildCacheMaxConcurrentCacheContentOperations)</MaxConcurrentCacheContentOperations>
3031
<LocalCacheRootPath>$(MSBuildCacheLocalCacheRootPath)</LocalCacheRootPath>
3132
<LocalCacheSizeInMegabytes>$(MSBuildCacheLocalCacheSizeInMegabytes)</LocalCacheSizeInMegabytes>
33+
<RandomlyForceCacheMissPercentage>$(MSBuildCacheRandomlyForceCacheMissPercentage)</RandomlyForceCacheMissPercentage>
3234
<IgnoredInputPatterns>$(MSBuildCacheIgnoredInputPatterns)</IgnoredInputPatterns>
3335
<IgnoredOutputPatterns>$(MSBuildCacheIgnoredOutputPatterns)</IgnoredOutputPatterns>
3436
<IdenticalDuplicateOutputPatterns>$(MSBuildCacheIdenticalDuplicateOutputPatterns)</IdenticalDuplicateOutputPatterns>

src/Local/MSBuildCacheLocalPlugin.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ protected override async Task<ICacheClient> CreateCacheClientAsync(PluginLoggerB
3838
#pragma warning restore CA2000 // Dispose objects before losing scope
3939
Context context = new(cacheLogger);
4040

41-
4241
#pragma warning disable CA2000 // Dispose objects before losing scope. Expected to be disposed by TwoLevelCache
4342
LocalCache cache = LocalCacheFactory.Create(cacheLogger, Settings.LocalCacheRootPath, Settings.LocalCacheSizeInMegabytes);
4443
#pragma warning restore CA2000 // Dispose objects before losing scope

0 commit comments

Comments
 (0)