Round #248
07 May 2026, 20:56· csharp· meta/llama-3.3-70b-instruct· r13-clean-hints
- Complexity
- band 0
- ZP / UO / OBS
- 2 / 0 / 0
- Journey weight
- 158
- Lightshift ΔL
- +0.50
Prompt
Implement an outbox pattern that ensures at-least-once delivery
Zero-point index (what the engine surfaced)
ZPI-ZPI-0016 | 2026-05-07T20:56:45Z
Implement an outbox pattern that ensures at-least-once delivery
ZERO POINT — 2 entries (structural invariants)
● hsl(136.10, 100%, 21%) DbContext [contract]
● hsl(61.72, 100%, 21%) BackgroundService [contract]
UNOBSERVED — 0 entries (implied truths)
OBSERVED — 0 entries (explicit in request)
COMPLEXITY │ 2 entries │ spread: 0° │ band: LOW
Baseline response (no ZPI)
**Outbox Pattern Implementation in C#**
======================================
The outbox pattern is a design pattern that ensures at-least-once delivery of messages or events. It works by storing messages in a local database (the outbox) before sending them to their destination. If the sending process fails, the message is retried until it is successfully delivered.
**Database Schema**
------------------
The outbox pattern requires a database schema to store the messages. The schema should include the following columns:
* `Id` (primary key): a unique identifier for the message
* `Message`: the message payload
* `Destination`: the destination of the message (e.g., a queue, topic, or API endpoint)
* `Status`: the status of the message (e.g., "pending", "sent", "failed")
* `RetryCount`: the number of times the message has been retried
* `CreatedAt`: the timestamp when the message was created
* `UpdatedAt`: the timestamp when the message was last updated
**Outbox Class**
----------------
The outbox class is responsible for storing and sending messages. It should have the following methods:
* `AddMessage`: adds a new message to the outbox
* `SendMessage`: sends a message from the outbox to its destination
* `RetryFailedMessages`: retries failed messages
```csharp
using System;
using System.Data.Entity;
using System.Threading.Tasks;
public class Outbox
{
private readonly DbContext _dbContext;
public Outbox(DbContext dbContext)
{
_dbContext = dbContext;
}
public async Task AddMessage(string message, string destination)
{
var outboxMessage = new OutboxMessage
{
Message = message,
Destination = destination,
Status = "pending",
RetryCount = 0,
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
_dbContext.OutboxMessages.Add(outboxMessage);
await _dbContext.SaveChangesAsync();
}
public async Task SendMessage(int messageId)
{
var outboxMessage = await _dbContext.OutboxMessages.FindAsync(messageId);
if (outboxMessage == null)
{
throw new Exception("Message not found");
}
try
{
// Send the message to its destination
await SendToDestination(outboxMessage.Message, outboxMessage.Destination);
outboxMessage.Status = "sent";
outboxMessage.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync();
}
catch (Exception ex)
{
outboxMessage.Status = "failed";
outboxMessage.RetryCount++;
outboxMessage.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync();
// Log the exception
Console.WriteLine($"Error sending message: {ex.Message}");
}
}
public async Task RetryFailedMessages()
{
var failedMessages = await _dbContext.OutboxMessages
.Where(m => m.Status == "failed")
.ToListAsync();
foreach (var message in failedMessages)
{
await SendMessage(message.Id);
}
}
private async Task SendToDestination(string message, string destination)
{
// Implement the logic to send the message to its destination
// For example, you can use a message queue or an API client
Console.WriteLine($"Sending message to {destination}: {message}");
}
}
public class OutboxMessage
{
public int Id { get; set; }
public string Message { get; set; }
public string Destination { get; set; }
public string Status { get; set; }
public int RetryCount { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
```
**Usage Example**
-----------------
```csharp
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
// Create a DbContext instance
var dbContext = new MyDbContext();
// Create an outbox instance
var outbox = new Outbox(dbContext);
// Add a message to the outbox
await outbox.AddMessage("Hello, world!", "https://example.com/api/endpoint");
// Send the message
await outbox.SendMessage(1);
// Retry failed messages
await outbox.RetryFailedMessages();
}
}
```
**At-Least-Once Delivery Guarantee**
----------------------------------
The outbox pattern ensures at-least-once delivery by storing messages in a local database before sending them to their destination. If the sending process fails, the message is retried until it is successfully delivered. This guarantees that the message will be delivered at least once, but it may be delivered multiple times if the sending process fails repeatedly.
**Best Practices**
------------------
* Use a reliable database to store the outbox messages.
* Implement a retry mechanism with exponential backoff to handle failures.
* Use a message queue or an API client to send
Enhanced response (with ZPI)
### Outbox Pattern Implementation
The outbox pattern is a design pattern used to ensure at-least-once delivery of messages in a distributed system. It works by storing messages in a database (the "outbox") before sending them to their destination. If a message fails to send, it will be retried until it is successfully delivered.
#### Database Context
We will use Entity Framework Core to interact with the database. First, let's create a `DbContext` class:
```csharp
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
public class OutboxMessage
{
[Key]
public Guid Id { get; set; }
public string Destination { get; set; }
public string Payload { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? SentAt { get; set; }
public int Attempts { get; set; }
}
public class OutboxDbContext : DbContext
{
public OutboxDbContext(DbContextOptions<OutboxDbContext> options) : base(options)
{
}
public DbSet<OutboxMessage> OutboxMessages { get; set; }
}
```
#### Background Service
Next, we will create a `BackgroundService` that will be responsible for sending messages from the outbox:
```csharp
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;
public class OutboxService : BackgroundService
{
private readonly OutboxDbContext _dbContext;
private readonly ILogger<OutboxService> _logger;
private readonly IMessageSender _messageSender;
public OutboxService(OutboxDbContext dbContext, ILogger<OutboxService> logger, IMessageSender messageSender)
{
_dbContext = dbContext;
_logger = logger;
_messageSender = messageSender;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await SendMessagesAsync(stoppingToken);
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
}
}
private async Task SendMessagesAsync(CancellationToken stoppingToken)
{
var messages = await _dbContext.OutboxMessages
.Where(m => m.SentAt == null)
.ToListAsync(stoppingToken);
foreach (var message in messages)
{
try
{
await _messageSender.SendMessageAsync(message.Destination, message.Payload, stoppingToken);
message.SentAt = DateTime.UtcNow;
message.Attempts++;
_dbContext.OutboxMessages.Update(message);
await _dbContext.SaveChangesAsync(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send message {Id}", message.Id);
message.Attempts++;
_dbContext.OutboxMessages.Update(message);
await _dbContext.SaveChangesAsync(stoppingToken);
}
}
}
}
public interface IMessageSender
{
Task SendMessageAsync(string destination, string payload, CancellationToken cancellationToken);
}
public class MessageSender : IMessageSender
{
public async Task SendMessageAsync(string destination, string payload, CancellationToken cancellationToken)
{
// Implement your message sending logic here
await Task.CompletedTask;
}
}
```
#### DI Registration
Finally, we need to register our services in the DI container:
```csharp
using Microsoft.Extensions.DependencyInjection;
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<OutboxDbContext>(options =>
options.UseSqlServer("Data Source=<your_database>;Initial Catalog=<your_database>;User ID=<your_username>;Password=<your_password>;"));
services.AddSingleton<IMessageSender, MessageSender>();
services.AddHostedService<OutboxService>();
}
```
### Explanation
The outbox pattern ensures at-least-once delivery of messages by storing them in a database before sending them to their destination. If a message fails to send, it will be retried until it is successfully delivered.
In this implementation, we use Entity Framework Core to interact with the database and a `BackgroundService` to send messages from the outbox. The `OutboxService` class is responsible for sending messages from the outbox and retrying failed messages.
The `IMessageSender` interface defines the contract for sending messages, and the `MessageSender` class implements this interface. You should replace the `MessageSender` class with your own implementation of message sending logic.
The `OutboxDbContext` class defines the database context for the outbox, and the `OutboxMessage` class defines the entity for the outbox messages.
In the `ConfigureServices` method, we register our services in the DI container. We add the `OutboxDbContext` to the services, add the `IMessageSender` interface and its implementation, and add the `OutboxService` as a hosted service.
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1claude-haiku-4-5-20251001
BetterV4qwen2.5-coder-7b-instruct
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.