graphql-platform
graphql-platform copied to clipboard
Redis Subscription Fails with: Unexpected Execution Error (HC0008)
Describe the bug I try to add a RedisSubscription Provider to my GQL API. If I do replace the Redis Subscription handler with the In Memory Subscription handler: Everything works as expected.
To Reproduce Steps to reproduce the behavior:
- Create A Azure Cache with default Settings.
- Use the following code to set everything up:
var redisConnectionConfiguration = new ConfigurationOptions()
{
Ssl = true,
AbortOnConnectFail = false,
Password = "TAKE_FROM_AZURE_PORTAL",
};
redisConnectionConfiguration.EndPoints.Add("TAKE_FORM_AZURE_PORTAL.redis.cache.windows.net:6380");
services.AddRedisSubscriptions(_ => ConnectionMultiplexer.Connect(redisConnectionConfiguration));
- Send an Event using
ITopicEventSender
-> You can view the data in redis usingpsubscribe *
. - Call the GQL Subscription that does work if you use a InMemeorySubscription Handler.
Expected behavior The Event Data which is visible in Redis is shown in my GQL Client (Banana Cake Pop). But I do get the following Error:
{
"errors": [
{
"message": "Unexpected Execution Error",
"extensions": {
"code": "HC0008"
}
}
]
}
Desktop (please complete the following information):
- OS: MacOS 11.2.3
- Version: 11.2.2
When you debug your application you should be seeing a more concrete exception than the Unexpected Execution Error
presented to clients. Would be helpful, if you could include said exception.
I have the same behaviour. I use an in memory subscription but I guess the reason might be the same. I get HotChocolate.Subscriptions.InMemory.InvalidMessageTypeException .
The return type of my subscription is a generic one. Actually in that case it was an enum. Can that cause the error?
Update
After further testing I got mine to work by use a concrete implementation like:
I guess the problem was that the generic value was received by reflection kind of magic and therefore the sendasync method did not get which type the message excatly was.
I have same error, only when I get EF DBcontext in resolver of subscription
Db context configuration:
services.AddPooledDbContextFactory<InseritasDbContext>(options =>
{
options
.UseNpgsql(configuration.GetConnectionString("DefaultConnection"), o => o.MigrationsAssembly("Example"))
.EnableSensitiveDataLogging(Debugger.IsAttached);
});
Repository pattern:
public class UnitOfWork : IUnitOfWork, IAsyncDisposable
{
private readonly InseritasDbContext _context;
public UnitOfWork(IDbContextFactory<InseritasDbContext> factoryContext)
{
_context = factoryContext.CreateDbContext();
ExampleRepository = new ExampleRepository(_context);
}
public IExampleRepository ExampleRepository { get; }
public int SaveChanges() => _context.SaveChanges();
public Task<int> SaveChangesAsync() => _context.SaveChangesAsync();
public IDbContextTransaction BeginTransaction() => _context.Database.BeginTransaction();
public Task<IDbContextTransaction> BeginTransactionAsync() => _context.Database.BeginTransactionAsync();
public ValueTask DisposeAsync() => _context.DisposeAsync();
}
GraphQL config:
services
.AddGraphQLServer()
.RegisterDbContext<ExampleDbContext>(DbContextKind.Pooled)
.RegisterService<IUnitOfWork>(ServiceKind.Pooled)
.AllowIntrospection(webHostEnvironment.IsDevelopment() || webHostEnvironment.IsStaging())
.AddSocketSessionInterceptor<SocketInterceptor>()
.SetPagingOptions(new PagingOptions
{
IncludeTotalCount = true
})
.ModifyOptions(options =>
{
options.DefaultBindingBehavior = BindingBehavior.Explicit;
})
.AddAuthorization()
.AddInMemorySubscriptions()
.AddQueryType<ExampleQuery>()
.AddMutationType<ExampleMutation>()
.AddSubscriptionType<ExampleSubscription>()
Subscription
public class InseritasSubscription : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor
.Name(OperationTypeNames.Subscription);
descriptor
.Field("example")
.Argument("argument", a => a.Type<StringType>())
.Type<ExampleType>()
.Resolve(ExampleResolver)
.Subscribe(ExampleSubscriberAsync);
}
private Example ExampleResolver(IResolverContext context) {
var uow= context.Service<IUnitOfWork>(); // When I add this row here I get the error and subscription disconnected.
return context.GetEventMessage<Example>();
}
private async ValueTask<ISourceStream> ExampleSubscriberAsync(IResolverContext context)
{
var receiver = context.Service<ITopicEventReceiver>();
var argument = context.ArgumentValue<string>("argument") ?? "example";
ISourceStream stream = await receiver.SubscribeAsync<string, Example>($"example_{argument}");
return stream;
}
}
My problem was that my UnitOfWork
service had implemented only IAsyncDisposable
after adding IDisposable
implementation everything started working as it should. hopefully this will help someone
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.