graphql-platform
graphql-platform copied to clipboard
Cosmos IQueryable throws "LINQ query please set allowSynchronousQueryExecution true or use GetItemQueryIterator to execute asynchronously"
Is there an existing issue for this?
- [X] I have searched the existing issues
Product
Hot Chocolate
Describe the bug
When returning a Cosmos Linq Queryable, HotChocolate throws because it appears to be attempting to access the IQueryable synchronously (rather than async)
[UseFiltering]
public IQueryable<MyModel> GetPartner() =>
MyContainer.GetItemLinqQueryable<MyModel>();
Steps to reproduce
- Connect your program to a cosmos database
- Return a queryable ala MyContainer.GetItemLinqQueryable<MyModel>()
- Exception happens when accessing that node
Relevant log output
GraphQL service exception for 'POST /graphql/UnknownOperation - 662a00b5500da5b6c5c6a01ee7142acd': To execute LINQ query please set allowSynchronousQueryExecution true or use GetItemQueryIterator to execute asynchronously
System.NotSupportedException: To execute LINQ query please set allowSynchronousQueryExecution true or use GetItemQueryIterator to execute asynchronously
at Microsoft.Azure.Cosmos.Linq.CosmosLinqQuery`1.GetEnumerator()+MoveNext()
at HotChocolate.Execution.Processing.Tasks.ResolverTask.<>c__DisplayClass50_0.<ExecuteResolverPipelineAsync>b__0()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)
Additional Context?
HC should try to load data from the IQuerayble asynchronously rather than synchronously
Version
13.0.5
Blockers to having a nice repository for searching/paging/filtering for Cosmos and HotChocolate
- [ ] This issue
- [ ] https://github.com/Azure/azure-cosmos-dotnet-v3/issues/3697
- [ ] https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3724
- [ ] https://github.com/Azure/azure-cosmos-dotnet-v3/pull/3725
It seems like this is the code to blame, perhaps? Does HotChocolate have a special case for EF Core or are all IQueryables really executed synchronously?

We check, if the queryable also implements IAsyncEnumerable than we will use the async variant. In the case of EFCore, they are implementing IAsyncEnumerable.
Does Cosmos implement IAsyncEnumerable?
Just double checked ... in the case of EFCore you can do the following, and that is what we do:
if (source is IAsyncEnumerable<TSource> asyncEnumerable)
{
return asyncEnumerable;
}
this is done in a middleware... the resolver task is kind of the last line of defense and there we will execute it in a task if no other way was found in the pipeline.
Looking at the docs the have this weird way with the iterator to fetch it. Strange that they do not implement IAsyncEnumerable.
What can be done are several things.... either a middleware specific for cosmos of a paging provider for cosmos.
Yeah, I think cosmos ought to implement Iasyncenumerable.. but you guys do have a ravendb provider, surely cosmos is more popular than that in 2023… right? 😅
Even if Cosmos' IQueryable supported IAsyncEnumerable, it would not be able to support retrieving totalCount efficiently
I ended up writing some middleware to support this kinda, but it would be cool if there was a HC package for cosmos support; would remove a lot of code
Yeah, I think cosmos ought to implement Iasyncenumerable.. but you guys do have a ravendb provider, surely cosmos is more popular than that in 2023… right?
Not sure about that ... the raven community was very active and lots of people wanted support for that. We had also lots of requests for EfCore and MongoDB ... I would say you are the first to ask for cosmos :D
Just checked ... 6 issues including this ... and 5 where asking question for cosmos with EFCore ... so not a lot of demand. Demand as from questions on slack is:
- Postgres
- MongoDB
- RavenDB
But if you want to do the work for the driver we will help you with that. The work for the MartenDB diver was also done by one of our community members. Interested to help on cosmos?
@michaelstaib I am interested in contributing it. I'm still struggling to figure out the best way to accomplish it with minimal use of attributes that have to be tacked on
We have a standard template for this. I can post you later a pr that shows how such a driver is implemented.
@michaelstaib any update on getting me that template?
@michaelstaib Bump.. still would like to contribute this
I'm new to this library and also very much invested in CosmosDB. Can anyone tell me if this is a bad approach to fixing the OPs error
[UseFiltering]
public async Task<IEnumerable<Users>?> GetUsers([FromServices] Container<Users> users, IResolverContext resolverContext)
{
var query = container
.GetItemLinqQueryable<Users>()
.Filter(resolverContext)
.ToFeedIterator();
var list = new List<Users>();
while (query.HasMoreResults)
{
var response = await query.ReadNextAsync();
foreach (var item in response)
{
list.Add(item);
}
}
return list;
}
It does work without the allowSynchronousQueryExecution set to true.
I was working with @PascalSenn and @michaelstaib on submitting a PR to support cosmos, @PascalSenn any update from that convo we had in May?
@onionhammer I'm also available if you need anything. I'd love to see cosmos officially supported. In the mean-time, is there any issues with my workaround to this? I've been using it for a few days and its worked fairly well.
We have a standard template for this. I can post you later a pr that shows how such a driver is implemented.
Any update on this?
Per nuget:
- RavenDB Client: Per day average 3.3K
- Marten: Per day average 2.1K
- Cosmos: Per day average 40.2K
I'm also interested in a Cosmos DB provider - please don't let this get closed by the stale bot.
Same
On Sun, 24 Mar 2024 at 11:30, David Paul McQuiggin @.***> wrote:
I'm also interested in a Cosmos DB provider - please don't let this get closed by the stale bot.
— Reply to this email directly, view it on GitHub https://github.com/ChilliCream/graphql-platform/issues/5958#issuecomment-2016763842, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABLPDEODX3XX2X5KCI5IVTYZ2TKVAVCNFSM6AAAAAAVZQ55BSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMJWG43DGOBUGI . You are receiving this because you are subscribed to this thread.Message ID: @.***>
Hi @onionhammer
I am also interested in this. did you guys get anywhere in the end? I can help out with getting the PR completed - if you need a hand. tvm
Unfortunately not, discussed it a few times with @michaelstaib , he seemed to think it was relatively easy but I can't remember any simple samples coming out of it
var list = new List<Users>(); while (query.HasMoreResults) { var response = await query.ReadNextAsync(); foreach (var item in response) { list.Add(item); } } return list;
Thanks for the reply @onionhammer.
The original code you quoted, which part of is it in HC? Are you still using Cosmos SDK with HC or did you change to use EF Core for example - if i may ask? I do wonder whether it's better to use EF core with HC if one had the choice.
thanks
@suneths I am still using cosmos SDK with hotchocolate, but I have written a significant amount of ugly glue code in my app to make paging/filtering/sorting work
@suneths I am still using cosmos SDK with hotchocolate, but I have written a significant amount of ugly glue code in my app to make paging/filtering/sorting work
Thanks @onionhammer.
asking the obvious, but would this code disappear with EF core in place? I guess there maybe other considerations, but do you have a choice to switch to EF core? - you don't want to because of architectural or other design reasons.
Many thanks.
@suneths I am still using cosmos SDK with hotchocolate, but I have written a significant amount of ugly glue code in my app to make paging/filtering/sorting work
Thanks @onionhammer.
asking the obvious, but would this code disappear with EF core in place? I guess there maybe other considerations, but do you have a choice to switch to EF core? - you don't want to because of architectural or other design reasons.
Many thanks.
It's generally a bad idea to use EF core with CosmosDB. It hides the details of the essential partition system which affects the runtime cost of the system. EF core provider is also non-complete so you'll find things not working occasionally.
Its pretty tricky to avoid cross-partition queries when ef-core abstracts away the idea of a partition in the first place
EF core provider is also non-complete so you'll find things not working occasionally.
Thanks @Arcalise08 @onionhammer for the replies. let's see whether @michaelstaib decides to add some love to Cosmos sdk in v14 :)
I will say, though, We ultimately decided to use REST instead of GraphQL. Though using my above solution did work, It came with some serious downsides. For one we couldn't control how the query was executed, so again, Cross-partition queries were difficult to stop.
If there is to be any support for the Cosmos.Sdk, Finding ways to avoid cross-partition queries should be a top priority. Partitioning should not just be some abstracted away concept. Its a huge deal to consumers of Cosmos.
I will say, though, We ultimately decided to use REST instead of GraphQL. Though using my above solution did work, It came with some serious downsides. For one we couldn't control how the query was executed, so again, Cross-partition queries were difficult to stop.
If there is to be any support for the Cosmos.Sdk, Finding ways to avoid cross-partition queries should be a top priority. Partitioning should not just be some abstracted away concept. Its a huge deal to consumers of Cosmos.
interesting. thanks for that. but isn't this down to the partition key and the type of queries though? i guess with REST you can control the type of querying a bit more?