graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

[UseServiceScope] attribute hangs with DataLoader

Open braidenstiller opened this issue 4 years ago • 5 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Hi,

When using the new [UseServiceScope] attribute on a resolver with a dataloader causes the resolver to hang when the dataloader's LoadAsync() method is called.

This breaks resolvers which require both dataloaders and scoped services.

Steps to reproduce

  1. Create DataLoader
  2. Create Resolver with DataLoader and use the [UseServiceScope] attribute on the resolver.
  3. Call LoadAsync() on the DataLoader.

Relevant log output

No logs. Just hangs.

Additional Context?

No response

Product

Hot Chocolate

Version

V12

braidenstiller avatar Oct 13 '21 01:10 braidenstiller

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar May 04 '22 12:05 stale[bot]

This appears to still be an issue.

jamiewinder avatar Jul 27 '22 09:07 jamiewinder

@jamiewinder what version are you on? Can you provide a minimal reproduction?

PascalSenn avatar Jul 27 '22 09:07 PascalSenn

@PascalSenn - This is on the latest version - 12.12.1 (same on 12.12.0).

The following example shows this:

public class ExampleDataLoader : BatchDataLoader<int, string>
{
    public ExampleDataLoader(IBatchScheduler batchScheduler, DataLoaderOptions? options = null) 
        : base(batchScheduler, options)
    {
    }

    protected override Task<IReadOnlyDictionary<int, string>> LoadBatchAsync(
        IReadOnlyList<int> keys, 
        CancellationToken cancellationToken)
        => Task.FromResult<IReadOnlyDictionary<int, string>>(keys.ToDictionary(key => key, key => key.ToString()));
}

public class Query
{
    [UseServiceScope]
    public Task<string> Example1([DataLoader] ExampleDataLoader dataLoader, int value)
        => dataLoader.LoadAsync(value);

    [UseServiceScope]
    public Task<string> Example2(int value)
        => Task.FromResult(value.ToString());

    public Task<string> Example3([DataLoader] ExampleDataLoader dataLoader, int value)
        => dataLoader.LoadAsync(value);
}

public static class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Services
            .AddGraphQLServer()
            .AddQueryType<Query>();

        var app = builder.Build();
        app.MapGraphQL();
        app.Run();
    }
}

The following will hang (resolver uses UseServiceScope and the data loader):

{
    example1(value: 1)
}

The following will work (resolver uses UseServiceScope, but not a data loader):

{
    example2(value: 1)
}

The following will work (resolver does not use UseServiceScope, but does use a data loader):

{
    example3(value: 1)
}

jamiewinder avatar Jul 27 '22 11:07 jamiewinder

A little more detail: the LoadAsync method (in the resolver) is being called, but the LoadBatchAsync method (of the data loader) is not.

jamiewinder avatar Jul 27 '22 11:07 jamiewinder

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Nov 24 '22 12:11 stale[bot]

@jamiewinder did you happen to find a workaround for this? I think I have the same issue

sgabler avatar Jan 09 '23 13:01 sgabler

@sgabler I'm afraid not, I've just had to force the resolvers to run in serial.

jamiewinder avatar Jan 09 '23 17:01 jamiewinder

This is now fixed and will be shipped with version 13 preview 95

michaelstaib avatar Jan 09 '23 17:01 michaelstaib