Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering ServiceStack

You're reading from   Mastering ServiceStack Utilize ServiceStack as the rock solid foundation of your distributed system

Arrow left icon
Product type Paperback
Published in Oct 2015
Publisher Packt
ISBN-13 9781783986583
Length 216 pages
Edition 1st Edition
Arrow right icon
Author (1):
Arrow left icon
Andreas Niedermair Andreas Niedermair
Author Profile Icon Andreas Niedermair
Andreas Niedermair
Arrow right icon
View More author details
Toc

The processing chains of ServiceStack

The ServiceStack services can be hosted in an HTTP and Message Queue context, hence there are two different processing chains, which will be covered in the following two sections.

We will also cover request and response filters and annotations later in the chapter, which allow you to apply late-bound changes to your requests and responses.

HTTP context

The following contexts and their base classes are all derived from ServiceStack.ServiceStackHost; they can be used for your HTTP hosted service:

  • ASP.NET
    • ServiceStack.AppHostBase
  • Self-hosted
    • ServiceStack.AppHostListenerBase for single-threaded processing
    • ServiceStack.AppHostListenerPoolBase, ServiceStack.AppSelfHostBase and ServiceStack.AppHostListenerSmartPoolBase for multithreaded processing, where the former is utilizing the .NET Thread Pool and the others Smart Thread Pool (https://smartthreadpool.codeplex.com/) for queuing their work items

The pipeline is the same for every scenario, as shown in the following diagram:

HTTP context

Before any request goes into the ServiceStack pipeline, the functions in your AppHost's RawHttpHandlers are executed and the result is in the favor of further processing in ServiceStack if the value is not null. The processing in ServiceStack is done in the following order:

  1. The path is checked against existing routes (by attribution and convention). If none is matching, the delegates added to the CatchAllHandlers property are used for probing.
  2. All the delegates added to the PreRequestFilters property are executed, which cannot access the RequestDTO yet though.
  3. The content (Query String, Form Data, POST payload …) is deserialized into the RequestDTO either by default binding or a custom RequestBinder predicate.
  4. All delegates added to the RequestConverters collection are executed.
  5. All the RequestFilterAttribute annotations with a Priority less than zero are executed.
  6. All the delegates added to the GlobalTypedRequestFilters property and GlobalRequestFilters property are executed.
  7. All the RequestFilterAttribute annotations with a Priority greater than or equal to zero are executed.
  8. All delegates added to the ResponseConverters collection are executed.
  9. Then the registered ServiceStack.Web.IServiceRunner object calls OnBeforeExecute, your service method, OnAfterExecute and HandleException.
  10. All the ResponseFilterAttribute annotations with a Priority less than zero are executed.
  11. All the delegates added to the GlobalTypedResponseFilter property and GlobalResponseFilters property are executed.
  12. All the ResponseFilterAttribute annotations with a Priority greater than or equal to zero are executed.
  13. Finally OnEndRequest and OnEndRequestCallback is called and the response is written to the HTTP stream.

Message Queue context

The following MQ server implementations are available (the packages are listed in brackets for easier searching on NuGet) for your ServiceStack service:

  • ServiceStack.RabbitMq.RabbitMqServer (ServiceStack.RabbitMq)
  • ServiceStack.Messaging.Redis.RedisMqServer (ServiceStack.Server)
  • ServiceStack.Messaging.Redis.RedisTransientMessageService (ServiceStack.Server)
  • ServiceStack.Messaging.Rcon.Server (ServiceStack.Server)
  • ServiceStack.Messaging.InMemoryTransientMessageService (ServiceStack)

Note

The specific messaging implementations are described in detail in Chapter 3, Asynchronous Communication between Components.

In contrast to the processing chain of an HTTP context, the steps in an MQ context are as follows:

  1. All delegates added to the RequestConverters collection are executed.
  2. First all the delegates added to the GlobalTypedMessageRequestFilters property and GlobalMessageRequestFilters property are executed.
  3. Then the registered ServiceStack.Web.IServiceRunner object calls OnBeforeExecute, your service method, OnAfterExecute and HandleException.
  4. All delegates added to the ResponseConverters collection are executed.
  5. All the delegates added to the GlobalTypedMessageResponseFilter property and GlobalMessageResponseFilters property are executed.
  6. Finally the response is returned to the MQ.

    Tip

    Some ServiceStack MQ server classes provide customized hooks to filter requests and responses, giving you specialized possibilities to customize your pipeline.

In contrast to this, you can easily combine an MQ service and an HTTP service and leverage a trimmed-down processing pipeline of the HTTP service. This is possible as one of the core concepts of ServiceStack is the Message Pattern, which comes quite handy in this scenario:

public class AppHost : ServiceStack.AppSelfHostBase
{
  public AppHost()
    : base ("Ticket Service",
            typeof (TaskService).Assembly)
  { }

  public override void Configure(Funq.Container container)
  {
    var messageService = container.Resolve<ServiceStack.Messaging.IMessageService>();
    messageService.RegisterHandler<FindTasks> (this.ServiceController.ExecuteMessage);
    messageService.Start();
  }
}

The preceding code relies on the registration of a ServiceStack.Interfaces.IMessageService implementation, which gets resolved inside the Configure method. Then all the plumbing is done to register the handlers and start the MQ client.

If you do not want to provide an HTTP endpoint but still use the internals of ServiceStack such as the powerful IoC-Container, which is an unusual common use-case, you can use the generic BasicAppHost for an extended processing pipeline such as:

var basicAppHost = new ServiceStack.Testing.BasicAppHost(typeof(TaskService.Assembly))
{
  ConfigureAppHost = host =>
  {
    var messageService = host.Container.Resolve <ServiceStack.Interfaces.IMessageService>();
    messageService.RegisterHandler <FindTasks>(host.ServiceController.ExecuteMessage);
    messageService.Start();
  }
};

This is especially helpful in testing scenarios, where you want to deal with the endpoints directly.

Note

The other hook to configure your service is ConfigureContainer, which is executed after ConfigureAppHost. You need to be aware of this order when you are trying to resolve any dependency, as configuring the container is done afterwards.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

You have been reading a chapter from
Mastering ServiceStack
Published in: Oct 2015
Publisher: Packt
ISBN-13: 9781783986583
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image