I have the following code using aws sqs as mq service [snippet]:
public class TestAppHost : AppSelfHostBase
{
public TestAppHost() : base("Testing", typeof(TestAppHost).Assembly)
{
}
public override void Configure(Container container)
{
QueueNames.QueuePrefix = "SS-TEST";
var mqServer = new ServiceStack.Aws.Sqs.SqsMqServer(accessKey, secret, RegionEndpoint.USWest2)
{
DisableBuffering= true,
RetryCount = 1,
}
container.Register<IMessageService>(mqServer);
container.Register<IMessageFactory>(mqServer.MessageFactory);
mqServer.RegisterHandler<Type1Request>(ServiceController.ExecuteMessage);
// ...
mqServer.RegisterHandler<Type30Request>(ServiceController.ExecuteMessage);
}
public override void OnAfterInit()
{
var mqService = HostContext.TryResolve<IMessageService>();
mqService.Start();
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); //This gives time for worker threads to actually run
base.OnAfterInit();
}
}
I noticed the following. Because I sleep for 5s in OnAfterInit, it gives the sqs workers time to pull messages. However, service stack has not finished its “Init” which means arrays like RequestConvertersArray
are null because PopulateArrayFilters
has not had a chance to run [i.e. it is waiting for OnAfterInit to finish].
If there is a message on the queue when this code starts, it will be received before OnAfterInit
returns,. However, RequestConvertersArray
is null so ApplyRequestConvertersAsync
throws an exception which results in Naq being invoked and moving the message to the dlq.
I looked at the sample test code MqServerIntroTests at function Does_dispose_request_scope_dependency_in_PostMessageHandler
which does start the mq service in configure but that has the same problem [i.e. workers pulling messages before service stack is initialized].
One way around this is to start the mq service after calling Init
on the app host. So my question comes down to: Is my understanding correct. Am I doing this right?