-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Eliminate framework use of 'IJSUnmarshalledRuntime' #46693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note there are some E2E test failures. I have not looked into details yet.
public static void BeginInvokeDotNet(string callId, string assemblyNameOrDotNetObjectId, string methodIdentifier, string argsJson) | ||
[JSExport] | ||
[SupportedOSPlatform("browser")] | ||
public static void BeginInvokeDotNet(string? callId, string assemblyNameOrDotNetObjectId, string methodIdentifier, string argsJson) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a next step (could be next PR), this could be replaced by promise/Task instead of Begin/End pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that would be good. We did the begin/end thing because it predated support for Task
in the WebAssembly runtime's interop mechanism.
{ | ||
#pragma warning disable CS0618 // Type or member is obsolete | ||
var componentsCount = jsRuntime.InvokeUnmarshalled<int>(RegisteredComponentsInterop.GetRegisteredComponentsCount); | ||
var componentsCount = jsMethods.RegisteredComponents_GetRegisteredComponentsCount(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this is perf critical but if so, it could be re-implemented as passing int[] Ids
, string[] assemblies
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. However it's only a one-time thing that happens during startup, so my guess is that we wouldn't be able to observe any difference.
src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
Show resolved
Hide resolved
src/Components/WebAssembly/WebAssembly/src/HotReload/WebAssemblyHotReload.cs
Outdated
Show resolved
Hide resolved
@@ -5,14 +5,14 @@ | |||
import { DotNet } from '@microsoft/dotnet-js-interop'; | |||
import { Blazor } from './GlobalExports'; | |||
import * as Environment from './Environment'; | |||
import { byteArrayBeingTransferred, Module, BINDING, monoPlatform } from './Platform/Mono/MonoPlatform'; | |||
import { Module, BINDING, monoPlatform } from './Platform/Mono/MonoPlatform'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In next PR we could try re-invent how the goal of invokeJSFromDotNet
could be achieved otherwise.
To ged rid of things like BINDING.js_string_to_mono_string
src/Components/WebAssembly/WebAssembly/src/Rendering/WebAssemblyRenderer.cs
Show resolved
Hide resolved
["ThrowException"] = @"""System.InvalidOperationException: Threw an exception!", | ||
["ExceptionFromSyncMethod"] = "Function threw an exception!", | ||
["invokeDisposedJSObjectReferenceException"] = @"""Error: JS object instance with ID", | ||
["ThrowException"] = @"""Threw an exception!", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the exception type name still exposed on the JS side somehow? Seems like that would be valuable for debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, it looks like that information is lost now. The JavaScript errors that get created from exceptions thrown in [JSExport]
methods have a message
property equivalent to the C# exception's Message
property, which excludes the exception type and stack trace. We could fix this by catching exceptions on the .NET side and wrapping them in a new Exception
to simulate the old behavior, like:
try
{
return DotNetDispatcher.Invoke(Instance, callInfo, argsJson);
}
catch (Exception ex)
{
throw new Exception(ex.ToString(), ex);
}
Or I wonder if there's a way to address this on the runtime side, perhaps by updating ManagedError
to include information about the type of exception that got thrown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are just a proxy and could also cross the boundary back to managed.
Collecting stack trace is very very expensive and we do it when you call toString()
on it (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Collecting stack trace is very very expensive and we do it when you call toString() on it (I think)
@pavelsavara Does that mean we could change the JS-side code to call throw new Error(exceptionProxy.toString())
, and thereby get back the information we had before? Or is there some other mechanism you'd recommend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, please don't do that. It would be slow as you would pay the cost of stack trace creation also for exceptions which would be caught and handled silently.
We override the implementation of ManagedError.stack
property to provide it on demand.
I think error.toString()
and console.log(error)
would both include stack
property (at least on chrome). I'm open to suggestions how to improve it.
Proxy in the other direction is also lazy
If the E2E tests still pass locally but are timing out in CI, that's likely an unrelated issue which we're currently investigating, and you don't need to block this PR on it. TLDR is that the CI machines auto-updated to chromedriver 110, and we don't yet know why, but this suffers connection issues that were not present in chromedriver 109. Please verify locally though! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! I really like the improved simplicity.
…lyRenderer.cs Co-authored-by: Steve Sanderson <[email protected]>
src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts
Outdated
Show resolved
Hide resolved
I've validated the hot reload changes locally. |
I'm going to merge this now and address improvements in a follow-up PR. |
Hey, is this available in the latest .NET 8 preview? I want to be able to use CSP security in blazor wasm, thanks. |
Hi @ctigrisht. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context. |
Eliminate framework use of
IJSUnmarshalledRuntime
Removes internal usage of
IJSUnmarshalledRuntime
to in favor of[JSImport]
-style JavaScript interop.Description
IInternalJSImportMethods
interface that gives us a layer of abstraction over direct calls to[JSImport]
methods:TestInternalJSImportMethods
and updated tests to utilize it[JSImport]
methods that only make sense in an E2E context do not appear inIInternalJSImportMethods
IJSUnmarshalledRuntime
for:WebAssemblyNavigationManager
andWebAssemblyNavigationInterception
)WebAssemblyHostBuilder
)WebAssemblyHotReload
)InternalCalls
andWebAssemblyJSRuntime
)WebAssemblyRenderer
)Contributes to #37787 and #46673