Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring

Delayed Delivery

Component: NServiceBus
NuGet Package: NServiceBus (9.x)

This sample shows a simple ordering system that:

  • sends a command from a client to a server
  • handles the command on the server

While sending the command, the user can choose to defer handling or delivery of the message.

The Shared Project

The Shared project is for shared classes including message definitions. This project is shared between the client and server so both sides agree on the typed message descriptions. It is referenced by all projects in the solution.

PlaceOrder Command

This is the command for placing an order; it used in the Defer Message Handling scenario

public class PlaceOrder :
    ICommand
{
    public Guid Id { get; set; }
    public string Product { get; set; }
}

PlaceDelayedOrder Command

This command also places an order but is used in the Defer Message Delivery scenario.

public class PlaceDelayedOrder :
    ICommand
{
    public Guid Id { get; set; }
    public string Product { get; set; }
}

Defer message handling

Choose option 1 in the client console to defer handling the message after receiving it on the server.

The Client

The Client initiates the ordering process. The sending code in the client is as follows.

var placeOrder = new PlaceOrder
{
    Product = "New shoes",
    Id = id
};
await endpointInstance.Send("Samples.DelayedDelivery.Server", placeOrder);
Console.WriteLine($"[Defer Message Handling] Sent a PlaceOrder message with id: {id.ToString("N")}");

The Server

The Server processes an Order. It receives PlaceOrder sent from Client and for the first time defers its handling for five seconds.

public async Task Handle(PlaceOrder message, IMessageHandlerContext context)
{
    if (ShouldMessageBeDelayed(message.Id))
    {
        var options = new SendOptions();

        options.DelayDeliveryWith(TimeSpan.FromSeconds(5));
        options.RouteToThisEndpoint();
        await context.Send(message, options);
        log.Info($"[Defer Message Handling] Deferring Message with Id: {message.Id}");
        return;
    }

    log.Info($"[Defer Message Handling] Order for Product:{message.Product} placed with id: {message.Id}");
}

Defer message delivery

Choose option 2 in the client console to defer delivery of the message on the client.

The Client

The Client initiates the ordering process. The 'Client' defers sending the message as can be seen below.

var placeDelayedOrder = new PlaceDelayedOrder
{
    Product = "New shoes",
    Id = id
};
var options = new SendOptions();

options.SetDestination("Samples.DelayedDelivery.Server");
options.DelayDeliveryWith(TimeSpan.FromSeconds(5));
await endpointInstance.Send(placeDelayedOrder, options);
Console.WriteLine($"[Defer Message Delivery] Deferred a PlaceDelayedOrder message with id: {id.ToString("N")}");

The Server

The Server project processes an Order. It receives PlaceDelayedOrder sent from Client and processes it normally.

public class PlaceDelayedOrderHandler :
    IHandleMessages<PlaceDelayedOrder>
{
    static ILog log = LogManager.GetLogger<PlaceDelayedOrderHandler>();

    public Task Handle(PlaceDelayedOrder message, IMessageHandlerContext context)
    {
        log.Info($"[Defer Message Delivery] Order for Product:{message.Product} placed with id: {message.Id}");
        return Task.CompletedTask;
    }
}

Related Articles