rebus-org / Rebus.SqlServer

:bus: Microsoft SQL Server transport and persistence for Rebus
https://mookid.dk/category/rebus
Other
43 stars 44 forks source link

Question: Prioritizing messages #76

Closed macchmie3 closed 4 years ago

macchmie3 commented 4 years ago

Hi!

I have been using rebus sql server transport for some time (works great for me) and I realized that message prioritization would also work great for me. Since it's hard to find much documentation about it I have some questions.

From what I have seen - you can set priority with headers, when using Bus.Send(message) - is it the only way?

In my scenario, the best approach would be to set priority based on message type (class type). Is there any built-in way to do so?

Since in my case I want to actually deprioritize some type of messages i guess I can just set negative priority since default is 0, is that correct?

mookid8000 commented 4 years ago

From what I have seen - you can set priority with headers, when using Bus.Send(message) - is it the only way?

Yes 😁 and it's a hack.

But since it's trivial for SQL Server to pick out individual rows ordered by their priority, it's a secret feature offered by that transport.

In my scenario, the best approach would be to set priority based on message type (class type). Is there any built-in way to do so?

No, but it would be fairly easy to implement with a custom step in the outgoing message pipeline, e.g. like

public class AssignDefaultPriorityStep : IOutgoingStep
{
    public async Task Process(OutgoingStepContext context, Func<Task> next)
    {
        var message = context.Load<Message>();

        message.Headers[SqlServerTransport.MessagePriorityHeaderKey] = ...;

        await next();
    }
}

which you would probably install like this:

Configure.With(...)
    .(...)
    .Options(o => {
        o.Decorate<IPipeline>(c => {
            var pipeline = new PipelineStepInjector(c.Get<IPipeline>());
            var step = new AssignDefaultPriorityStep();

            return pipeline
                .OnSend(step, PipelineStepPosition.Before, typeof(AssignDefaultHeadersStep));
        })
    })
    .Start();

most likely wrapping it in an extension method so it becomes pretty like this:

Configure.With(...)
    .(...)
    .Options(o => o.AutomaticallyAssignDefaultMessagePriorities())
    .Start();

Since in my case I want to actually deprioritize some type of messages i guess I can just set negative priority since default is 0, is that correct?

I would believe that that would work just fine, yes 🙂