asp.netmasstransitoutbox-pattern

Masstransit's inbox configuration


I'm publishing messages from the asp.net controller using outbox. On the receiver side, i expect them first to be saved into the InboxState table(to avoid duplicates) and after that handled by the consumer-side worker to the consumers. But messages somehow are handled to the consumers directly, without saving them into inbox table.

My consumer is like that:

public class OrderWithEmailConsumer
    : IConsumer<SendEmailWithOrderDetails>
{
    private AppDbContext _dbContext;
    private ILogger<OrderWithEmailConsumer> _logger;

    public OrderWithEmailConsumer(AppDbContext dbContext, ILogger<OrderWithEmailConsumer> logger)
    {
        _dbContext = dbContext;
        _logger = logger;
    }

    public async Task Consume(ConsumeContext<SendEmailWithOrderDetails> context)
    {
        // send email to the customer
        _logger.LogInformation("Sending email to {Email} with order details", context.Message.Email);
        await Task.Delay(1000);
        _dbContext.Emails.Add(new OrderSentEmail()
        {
            EmailAdress = context.Message.Email,
            Subject = "Order details",
            Body = context.Message.OrderDetails
        });

        await _dbContext.SaveChangesAsync();
        
        _logger.LogInformation("Email sent to {Email}", context.Message.Email);
    }
}

and i configure outbox model like this(on the consumer's side)

configurator.AddEntityFrameworkOutbox<AppDbContext>(c =>
{
    c.QueryTimeout = TimeSpan.FromSeconds(10);
    c.QueryDelay = TimeSpan.FromSeconds(5);
    c.DuplicateDetectionWindow = TimeSpan.FromMinutes(5);
    c.DisableInboxCleanupService();
    c.UsePostgres();
});

configurator.AddConsumer<OrderWithEmailConsumer>();

And the DbContext class

public class AppDbContext: Microsoft.EntityFrameworkCore.DbContext
{
    public DbSet<OrderSentEmail> Emails { get; set; } = null!;
    
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.AddInboxStateEntity();
        modelBuilder.AddOutboxMessageEntity();
        modelBuilder.AddOutboxStateEntity();
    }
}

What i tried, is to look into InboxState table after publishing message, but it gives me 0 rows. I also tried to log all the db operations that it makes, but apart from polling outbox table i see no polling inbox? i really don't understand how can i configure inbox table polling


Solution

  • You need to actually configure the outbox on the consumer's endpoint. You can do this in the Consumer Definition or via a configure endpoints callback.

    These options are covered in the documentation.