Delayed Delivery

Component: NServiceBus
NuGet Package NServiceBus (6.x)

In this sample shows a very simple ordering system that:

  • Sends a command from a client to a server.
  • That server handles the command.

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

The Shared Project

The Shared project is the container for shared classes including message definitions. This project will be 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

Used to place an order, used in Defer Message Handling scenario

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

PlaceDelayedOrder Command

Used to place an order, used in Defer Message Delivery scenario

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

Defer message handling

This flow is shown when user chose 1 on Client Console. In this case message is deferred after receiving on the Server.

The Client

The Client is the initiate for 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)
    .ConfigureAwait(false);
Console.WriteLine($"[Defer Message Handling] Sent a PlaceOrder message with id: {id.ToString("N")}");

The Server

The Server project processes an Order. It receives PlaceOrder sent from Client and for the first time defers it's handling for some time.

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)
            .ConfigureAwait(false);
        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

This flow is shown when user chose 2 on Client Console. In this case message is deferred before being send on the Client.

The Client

The Client is the initiate for the ordering process. The 'Client' defers sending of a 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)
    .ConfigureAwait(false);
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 process it.

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


Last modified