Amazon SQS MQ

Support for registering Amazon Simple Queue Service (SQS) as an MQ Server is available in ServiceStack.Aws NuGet package:

<PackageReference Include="ServiceStack.Aws" Version="6.*" />

Once installed SQS can be configured the same way as any other MQ Servers, by first registering the ServiceBus IMessageService provider followed by registering all ServiceStack Services you want to be able to invoke via MQ’s:

container.Register<IMessageService>(c => new SqsMqServer(
    AwsConfig.AwsAccessKey, AwsConfig.AwsSecretKey, RegionEndpoint.USEast1) {
    DisableBuffering = true, // Trade-off latency vs efficiency
});

var mqServer = container.Resolve<IMessageService>();
mqServer.RegisterHandler<MyRequest>(ExecuteMessage);

AfterInitCallbacks.Add(appHost => mqServer.Start());

When an MQ Server is registered, ServiceStack automatically publishes Requests accepted on the "One Way" pre-defined route to the registered MQ broker. The message is later picked up and executed by a Message Handler on a background Thread.

SQS MQ Server Example

The AWS Email Contacts example shows the same long-running EmailContact Service being executed from both HTTP and MQ Server by just changing which url the HTML Form is posted to:

//html
<form id="form-emailcontact" method="POST"
    action="@(new EmailContact().ToPostUrl())" 
    data-action-alt="@(new EmailContact().ToOneWayUrl())">
    ...
    <div>
        <input type="checkbox" id="chkAction" data-click="toggleAction" />
        <label for="chkAction">Email via MQ</label>
    </div>
    ...   
</form>

The urls are populated from a typed Request DTO using the Reverse Routing Extension methods

Checking the Email via MQ checkbox fires the JavaScript handler below that's registered as declarative event in ss-utils.js:

$(document).bindHandlers({
    toggleAction: function() {
        var $form = $(this).closest("form"), action = $form.attr("action");
        $form.attr("action", $form.data("action-alt"))
                .data("action-alt", action);
    }
});

The code to configure and start an SQS MQ Server is similar to other MQ Servers:

container.Register<IMessageService>(c => new SqsMqServer(
    AwsConfig.AwsAccessKey, AwsConfig.AwsSecretKey, RegionEndpoint.USEast1) {
    DisableBuffering = true, // Trade-off latency vs efficiency
});

var mqServer = container.Resolve<IMessageService>();
mqServer.RegisterHandler<EmailContacts.EmailContact>(ExecuteMessage);

AfterInitCallbacks.Add(appHost => mqServer.Start());

Intercepting Filters

A number of new filters are available on SqsMqServer and SqsMqClient which will let you intercept and apply custom logic before SQS messages are sent and received:

Action<SendMessageRequest,IMessage> SendMessageRequestFilter
Action<ReceiveMessageRequest> ReceiveMessageRequestFilter
Action<Amazon.SQS.Model.Message, IMessage> ReceiveMessageResponseFilter
Action<DeleteMessageRequest> DeleteMessageRequestFilter
Action<ChangeMessageVisibilityRequest> ChangeMessageVisibilityRequestFilter

Polling Duration

The polling duration used to poll SQS queues can be configured with:

new SqsMqServer {
    PollingDuration = TimeSpan.FromMilliseconds(1000) //default
}