Skip to content

Commit a42059b

Browse files
authored
[Blazor] Prepare for custom cache removal (#61666)
1 parent a4bf2d1 commit a42059b

File tree

6 files changed

+20
-118
lines changed

6 files changed

+20
-118
lines changed

src/Components/Web.JS/src/Services/WebRootComponentManager.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,10 +470,6 @@ function isDescriptorInDocument(descriptor: ComponentDescriptor): boolean {
470470
}
471471

472472
function areWebAssemblyResourcesLikelyCached(config: MonoConfig): boolean {
473-
if (!config.cacheBootResources) {
474-
return false;
475-
}
476-
477473
const hash = getWebAssemblyResourceHash(config);
478474
if (!hash) {
479475
return false;

src/Components/WebAssembly/Directory.Build.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@
77
<PropertyGroup>
88
<WasmPreloadAssets>false</WasmPreloadAssets>
99
</PropertyGroup>
10+
<PropertyGroup>
11+
<BlazorCacheBootResources>false</BlazorCacheBootResources>
12+
</PropertyGroup>
1013
</Project>

src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ public class BootResourceRequestLog
99
{
1010
private readonly ConcurrentBag<string> _requestPaths = new ConcurrentBag<string>();
1111

12-
public IReadOnlyCollection<string> RequestPaths => _requestPaths;
12+
public IReadOnlyCollection<string> RequestPathsWithNewContent => _requestPaths;
1313

14-
public void AddRequest(HttpRequest request)
14+
public void AddRequest(string originalRequestPath, HttpResponse response)
1515
{
16-
_requestPaths.Add(request.Path);
16+
if (response.StatusCode != StatusCodes.Status304NotModified)
17+
{
18+
_requestPaths.Add(originalRequestPath);
19+
}
1720
}
1821

1922
public void Clear()

src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,18 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, BootReso
2424
{
2525
var mapAlternativePathApp = Configuration.GetValue<bool>("UseAlternativeBasePath");
2626
var mapAllApps = Configuration.GetValue<bool>("MapAllApps");
27-
app.Use((context, next) =>
27+
app.Use(async (context, next) =>
2828
{
29+
string originalRequestPath = context.Request.Path;
30+
await next(context);
31+
2932
// This is used by E2E tests to verify that the correct resources were fetched,
3033
// and that it was possible to override the loading mechanism
3134
if (context.Request.Query.ContainsKey("customizedbootresource")
32-
|| context.Request.Headers.ContainsKey("customizedbootresource")
33-
|| context.Request.Path.Value.EndsWith("/blazor.boot.json", StringComparison.Ordinal))
35+
|| context.Request.Headers.ContainsKey("customizedbootresource"))
3436
{
35-
bootResourceRequestLog.AddRequest(context.Request);
37+
bootResourceRequestLog.AddRequest(originalRequestPath, context.Response);
3638
}
37-
return next(context);
3839
});
3940

4041
if (env.IsDevelopment())

src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs

Lines changed: 2 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests;
1919
public partial class BootResourceCachingTest
2020
: ServerTestBase<AspNetSiteServerFixture>
2121
{
22-
// The cache name is derived from the application's base href value (in this case, '/')
23-
private const string CacheName = "dotnet-resources-/";
24-
2522
public BootResourceCachingTest(
2623
BrowserFixture browserFixture,
2724
AspNetSiteServerFixture serverFixture,
@@ -56,114 +53,13 @@ public void CachesResourcesAfterFirstLoad()
5653
Navigate("/");
5754
WaitUntilLoaded();
5855
var subsequentResourcesRequested = GetAndClearRequestedPaths();
59-
Assert.DoesNotContain(subsequentResourcesRequested, path =>
60-
path.Contains("/dotnet.native.", StringComparison.Ordinal) &&
61-
path.EndsWith(".wasm", StringComparison.Ordinal));
62-
Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js", StringComparison.Ordinal)));
63-
Assert.DoesNotContain(subsequentResourcesRequested, path =>
64-
!path.Contains("/dotnet.native.", StringComparison.Ordinal) &&
65-
path.EndsWith(".wasm", StringComparison.Ordinal));
66-
}
67-
68-
[Fact]
69-
public async Task IncrementallyUpdatesCache()
70-
{
71-
// Perform a first load to populate the cache
72-
Navigate("/");
73-
WaitUntilLoaded();
74-
var cacheEntryUrls1 = GetCacheEntryUrls();
75-
var cacheEntryForComponentsDll = cacheEntryUrls1.Single(IsFingerprintedComponentsEntry);
76-
var cacheEntryForDotNetWasm = cacheEntryUrls1.Single(IsFingerprintedDotNetWasmEntry);
77-
var cacheEntryForDotNetWasmWithChangedHash = cacheEntryForDotNetWasm.Replace(".sha256-", ".sha256-different");
78-
79-
// Remove some items we do need, and add an item we don't need
80-
RemoveCacheEntry(cacheEntryForComponentsDll);
81-
RemoveCacheEntry(cacheEntryForDotNetWasm);
82-
AddCacheEntry(cacheEntryForDotNetWasmWithChangedHash, "ignored content");
83-
var cacheEntryUrls2 = GetCacheEntryUrls();
84-
Assert.DoesNotContain(cacheEntryForComponentsDll, cacheEntryUrls2);
85-
Assert.DoesNotContain(cacheEntryForDotNetWasm, cacheEntryUrls2);
86-
Assert.Contains(cacheEntryForDotNetWasmWithChangedHash, cacheEntryUrls2);
87-
88-
// On the next load, we'll fetch only the items we need (not things already cached)
89-
GetAndClearRequestedPaths();
90-
Navigate("about:blank");
91-
Browser.Equal(string.Empty, () => Browser.Title);
92-
Navigate("/");
93-
WaitUntilLoaded();
94-
var subsequentResourcesRequested = GetAndClearRequestedPaths();
95-
Assert.Collection(subsequentResourcesRequested.Where(url => url.Contains(".wasm")),
96-
requestedDll => Assert.True(IsFingerprintedComponentsEntry(requestedDll)),
97-
requestedDll => Assert.True(IsFingerprintedDotNetWasmEntry(requestedDll)));
98-
99-
var cacheEntryUrls3 = GetCacheEntryUrls();
100-
// wait until the cache was cleaned, max 500ms
101-
for (var i = 0; i < 5; i++)
102-
{
103-
if (!cacheEntryUrls3.Contains(cacheEntryForDotNetWasmWithChangedHash))
104-
{
105-
break;
106-
}
107-
await Task.Delay(100); // wait for cache purge
108-
cacheEntryUrls3 = GetCacheEntryUrls();
109-
}
110-
Assert.Contains(cacheEntryForComponentsDll, cacheEntryUrls3);
111-
Assert.Contains(cacheEntryForDotNetWasm, cacheEntryUrls3);
112-
Assert.DoesNotContain(cacheEntryForDotNetWasmWithChangedHash, cacheEntryUrls3);
113-
}
114-
115-
[GeneratedRegex("/Microsoft\\.AspNetCore\\.Components\\.\\w*\\.wasm")]
116-
private static partial Regex GetFingerprintedComponentsEntryRegex { get; }
117-
118-
[GeneratedRegex("/dotnet\\.native\\.\\w*\\.wasm")]
119-
private static partial Regex GetFingerprintedDotNetWasmEntryRegex { get; }
120-
121-
private static bool IsFingerprintedComponentsEntry(string url)
122-
=> GetFingerprintedComponentsEntryRegex.IsMatch(url);
123-
124-
private static bool IsFingerprintedDotNetWasmEntry(string url)
125-
=> GetFingerprintedDotNetWasmEntryRegex.IsMatch(url);
126-
127-
private IReadOnlyCollection<string> GetCacheEntryUrls()
128-
{
129-
var js = @"
130-
(async function(cacheName, completedCallback) {
131-
const cache = await caches.open(cacheName);
132-
const keys = await cache.keys();
133-
const urls = keys.map(r => r.url);
134-
completedCallback(urls);
135-
}).apply(null, arguments)";
136-
var jsExecutor = (IJavaScriptExecutor)Browser;
137-
var result = (IEnumerable<object>)jsExecutor.ExecuteAsyncScript(js, CacheName);
138-
return result.Cast<string>().ToList();
139-
}
140-
141-
private void RemoveCacheEntry(string url)
142-
{
143-
var js = @"
144-
(async function(cacheName, urlToRemove, completedCallback) {
145-
const cache = await caches.open(cacheName);
146-
await cache.delete(urlToRemove);
147-
completedCallback();
148-
}).apply(null, arguments)";
149-
((IJavaScriptExecutor)Browser).ExecuteAsyncScript(js, CacheName, url);
150-
}
151-
152-
private void AddCacheEntry(string url, string content)
153-
{
154-
var js = @"
155-
(async function(cacheName, urlToAdd, contentToAdd, completedCallback) {
156-
const cache = await caches.open(cacheName);
157-
await cache.put(urlToAdd, new Response(contentToAdd));
158-
completedCallback();
159-
}).apply(null, arguments)";
160-
((IJavaScriptExecutor)Browser).ExecuteAsyncScript(js, CacheName, url, content);
56+
Assert.Empty(subsequentResourcesRequested);
16157
}
16258

16359
private IReadOnlyCollection<string> GetAndClearRequestedPaths()
16460
{
16561
var requestLog = _serverFixture.Host.Services.GetRequiredService<BootResourceRequestLog>();
166-
var result = requestLog.RequestPaths.ToList();
62+
var result = requestLog.RequestPathsWithNewContent.ToList();
16763
requestLog.Clear();
16864
return result;
16965
}

src/Components/test/testassets/Directory.Build.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@
2222
<PropertyGroup>
2323
<WasmPreloadAssets>false</WasmPreloadAssets>
2424
</PropertyGroup>
25+
<PropertyGroup>
26+
<BlazorCacheBootResources>false</BlazorCacheBootResources>
27+
</PropertyGroup>
2528
</Project>

0 commit comments

Comments
 (0)