📓 Cabinet of Ideas

Wolverine’s New Message Batching – The Shade Tree Developer

Wolverine’s New Message Batching – The Shade Tree Developer #

Excerpt #

Hey, did you know that JasperFx Software offers both consulting services and support plans for the “Critter Stack” tools? The new feature shown in this post was done at the behest of a …


Hey, did you know that JasperFx Software offers both consulting services and support plans for the “Critter Stack” tools? The new feature shown in this post was done at the behest of a JasperFx support customer. And of course, we’re also more than happy to help you with any kind of .NET backend development:)

Wolverine‘s new 3.0.0-beta-1 release adds a long requested feature set for batching up message handling. What does that mean? Well, sometimes you might want to process a stream of incoming messages in batches rather than one at a time. This might be for performance reasons, or maybe there’s some kind of business logic that makes more sense to calculate for batches, or maybe you want a logical  “debounce” in how your system responds to the incoming messages so you don’t update some resource on every single message received by your system.

To that end, Wolverine 3.0 introduces a new feature for batching up message handling within a Wolverine system. Let’s say that you have a message type in your system like this:

1

public record Item(string Name);

And for whatever reason, we need to process these messages in batches. To do that, we first need to have a message handler for an array of Item like so:

1

2

3

4

5

6

7

8

public static class ItemHandler

{

    public static void Handle(Item[] items)

    {

    }

}

And yes, before you ask, so far Wolverine only understands an array of the batched message type as the input message for the batch handler.

With that in our system, now we need to tell Wolverine to group Item messages, and we do that with the following syntax:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

theHost = await Host.CreateDefaultBuilder()

    .UseWolverine(opts =>

    {

        opts.BatchMessagesOf<Item>(batching =>

        {

            batching.BatchSize = 500;

            batching.LocalExecutionQueueName = "items";

            batching.TriggerTime = 1.Seconds();

        })

            .Sequential();

    }).StartAsync();

A particularly lazy and hopefully effective technique in OSS project documentation is to take code snippets directly out of test code, and that’s what you see above. Two birds with one stone. Sometimes that works out well.

And that’s that! Just to bring this a little more into focus, here’s an end to end test from the Wolverine codebase — which just for clarity, is using Wolverine’s built in test automation support for end to end testing:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

[Fact]

public async Task send_end_to_end_with_batch()

{

    var item1 = new Item("one");

    var item2 = new Item("two");

    var item3 = new Item("three");

    var item4 = new Item("four");

    Func<IMessageContext, Task> publish = async c =>

    {

        await c.PublishAsync(item1);

        await c.PublishAsync(item2);

        await c.PublishAsync(item3);

        await c.PublishAsync(item4);

    };

    var session = await theHost.TrackActivity()

        .WaitForMessageToBeReceivedAt<Item[]>(theHost)

        .ExecuteAndWaitAsync(publish);

    var items = session.Executed.SingleMessage<Item[]>();

    items.Length.ShouldBe(4);

    items.ShouldContain(item1);

    items.ShouldContain(item2);

    items.ShouldContain(item3);

    items.ShouldContain(item4);

}

Alright, with all that being said, here’s a few more facts about the batch messaging support:

  1. There is absolutely no need to create a specific message handler for the Item message, and in fact, you should not do so
  2. The message batching is able to group the message batches by tenant id if your Wolverine system uses multi-tenancy
  3. If you are using a durable inbox in your system, Wolverine is not marking the incoming envelopes as handled until the messages are successfully handled inside a batch message
  4. Likewise, if a batch message fails to the point where it triggers a move to the dead letter queue, each individual message that was part of that original batch is moved to the dead letter queue separately

Summary #

Hey, that’s actually all I had to say about that! Wolverine 3.0 will hopefully go RC later this week or next, with the official release *knock on wood* happening before I leave for Swetugg and a visit in Copenhagen with a JasperFx client in a couple weeks.

Published September 3, 2024

Post navigation #