From 0be52723019a330e687a402578fe8376e4a24660 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 24 Feb 2023 17:33:15 +0100 Subject: [PATCH 1/4] fix assets counting --- src/mono/wasm/runtime/assets.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index 80d63429102938..6805406e1b46ff 100644 --- a/src/mono/wasm/runtime/assets.ts +++ b/src/mono/wasm/runtime/assets.ts @@ -76,9 +76,11 @@ export async function mono_download_assets(): Promise { asset.pendingDownloadInternal = asset.pendingDownload; const waitForExternalData: () => Promise = async () => { const response = await asset.pendingDownloadInternal!.response; - ++actual_downloaded_assets_count; if (!headersOnly) { asset.buffer = await response.arrayBuffer(); + ++actual_downloaded_assets_count; + } else { + ++actual_downloaded_assets_count; } return { asset, buffer: asset.buffer }; }; @@ -122,6 +124,10 @@ export async function mono_download_assets(): Promise { if (!skipInstantiateByAssetTypes[asset.behavior]) { expected_instantiated_assets_count--; } + } else { + if (skipBufferByAssetTypes[asset.behavior]) { + ++actual_downloaded_assets_count; + } } } })()); @@ -197,7 +203,9 @@ async function start_asset_download_with_throttle(asset: AssetEntry, downloadDat if (!downloadData || !response) { return undefined; } - return await response.arrayBuffer(); + const buffer = await response.arrayBuffer(); + ++actual_downloaded_assets_count; + return buffer; } finally { --parallel_count; @@ -226,7 +234,6 @@ async function start_asset_download_sources(asset: AssetEntryInternal): Promise< } }) as any }; - ++actual_downloaded_assets_count; return asset.pendingDownloadInternal.response; } if (asset.pendingDownloadInternal && asset.pendingDownloadInternal.response) { @@ -262,7 +269,6 @@ async function start_asset_download_sources(asset: AssetEntryInternal): Promise< if (!response.ok) { continue;// next source } - ++actual_downloaded_assets_count; return response; } catch (err) { @@ -293,7 +299,7 @@ function resolve_path(asset: AssetEntry, sourcePrefix: string): string { : asset.name; } else if (asset.behavior === "resource") { - const path = asset.culture !== "" ? `${asset.culture}/${asset.name}` : asset.name; + const path = asset.culture && asset.culture !== "" ? `${asset.culture}/${asset.name}` : asset.name; attemptUrl = assemblyRootFolder ? (assemblyRootFolder + "/" + path) : path; @@ -420,7 +426,7 @@ function _instantiate_asset(asset: AssetEntry, url: string, bytes: Uint8Array) { Module.printErr(`MONO_WASM: Error loading ICU asset ${asset.name}`); } else if (asset.behavior === "resource") { - cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture!, offset!, bytes.length); + cwraps.mono_wasm_add_satellite_assembly(virtualName, asset.culture || "", offset!, bytes.length); } ++actual_instantiated_assets_count; } @@ -429,10 +435,10 @@ export async function instantiate_wasm_asset( pendingAsset: AssetEntryInternal, wasmModuleImports: WebAssembly.Imports, successCallback: InstantiateWasmSuccessCallback, -) { - mono_assert(pendingAsset && pendingAsset.pendingDownloadInternal, "Can't load dotnet.wasm"); +): Promise { + mono_assert(pendingAsset && pendingAsset.pendingDownloadInternal && pendingAsset.pendingDownloadInternal.response, "Can't load dotnet.wasm"); const response = await pendingAsset.pendingDownloadInternal.response; - const contentType = response.headers ? response.headers.get("Content-Type") : undefined; + const contentType = response.headers && response.headers.get ? response.headers.get("Content-Type") : undefined; let compiledInstance: WebAssembly.Instance; let compiledModule: WebAssembly.Module; if (typeof WebAssembly.instantiateStreaming === "function" && contentType === "application/wasm") { From 6d33f7556c99e73ec3cf952cd8d0221def87f52b Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 27 Feb 2023 16:46:38 +0100 Subject: [PATCH 2/4] test that we could retry asset downloads --- .../wasm/browser/Wasm.Browser.Sample.csproj | 2 +- src/mono/sample/wasm/browser/main.js | 14 ++++++++++ src/mono/sample/wasm/simple-server/Program.cs | 26 ++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj index 817971712ae5fe..c1eca5280663e1 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.Sample.csproj @@ -14,5 +14,5 @@ <_SampleProject>Wasm.Browser.Sample.csproj - + diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index afe23356a73951..560fda61a6d36f 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -8,12 +8,26 @@ function sub(a, b) { return a - b; } +let testError = true; +let testRetry = true; try { const { runtimeBuildInfo, setModuleImports, getAssemblyExports, runMain, getConfig } = await dotnet .withConsoleForwarding() .withElementOnExit() .withModuleConfig({ configSrc: "./mono-config.json", + locateFile: (url) => { + // we are testing that we can retry loading of the assembly + if (testRetry && url.indexOf('System.Private.Uri.dll') != -1) { + testRetry = false; + return url + "?testAbort=true"; + } + if (testError && url.indexOf('System.Console.dll') != -1) { + testError = false; + return url + "?testError=true"; + } + return url; + }, onConfigLoaded: (config) => { // This is called during emscripten `dotnet.wasm` instantiation, after we fetched config. console.log('user code Module.onConfigLoaded'); diff --git a/src/mono/sample/wasm/simple-server/Program.cs b/src/mono/sample/wasm/simple-server/Program.cs index 70ef1e573093f1..7a26f4406fb0dd 100644 --- a/src/mono/sample/wasm/simple-server/Program.cs +++ b/src/mono/sample/wasm/simple-server/Program.cs @@ -159,12 +159,36 @@ private async void ServeAsync(HttpListenerContext context) if (path.EndsWith(".js") || path.EndsWith(".mjs") || path.EndsWith(".cjs")) contentType = "text/javascript"; + var stream = context.Response.OutputStream; + + // test download re-try + if (url.Query.Contains("testError")) + { + Console.WriteLine("Faking 500 " + url); + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + await stream.WriteAsync(buffer, 0, 0).ConfigureAwait(false); + await stream.FlushAsync(); + context.Response.Close(); + return; + } + if (contentType != null) context.Response.ContentType = contentType; context.Response.ContentLength64 = buffer.Length; context.Response.AppendHeader("cache-control", "public, max-age=31536000"); - var stream = context.Response.OutputStream; + + // test download re-try + if (url.Query.Contains("testAbort")) + { + Console.WriteLine("Faking abort " + url); + await stream.WriteAsync(buffer, 0, 10).ConfigureAwait(false); + await stream.FlushAsync(); + await Task.Delay(100); + context.Response.Abort(); + return; + } + try { await stream.WriteAsync(buffer).ConfigureAwait(false); From 36100b2ad8a6c484e336a19f59bda321c155b1ba Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 27 Feb 2023 18:17:21 +0100 Subject: [PATCH 3/4] nicer --- src/mono/sample/wasm/browser/main.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index 560fda61a6d36f..cf71a8e416b30b 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -9,24 +9,26 @@ function sub(a, b) { } let testError = true; -let testRetry = true; +let testAbort = true; try { const { runtimeBuildInfo, setModuleImports, getAssemblyExports, runMain, getConfig } = await dotnet .withConsoleForwarding() .withElementOnExit() .withModuleConfig({ configSrc: "./mono-config.json", - locateFile: (url) => { - // we are testing that we can retry loading of the assembly - if (testRetry && url.indexOf('System.Private.Uri.dll') != -1) { - testRetry = false; - return url + "?testAbort=true"; + imports: { + fetch: (url, fetchArgs) => { + // we are testing that we can retry loading of the assembly + if (testAbort && url.indexOf('System.Private.Uri.dll') != -1) { + testAbort = false; + return fetch(url + "?testAbort=true", fetchArgs); + } + if (testError && url.indexOf('System.Console.dll') != -1) { + testError = false; + return fetch(url + "?testError=true", fetchArgs); + } + return fetch(url, fetchArgs); } - if (testError && url.indexOf('System.Console.dll') != -1) { - testError = false; - return url + "?testError=true"; - } - return url; }, onConfigLoaded: (config) => { // This is called during emscripten `dotnet.wasm` instantiation, after we fetched config. From a4b13641ec5c68811c79284f0c0024311855026d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 28 Feb 2023 12:01:56 +0100 Subject: [PATCH 4/4] feedback --- src/mono/wasm/runtime/assets.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index 6805406e1b46ff..8e3630188ddbfb 100644 --- a/src/mono/wasm/runtime/assets.ts +++ b/src/mono/wasm/runtime/assets.ts @@ -78,10 +78,8 @@ export async function mono_download_assets(): Promise { const response = await asset.pendingDownloadInternal!.response; if (!headersOnly) { asset.buffer = await response.arrayBuffer(); - ++actual_downloaded_assets_count; - } else { - ++actual_downloaded_assets_count; } + ++actual_downloaded_assets_count; return { asset, buffer: asset.buffer }; }; promises_of_assets_with_buffer.push(waitForExternalData());