Orcas Durable Services

Long running WCF Services is another great feature of the new Orcas Beta 1. Implementing durable service is always a combination of persisting the message itself as well as the state of the service. The current version of WCF provides stateful WCF services using sessions. However this feature does not address a lot of the most common enterprise stateful services scenarios on which state of an service instance needs to be persisted to a more robust durable store in order to handle unexpected events like host recycling, server shutdown, etc. Other Microsoft technologies such as BizTalk Server and Windows Workflow Foundation (WF) do provide support for long running services. Specifically, WF provides an extensible model based on persistence services that allow developers to create their own mechanisms for persisting the state of a WF instance.

The upcoming version of the .NET Framework (3.5) implements a similar mechanism for persisting the state of WCF Services. The following sections will describe the steps required to implement truly WCF stateful services using Orcas Beta 1. Let’s take the following service contract that describes a stateful interaction:

[ServiceContract]

public interface ITextComposer

{

 

    [OperationContract]

    string PowerOn(string text);

 

    [OperationContract]

    string InsertText(string text);

 

    [OperationContract]

    string DeleteText(string text);

 

   [OperationContract]

    void PowerOff();

}

Figure 1: Service Contract

To customize the contract implementation as a durable service we use the DurableService and DurableOperation behaviors. Similarly to the current support for session management in .NET 3.0, we can use behavior parameters to configure the lifetime of an instance. On our example the PowerOn and PowerOff operations set the instantiation and completion of a service instance.

[Serializable]

[DurableServiceBehavior]

public class TextComposer : ITextComposer

{

    private string CurrentText ;

 

    [DurableOperationBehavior(CanCreateInstance = true)]

    public string PowerOn(string text)

    {

        CurrentText = text;

        return CurrentText;

    }

 

    [DurableOperationBehavior()]

    public string InsertText(string text)

    {

        CurrentText += " " + text;

        return CurrentText;

    }

 

    [DurableOperationBehavior()]

    public string DeleteText(string text)

    {

        CurrentText = CurrentText.Replace(text, "");

        return CurrentText;

    }

 

   [DurableOperationBehavior(CompletesInstance=true)]

    public void PowerOff()

    {

    }

}

Figure 2: WCF Service implementation

Now it is time to configure the persistent service to be used to serialize the state of the service instance. For that we use the new wsHttpContextBinding which allows passing the state information in the form of Http headers. The SDK includes the scripts to create the database used by the default persistent service. As I mentioned before this process is very similar to configuring the WF Persistent Service.

<?xml version="1.0"?>

<configuration>

          <system.serviceModel>

                   <services>

                             <service name="TextComposer" behaviorConfiguration="ServiceBehavior">

                                      <endpoint address="ContextOverHttp" binding="wsHttpContextBinding" bindingConfiguration="DemoBinding" contract="ITextComposer" />

                             </service>

                   </services>

                   <behaviors>

                             <serviceBehaviors>

                                      <behavior name="ServiceBehavior">

                                                <serviceMetadata httpGetEnabled="true"/>

                                                <serviceDebug includeExceptionDetailInFaults="true"/>

                                                <serviceCredentials>

                                                          <windowsAuthentication allowAnonymousLogons="false" includeWindowsGroups="true"/>

                                                </serviceCredentials>

                                                <persistenceProvider type="System.ServiceModel.Persistence.SqlPersistenceProvider, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DurableServiceStore" persistenceOperationTimeout="00:00:10" lockTimeout="00:01:00" serializeAsText="true"/>

                                      </behavior>

                             </serviceBehaviors>

                   </behaviors>

 

    <bindings>

      <wsHttpContextBinding>

        <binding name="DemoBinding">

          <security mode="None" />

        </binding>

      </wsHttpContextBinding>

    </bindings>

   

          </system.serviceModel>

          <connectionStrings>

                   <add name="DurableServiceStore" connectionString="Data Source=localhost\SQLEXPRESS;Initial Catalog=ServiceState;Integrated Security=SSPI"/>

          </connectionStrings>

          <system.web>

                   <compilation debug="true">

                             <assemblies>

                                      <add assembly="System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

      </assemblies>

    </compilation>

  </system.web>

</configuration>

Figure 3: WCF Service Host configuration

Now we are ready to create our WCF client. Although this is very similar to the traditional process we follow with NET 3.0 the implementation code presents some interesting differences.

ServiceReference.TextComposerClient proxy = new ClientApp.ServiceReference.TextComposerClient();

using(new OperationContextScope((IContextChannel)proxy.InnerChannel))

  {

            string text= proxy.PowerOn("Text...");

            context = ContextManager.ExtractContextFromChannel(proxy.InnerChannel);

            ContextManager.ApplyContextToChannel(Context, proxy.InnerChannel);

            text = proxy.InsertText("First line ");

            text = proxy.InsertText("Second line");

      }

Figure 4: Client code

The call to PowerOn on this code produces the following HTTP-SOAP request and response message.

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://tempuri.org/ITextComposer/PowerOn</a:Action>
        <a:MessageID>urn:uuid:4bbd8b6e-8a27-4515-8856-f4e3aa684983</a:MessageID>
        <a:ReplyTo>
            <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">http://localhost:1242/TextComposer/Service1.svc/ContextOverHttp</a:To>
    </s:Header>
    <s:Body>
        <PowerOn xmlns="http://tempuri.org/">
            <text>Text...</text>
        </PowerOn>
    </s:Body>
</s:Envelope>

Figure 5: HTTP-SOAP request

HTTP/1.1 200 OK

Server: ASP.NET Development Server/9.0.0.0

Date: Tue, 12 Jun 2007 05:08:27 GMT

X-AspNet-Version: 2.0.50727

Set-Cookie: WscContext=PEFycmF5T2ZLZXlWYWx1ZU9mUU5hbWVzdHJpbmcgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzL…context state

Cache-Control: private

Content-Type: application/soap+xml; charset=utf-8

Content-Length: 559

Connection: Close

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://tempuri.org/ITextComposer/PowerOnResponse</a:Action>
        <a:RelatesTo>urn:uuid:4bbd8b6e-8a27-4515-8856-f4e3aa684983</a:RelatesTo>
        <Context xmlns="http://schemas.microsoft.com/ws/2006/05/context">
            <InstanceId>e32c3fd9-8f56-4024-b818-4f920813d313</InstanceId>
        </Context>
    </s:Header>
    <s:Body>
        <PowerOnResponse xmlns="http://tempuri.org/">
            <PowerOnResult>Text...</PowerOnResult>
        </PowerOnResponse>
    </s:Body>
</s:Envelope>

Figure 6: HTTP-SOAP response

The highlighted lines on figure 4 leverage a helper class for manipulating the service state headers provided as part of the .NET Framework 3.5 SDK. Specifically, the ExtractContectFromChannel operation retrieves the instance key from the SOAP headers .

static public IDictionary<XmlQualifiedName, string> ExtractContextFromChannel(IClientChannel channel)

        {   // extract context from channel

            IContextManager cm = channel.GetProperty<IContextManager>();

            if (cm != null)

            {   // attempt to extract context from channel

                return cm.GetContext();

            }

            else if (OperationContext.Current != null)

            {   // attempt to extract context from HttpCookie

                CookieContainer cookies = new CookieContainer();

                if (OperationContext.Current.IncomingMessageProperties.ContainsKey(HttpResponseMessageProperty.Name))

                {

                    HttpResponseMessageProperty httpResponse = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name];

                    cookies.SetCookies(ccUri, httpResponse.Headers[HttpResponseHeader.SetCookie]);

                }

                if (cookies.Count > 0)

                {   // put WscContext cookie into dictionary

                    Dictionary<XmlQualifiedName, string> newContext = new Dictionary<XmlQualifiedName, string>();

                    foreach (Cookie cookie in cookies.GetCookies(ccUri))

                    {

                        if (cookie.Name.Equals(WscContextKey))

                        {

                            newContext.Add(new XmlQualifiedName(WscContextKey), cookie.Value);

                            break;

                        }

                    }

                    return newContext;

                }

            }

            return null;

        }

  Figure 7: ExtractContectFromChannel helper

Similarly, the ApplyContextToChannel operation adds the specific state to the operation context.

 static public bool ApplyContextToChannel(IDictionary<XmlQualifiedName, string> context, IClientChannel channel)

        {

            if (context != null)

            {

                IContextManager cm = channel.GetProperty<IContextManager>();

                if (cm != null && cm.GetContext() == null)

                {   // apply context to ContextChannel

                    cm.SetContext(context);

                    return true;

                }

                else if (OperationContext.Current != null)

                {   // apply context as HttpCookie

                    CookieContainer cookies = new CookieContainer();

                    foreach (KeyValuePair<XmlQualifiedName, string> item in context)

                    {

                        cookies.Add(ccUri, new Cookie(item.Key.ToString(), item.Value));

                    }

                    if (cookies.Count > 0)

                    {

                        HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty();

                        OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest);

                        httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookies.GetCookieHeader(ccUri));

                        return true;

                    }

                }

            }

            return false;

        }

 

  Figure 8: ApplyContextToChannel helper

The SQL Server persistent service allows the WCF Service instance state to be persisted even if the host gets recycled. This is a great feature that can be combined with the use of some channels such as MSMQ or Service Broker in order to complement the stateful WCF services with durable messaging.

Published Thursday, June 14, 2007 6:37 PM by gsusx

Comments

# WCF Durable services

My friend Jesus Rodriguez has published an excellent article about one the cool features that will be

Tuesday, June 19, 2007 9:28 AM by Pablo M. Cibraro (aka Cibrax)

# re: Orcas Durable Services

I really want to post something on my blog about this, but this comment will have to do in the meantime.

Explicit state management is what scales and is robust in the face of failure. This solution seems, to me, to be lacking in those respects. It may also just be me, but the solution seems quite complex. What about something more similar to long-running workflows?

Am I missing something here?

Saturday, June 30, 2007 5:24 PM by Udi Dahan - The Software Simplist

# kennyw.com &raquo; Blog Archive &raquo; Throttling in WCF

Pingback from  kennyw.com  &raquo; Blog Archive   &raquo; Throttling in WCF

Tuesday, August 07, 2007 9:04 PM by kennyw.com » Blog Archive » Throttling in WCF

# [Podcast] Durable Services with WCF, WF, and NServiceBus

Pingback from  [Podcast] Durable Services with WCF, WF, and NServiceBus

Tuesday, October 23, 2007 5:18 PM by [Podcast] Durable Services with WCF, WF, and NServiceBus

# Beyond the Obvious: New Features and Fixes for WCF in .NET 3.5

With .NET 3.5 and Visual Studio 2008 being quite close to RTM these days, I thought it would be time...

Monday, October 29, 2007 10:47 AM by Christian Weyer: Smells like service spirit

# [WCF] Novità e fix del .NET Framework 3.5 e .NET 3.0 Sp1

Christian Weyer hascritto un gran bel post riassuntivo delle maggiori novità e fix della nuova release.

Wednesday, October 31, 2007 4:22 AM by BlogServiceHost.Create()

# WCF Durable Services

WCF Durable Services

Saturday, January 19, 2008 2:36 PM by Compono Technology, Inc.

# re: Orcas Durable Services

Hi,

Your article is really useful for beginners who are exploring Durable services.

Found one issue with the code though. In Fig. 2, you marked TextComposer service with a "DurableServiceBehavior" attribute instead of "DurableService". This is a typo, did trouble for a while though :). Hope you can correct it.

Thanks for the post.

Thursday, February 07, 2008 10:35 AM by Channappa J B

# TechDays – Dia 2

Decorreu na passada semana entre os dias 12 e 14 de Março a edição deste ano do TechDays , o maior evento

Monday, March 17, 2008 5:27 PM by Miguel Isidoro

# TechDays – 2º Dia

Decorreu na passada semana entre os dias 12 e 14 de Março a edição deste ano do TechDays , o maior evento

Monday, March 17, 2008 5:49 PM by Miguel Isidoro

# My durable WCF RESTful calculator

A durable service in WCF is by a definition a service that can persist all its internal state across

Tuesday, November 25, 2008 2:00 PM by Pablo M. Cibraro (aka Cibrax)

# WCF Durable Services - Compono Technology

Pingback from  WCF Durable Services - Compono Technology

Sunday, March 07, 2010 11:23 AM by WCF Durable Services - Compono Technology

# Throttling in WCF &laquo; Bhavin Patel

Pingback from  Throttling in WCF &laquo; Bhavin Patel

Monday, July 26, 2010 8:36 PM by Throttling in WCF « Bhavin Patel

# BizTalk and the Cloud &laquo; MS Innovations Blog

Pingback from  BizTalk and the Cloud &laquo; MS Innovations Blog

Wednesday, September 29, 2010 4:55 PM by BizTalk and the Cloud « MS Innovations Blog

# re: Orcas Durable Services

Orcas durable services.. Dandy :)

Monday, April 04, 2011 5:41 AM by weblogs.asp.net

# re: Orcas Durable Services

Hello Everyone! I like watching BBC Football online.

Monday, June 06, 2011 5:03 PM by football

# re: Orcas Durable Services

I'm definitely enjoying the theme/design of your weblog. Do you ever run into any internet browser compatibility problems? A little number of my weblog audience have complained about my blog not working properly in Explorer but looks fantastic in Firefox. Do you've any suggestions to assist fix this issue?

Thursday, July 07, 2011 10:27 PM by Georgeanna Schaetzle

# Blogged By Chris &raquo; MCPD Exam 70-513 (Part 5): Managing the Service Instance Life Cycle

Pingback from  Blogged By Chris &raquo; MCPD Exam 70-513 (Part 5): Managing the Service Instance Life Cycle

# re: Orcas Durable Services

I was suggested this blog by my cousin. I am not sure whether this post is written by him as nobody else know such detailed about my difficulty. You are incredible! Thanks!

Wednesday, August 01, 2012 3:13 AM by Sherinas Canasb

# re: Orcas Durable Services

There may be a fresh creation that everybody who smokes must find out about. It is referred to as the ecigarette, also known as a smokeless cigarette or <a href=www.vaporultra.com/.../>do electronic cigarettes work </a> , and it can be shifting the lawful panorama for cigarette people who smoke throughout the planet.

The patented Electronic cigarette gives to proficiently simulate the practical experience of using tobacco an genuine cigarette, with out any in the health and fitness or lawful difficulties encompassing classic cigarettes.

Although E cigs search, really feel and flavor much like standard cigarettes, they functionality pretty in another way. The thing is, electric cigarettes never basically burn off any tobacco, but relatively, any time you inhale from an e-cigarette, you activate a "flow censor" which releases a water vapor that contains nicotine, propylene glycol, and a scent that simulates the flavour of tobacco. All of which basically ensures that e cigarettes enable you to get your nicotine fix when avoiding every one of the cancer resulting in agents discovered in standard cigarettes like as tar, glue, numerous additives, and hydrocarbons.

In addition to becoming healthier than traditional cigarettes, and perhaps most significantly of all, would be the undeniable fact that electric cigarettes are fully lawful. Since E-cigarettes don't contain tobacco, you can lawfully smoke them anyplace that conventional cigarettes are prohibited like as bars, dining establishments, the get the job done area, even on airplanes. Furthermore, electric cigarettes allow you to smoke with no fears of inflicting harm on other people due to terrible second hand smoke.

The refillable cartridges are available a mess of flavors together with nicotine strengths. You can get regular, menthol, even apple and strawberry flavored cartridges and nicotine strengths are available complete, medium, light, and none. Though e-cigarettes are technically a "smoking alternative" instead than the usual cigarette smoking cessation unit, the array of nicotine strengths presents some apparent possible as an assist from the types makes an attempt to stop cigarette smoking and appears to get proving well-liked within just that marketplace.

The good detail about electronic cigarettes as apposed to mention, nicotine patches, is e-cigarettes create the exact same tactile sensation and oral fixation that people who smoke motivation, though satisfying kinds tobacco cravings also. If you acquire a drag from n electronic cigarette you truly really feel the your lungs fill by using a heat tobacco flavored smoke and when you exhale the smoke billows out of your lungs similar to common using tobacco, on the other hand, as described, that smoke is actually a substantially much healthier drinking water vapor that easily evaporates and as a consequence isn't going to offend any one while in the rapid vicinity.

Whilst electric cigarettes are already all over for some time in various incarnations, it's been recent advancements in the technology in addition to ever increasing limitations from smoking that have propelled the e-cigarette right into a new identified recognition. Should you be enthusiastic about a healthier alternative to smoking cigarettes, or when you only desire to hold the flexibility to smoke where ever and each time you'd like, an electric cigarette may be the answer you have been on the lookout for.

Sunday, September 23, 2012 5:08 PM by Grierhoom