Skip to content
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

DragNDrop SSB Race Condition #71

Closed
srowan opened this issue Aug 30, 2019 · 3 comments · Fixed by #73
Closed

DragNDrop SSB Race Condition #71

srowan opened this issue Aug 30, 2019 · 3 comments · Fixed by #73
Labels
bug Something isn't working

Comments

@srowan
Copy link

srowan commented Aug 30, 2019

  • Server side blazor
  • Similar code to the dragndrop example
  • Getting the following error randomly on refresh (about 30%-50% of the time):
      Unhandled exception rendering component: Could not find 'FileReaderComponent' in 'window'.
Error: Could not find 'FileReaderComponent' in 'window'.

The error occurs on: RegisterDropEventsAsync(); :

       protected override async Task OnAfterRenderAsync()
        {
            labelFilesReference = fileReaderService.CreateReference(labelElement);
            await labelFilesReference.RegisterDropEventsAsync();
        }

I do have InitializeOnFirstCall enabled, but I also tried this as well:

       protected override async Task OnAfterRenderAsync()
        {
            await fileReaderService.EnsureInitializedAsync();
            labelFilesReference = fileReaderService.CreateReference(labelElement);
            await labelFilesReference.RegisterDropEventsAsync();
        }

... and still received the error (same frequency). Adding Task.Delay did not help.

Retrying when it fails fixes the issue, which I think is probably evidence that there is a race condition here (which could mean the problem can only be replicated at very low latency e.g. local development).

This works:

        protected override async Task OnAfterRenderAsync()
        {
            labelFilesReference = fileReaderService.CreateReference(labelElement);
            try
            {
                await labelFilesReference.RegisterDropEventsAsync();
            }
            catch (JSException ex)
            when (ex.Message.Contains("Could not find 'FileReaderComponent' in 'window'"))
            {
                // failed race condition, just try again
                await labelFilesReference.RegisterDropEventsAsync();
            }
        }
@srowan srowan changed the title DragNDrop SSB Race Condition (warn: Microsoft.AspNetCore.Components.Web.Rendering.RemoteRenderer[100] Unhandled exception rendering component: Could not find 'FileReaderComponent' in 'window'. Error: Could not find 'FileReaderComponent' in 'window'.) DragNDrop SSB Race Condition Aug 30, 2019
@Tewr
Copy link
Owner

Tewr commented Aug 30, 2019

Thank you for your report.

I suspect something like prerendering
dotnet/aspnetcore#11876 but it's quite odd, doesn't really fit the bill. However, the drag and drop is the only example which does jsinvoke in afterrender.

Could you try disabling the prerendering and see if it helps? from https://docs.microsoft.com/en-us/aspnet/core/blazor/state-management?view=aspnetcore-3.0:

To disable prerendering:

  1. Open the _Pages/Host.cshtml file and remove the call to Html.RenderComponentAsync.
  2. Open the Startup.cs file and replace the call to endpoints.MapBlazorHub() with endpoints.MapBlazorHub<App>("app"). App is the type of the root component. "app" is a CSS selector specifying the location for the root component.

If this can be confirmed, I should probably add an alternative setup method for SSB in the demo project ( webBuilder.UseStaticWebAssets() etc), still, setting up js events with prerendering is a bit of a hassle

@Tewr Tewr added the bug Something isn't working label Aug 30, 2019
@srowan
Copy link
Author

srowan commented Aug 30, 2019

I actually already have pre-rendering disabled. I never had a problem with the loading time of SSB (way faster than any angular application I've ever written) and it only caused me headaches :)

@Tewr
Copy link
Owner

Tewr commented Aug 30, 2019

Effectively, I can reproduce this without prerendering so please disregard my previous comment. The problem is, like you say, a race condition in the FileReaderJsInterop.EnsureInitializedAsync method which happens occasionally, when the browser server has cached everything really well and executes the code which comes after faster than the script blob has been loaded in the browser context.

A possible fix that I've tried which works is to block asyncronically for a few ms and check if the script has been loaded. I find this fix unnerving because I have set script.async to false, and despite this, the script is apparently not always loaded when the eval ends...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants