Wolverine IMessageBus.InvokeAsync<T> not returning result in a TimeoutException

21 Views Asked by At

I am trying to use Wolverine in my application stack to do a request/response but got stuck.

I have two asp.net webapi hosts (services) running, and I need to get data from 2nd service to 1st one. I decided to use IMessageBus.InvokeAsync() to do so, but what happens is:

  • The message is sent and received by the 2nd service and successfully handled
  • The response is not received on the 1st service and TimeOutException occurs.

I am using RabbitMq as a transport. I tried increasing timeout to 15 sec but with the same result.

My wolverine configuration at both services is the same and is this:

builder.Host.UseWolverine(opts =>
    {        
        opts.Services.Scan(s =>
        {
            s.TheCallingAssembly();
            s.WithDefaultConventions();
            s.LookForRegistries();
        });
                
        var conStr = builder.Configuration["Api:RabbitMq"];
        opts.UseRabbitMq(new Uri(conStr!))
            .UseConventionalRouting()
            .AutoProvision()
            .AutoPurgeOnStartup();
        
        opts.UseFluentValidation();
    })
    .ApplyOaktonExtensions();

Service 1 publisher is like this:

    public static class StartProcessCommandHandler
    {
        public static async Task<Result<GetProcessDataMessageResponse>> LoadAsync(StartProcessCommand command, IMessageBus bus)
        {
            var result = await bus.InvokeAsync<GetProcessDataMessageResponse>(new GetProcessDataMessage(command.ProcessId), default, TimeSpan.FromSeconds(15));
            if (result==null)
            {
                return Result.Fail("Process not found");
            }

            return Result.Ok(result);
        }

        public static async Task<Result<int>> HandleAsync(StartProcessCommand command, Result<GetProcessDataMessageResponse> processDataResult, ApplicationDbContext dbContext, ILogger<StartProcessCommand> logger, IMessageContext bus,  CancellationToken cancellationToken)
        {
            if (processDataResult.IsFailed)
            {
                return Result.Fail(processDataResult.Errors);
            }
            
            //contrust a process entity and save it to the database
            
            await dbContext.TrackingProcess.AddAsync(trackingprocessData, cancellationToken);
            await dbContext.SaveChangesAsync(cancellationToken);
            
            //publish an event for subscribbers
            await bus.PublishAsync(new ProcesStartedMessage(command.ProcessId));
            
            return Result.Ok();
        }
    }

And my Service 2 handler is:

    public static async Task<GetProcessDataMessageResponse> HandleAsync(GetProcessDataMessage message, ApplicationDbContext dbContext)
    {
        var id = message.ProcessId;
        var data = await dbContext.ProcessData
            .Where(x => x.Id == id)
            .AsNoTracking()
            .FirstOrDefaultAsync();


        var result = new GetProcessDataMessageResponse(data.Id, data.ProcessCode,...);
        return result;
    }

  • So the GetProcessDataMessage is sent from Service 1.
  • The message is being received on Service 2.
  • The Handler on Service 2 returns the GetProcessDataMessageResponse.
  • The GetProcessDataMessageResponse is not received on Service 1 endpoint and TimeoutException occurs.

What am I doing wrong?

Update1

The class

StartProcessCommandHandler

is also a wolverine handler used like a Mediator handler. It is being called by a wolverine http endpoint.

Please help

0

There are 0 best solutions below