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

Cosmos client fails in Blazor WebAssembly app #1429

Closed
JeremyLikness opened this issue Apr 24, 2020 · 7 comments
Closed

Cosmos client fails in Blazor WebAssembly app #1429

JeremyLikness opened this issue Apr 24, 2020 · 7 comments

Comments

@JeremyLikness
Copy link

Describe the bug
When instantiating an instance of CosmosClient in a Blazor WebAssembly app, the constructor throws an exception:

System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime.

To Reproduce
Create a new Blazor WebAssembly project. I used the latest preview (3.2.0 preview 5). Install Microsoft.Azure.Cosmos (I used 3.7.0-preview). In Program.Main add the following code anywhere:

var client = new CosmosClient(
   "[CosmosEndpoint]",
  "[CosmosKey]",
  new CosmosClientOptions()
  {
     ConnectionMode = ConnectionMode.Gateway,
     LimitToEndpoint = true
   });

Replace the endpoint and key with an actual endpoint/key. The error will throw immediately.

Expected behavior
I would expect to be able to use the Cosmos client SDK from a Blazor client in gateway mode as it is simply HTTP.

Actual behavior
The client throws, likely due to using an invalid HttpClient instead of the one provided by Blazor via DI.

Environment summary
SDK Version: 3.7.0-preview
OS Version: Windows 10
Visual Studio Version: 16.6.0 preview 4.0
.NET Core Version: 5.0.100-preview.3.20216.6
Blazor Version: 3.2.0-preview5.20216.8

Additional context
Full call stack from exception:

System.Threading.SynchronizationLockException: Cannot wait on monitors on this runtime.
blazor.webassembly.js:1 at (wrapper managed-to-native) System.Threading.Monitor.Monitor_wait(object,int)
blazor.webassembly.js:1 at System.Threading.Monitor.ObjWait (System.Boolean exitContext, System.Int32 millisecondsTimeout, System.Object obj) <0x2fd5d88 + 0x00046> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout, System.Boolean exitContext) <0x2fd5aa8 + 0x00022> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Monitor.Wait (System.Object obj, System.Int32 millisecondsTimeout) <0x2fd59e0 + 0x0000a> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.ManualResetEventSlim.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x2fd5060 + 0x001be> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Tasks.Task.SpinThenBlockingWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x2fd15f8 + 0x00072> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Tasks.Task.InternalWait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x2fd0f68 + 0x000ca> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Tasks.Task.Wait (System.Int32 millisecondsTimeout, System.Threading.CancellationToken cancellationToken) <0x2fad5a0 + 0x00036> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Threading.Tasks.Task.Wait () <0x2fad2e0 + 0x00018> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Net.ServicePointScheduler+AsyncManualResetEvent.Set () <0x2facb90 + 0x0007a> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Net.ServicePointScheduler.Run () <0x2fc0760 + 0x00034> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Net.ServicePointScheduler.set_ConnectionLimit (System.Int32 value) <0x2fc0600 + 0x00030> in <filename unknown>:0 
blazor.webassembly.js:1 at System.Net.ServicePoint.set_ConnectionLimit (System.Int32 value) <0x2fc0490 + 0x00024> in <filename unknown>:0 
blazor.webassembly.js:1 at Microsoft.Azure.Cosmos.DocumentClient.Initialize (System.Uri serviceEndpoint, Microsoft.Azure.Cosmos.ConnectionPolicy connectionPolicy, System.Nullable`1[T] desiredConsistencyLevel, System.Net.Http.HttpMessageHandler handler, Microsoft.Azure.Documents.ISessionContainer sessionContainer, System.Nullable`1[T] enableCpuMonitor, Microsoft.Azure.Documents.IStoreClientFactory storeClientFactory) <0x2f8f418 + 0x00832> in <filename unknown>:0 
blazor.webassembly.js:1 at Microsoft.Azure.Cosmos.DocumentClient..ctor (System.Uri serviceEndpoint, System.String authKeyOrResourceToken, System.EventHandler`1[TEventArgs] sendingRequestEventArgs, Microsoft.Azure.Cosmos.ConnectionPolicy connectionPolicy, System.Nullable`1[T] desiredConsistencyLevel, Newtonsoft.Json.JsonSerializerSettings serializerSettings, Microsoft.Azure.Documents.ApiType apitype, System.EventHandler`1[TEventArgs] receivedResponseEventArgs, System.Net.Http.HttpMessageHandler handler, Microsoft.Azure.Documents.ISessionContainer sessionContainer, System.Nullable`1[T] enableCpuMonitor, System.Func`2[T,TResult] transportClientHandlerFactory, Microsoft.Azure.Documents.IStoreClientFactory storeClientFactory) <0x2f6d870 + 0x0015a> in <filename unknown>:0 
blazor.webassembly.js:1 at Microsoft.Azure.Cosmos.CosmosClient..ctor (System.String accountEndpoint, System.String authKeyOrResourceToken, Microsoft.Azure.Cosmos.CosmosClientOptions clientOptions) <0x2f0df48 + 0x00166> in <filename unknown>:0 
blazor.webassembly.js:1 at BlazorApp1.Program.Main (System.String[] args) [0x000cb] in c:\temp\BlazorApp1\BlazorApp1\Program.cs:28 
blazor.webassembly.js:1 at Microsoft.AspNetCore.Components.WebAssembly.Hosting.EntrypointInvoker.InvokeEntrypoint (System.String assemblyName, System.String[] args, Microsoft.AspNetCore.Components.WebAssembly.Hosting.SatelliteResourcesLoader satelliteResourcesLoader) <0x2c25360 + 0x001ec> in <filename unknown>:0 
@Lupusa87
Copy link

I think it can be fixed by mono team, their mono wasm sdk is responsible to run regular .net libraries like cosmos client in browser.
I encourage you to open same issue there to.
Good luck.

@j82w
Copy link
Contributor

j82w commented Apr 25, 2020

I haven't tested it with the latest preview yet, but it seems to be working with the current version of Blazor. Please check out the PR adding it as a sample.

@JeremyLikness
Copy link
Author

@j82w Yes, Blazor Server works fine. It's Blazor WebAssembly that has the issue.

@JeremyLikness
Copy link
Author

@Lupusa87 the issue looks like it is related to the special HttpClient that is configured by Blazor. I don't think the mono team can fix this, we need the CosmosClient SDK to allow us to pass in a HttpClient or IHttpClientFactory (if that is feasible).

@ealsur
Copy link
Member

ealsur commented Apr 27, 2020

@JeremyLikness Is the scenario WebAssembly with ASP.NET Core or without? I'm looking at how Blazor handles the HttpClient instance provisioning.

@JeremyLikness
Copy link
Author

@ealsur either version works ... the ASP.NET Core just hosts the static files and makes it easier to set up server-side APIs, but the client project should work the same and provision the same. I'm trying to make it work without ASP.NET Core.

@ealsur
Copy link
Member

ealsur commented May 1, 2020

Required code changes were merged, will be available in the next release.

@ealsur ealsur closed this as completed May 1, 2020
ealsur added a commit that referenced this issue Jul 20, 2020
#1429 added support for HttpClientFactory inside the gateway connection mode, but the DocumentClient was maintaining two other HttpClient instances on GatewayAccountReader and GatewayAddressCache.

If the user was trying to use a custom HttpClientFactory to use a single HttpClient instance, it was not reaching these classes.

The effect also was that we were maintaining 3 different HttpClient instances normally.

This PR unifies this into a single HttpClient, that can either be created or obtained from the HttpClientFactory.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants