Human Windows Workflow Foundation 3.5 over WCF

August 4, 2010

Couple of things I have started to notice some basic gotch-yas for developers around my place of employment.

Error on activity validation – cannot find condition

You will get this error when using embedded declarative code conditions in anything from a WhileActivity to a IfElseActivity. Basically if your .rule file is not named exactly the same as your .xoml file (including case!) the *.rules file will not load.

To fix this open up the *.csproj file and change the dependency to include the correct casing and names for the rules.

Powershell: Script to create WCF 4.0 WAS (net.tcp, http, net.msmq bindings)

May 5, 2010

Was tinkering with power-shell today to finish up an automated build environment that handles 12+ WCF services. When I stumbled onto a large issue (read: I am a novice powershell user). I could not effectively open powershell and set the defaultProtocols required to enabled net.msmq, net.tcp.

After a bit of searching I ended up with the below solution. It seems to work well enough. I’m trying to get a demo together of an automated build and deploy which handles the entire process of taking servers out of the load balancer gracefully bleeding current requests, and then deploying, and updating. But that is for another day…

Enjoy the powershell goodness…

Import-Module WebAdministration

$fqn = Read-Host "Enter Domain Name (ie test.com)"

Write-Host -ForegroundColor green "Creating Directory C:\inetpub\wwwroot\$fqn..."

New-Item C:\inetpub\wwwroot\$fqn -type Directory

Write-Host -ForegroundColor green "Creating AppPool IIS:\AppPools\$fqn..."
New-Item IIS:\AppPools\$fqn
$pool = Get-Item IIS:\AppPools\$fqn
$pool.processModel.userName = "DOMAIN\USERID"
$pool.processModel.password = "P@SSW0RD"
$pool.processModel.identityType = 3
$pool.managedRuntimeVersion = "v4.0"
$pool | Set-Item

Write-Host -ForegroundColor green "Creating Website IIS:\Sites\$fqn..."
$dns = ":80:" + $fqn
New-Item iis:\Sites\$fqn -bindings @{protocol="http";bindingInformation=$dns} -physicalPath c:\inetpub\wwwroot\$fqn

Write-Host -ForegroundColor green "Adding NET.TCP to IIS:\Sites\$fqn..."
New-ItemProperty IIS:\sites\$fqn -name bindings -value @{protocol="net.tcp";bindingInformation="8080:$fqn"}

Write-Host -ForegroundColor green "Enabling [http,net.tcp,net.msmq] protocols on IIS:\Sites\$fqn..."
Set-ItemProperty IIS:\Sites\$fqn -name applicationDefaults.enabledProtocols -value "http,https,net.tcp,net.msmq"

Write-Host -ForegroundColor green "Assigning AppPool to IIS:\Sites\$fqn..."
Set-ItemProperty IIS:\Sites\$fqn -name applicationPool -value "$fqn"

Removing a Site

Removing a site is pretty basic right now, in time, when I have some and can get over the cold I’d like to take this to the next level by setting up a job to take the site offline and have the load balancer bleed people off…

Import-Module WebAdministration

$fqn = Read-Host "Enter Domain Name (ie test.com)"

Write-Host -ForegroundColor green "Removing AppPool $fqn..."
Remove-Item IIS:\AppPools\$fqn -recurse

Write-Host -ForegroundColor green "Removing IIS Site $fqn..."
Remove-Item IIS:\Sites\$fqn -recurse

Write-Host -ForegroundColor green "Removing Directory c:\inetpub\wwwroot\$fqn..."
Remove-Item c:\inetpub\wwwroot\$fqn -recurse

High Performance WCF Services : netTcpBinding

April 12, 2010

A bit of a divergence away from Azure today. I had two questions I wanted to answer before running comparison of performance in Azure.

I received some requests for some down-loadable source. It can be downloaded here: NetTcpBindingExample

How fast can WCF go? How about ~29,000 requests per second?

Ah, the eternal question… The benefit of finding the answer is that it puts some sanity checks in place whenever we are planning our architecture. If a business user wants to have two million transactions processed in a minute can you do this with WCF? What about 1 hour? What about 24 hours? Somewhere in there is a “yes we can do this”, but alas, unless you read on you wont know where to start…

Further if you don’t know the absolute fastest WCF can perform how do you know if you are running ’slow’ or ‘good’. What about how many servers you may need? Baselines are great tools… read on…

WCF Binding Comparisons

Below charts show the comparison of basicHttpBinding, binaryHttpBinding, and netTcpBinding.

One Way Operations with Basic String (Calls Made Per Second)
Compare2

Large Object Operation with Complex Object (Calls Made Per Second)
Compare

By far the best channel is netTcpBinding for performance – both for large objects and one-way operations. You’ll note the benefit of binaryHttpBinding over basicHttpBinding is not apparent when dealing with small objects. This makes sense considering the network savings aren’t in play for our simple string operation.

The Service Tested

To answer “the fastest” question and to do sanity checks the below was the service interface created.

[ServiceBehavior(
    ConcurrencyMode=ConcurrencyMode.Multiple,
    InstanceContextMode=InstanceContextMode.Single,
    AddressFilterMode=AddressFilterMode.Any)]
public class HelloWorldService : IHelloWorldService
{
    public void MockOneWayOperation(string name)
    {
          // do absolutely nothing
    }

    public CompositeType MockTwoWayOperation(CompositeType composite)
    {
        return composite;
    }
}

You will note that this service does absolutely nothing. We took out database calls, or any other dependency… Its the simplest and most pure service ever… you can’t make a faster service so it’s good in that it eliminates any external dependency (save network).

It is recommended that you always call Channel.Open()

On top of just the binding chosen you have one more thing to worry about (well two to be exact). If you are calling a WCF service please be sure to call yourclient.open(); explicitly before actually calling a service operation.

Calling svc.Open() on netTcpBinding helps, please do it… your mom will thank you
netTcpBinding_Small

Calling svc.Open() on WCF BasicHttpBinding helps a lot as you can see below
BasicHttpBinding_Small

Configuration of net.tcp when running in port sharing mode:
http://msdn.microsoft.com/en-us/library/aa702669.aspx

Note: When running your WCF services in netTcpBinding using port sharing the configuration of the netTcpBinding is ignored. You must change these settings as described in the above MSDN document to get maximum throughput.

My performance isn’t that good?! What voodoo are you using?!

Please be sure when running your tests you answer NO to both these questions:

Is your web.config in debug mode?
Is your test client running in debug?

Running with any of the above is a recipe for disappointment. As an example of how much of a disappointment you are in for, the below chart shows the potential performance hit you will take if you have either the server or the client in debug (or both).

Keep in mind this is the same high performance netTcpBinding!

The only thing I am doing here is running the service in debug and the client tester (VS Unit Test) in debug.

Note the extreme difference in performance when client is running in debug
debug

When measuring performance please be sure your WCF service is not running in debug (web.config) and your client is not running in debug. If you are using a Visual Studio Unit Test for quick performance evaluation be sure to run the unit test as “Run Selection”, not “Debug Selection”.

Measurements

table

As you can see the running debug+debug without server GC on the fastest WCF binding will cause you to be running 29x slower than you would otherwise expect.

Maximum Performance WCF netTcpBinding Configuration…

No security, no reliable sessions, max serialization, max listen backlog.

  <system.serviceModel>
    <services>
      <service name="NetTcpBindingExample.HelloWorldService">
        <endpoint
            binding="netTcpBinding"
            bindingConfiguration="ultra"
            contract="NetTcpBindingExample.IHelloWorldService"/>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="ultra"
                 maxBufferPoolSize="2147483647"
                 maxBufferSize="2147483647"
                 maxConnections="2147483647"
                 maxReceivedMessageSize="2147483647"
                 portSharingEnabled="false"
                 transactionFlow="false"
                 listenBacklog="2147483647">
          <security mode="None">
            <message clientCredentialType="None"/>
            <transport protectionLevel="None" clientCredentialType="None"/>
          </security>
          <reliableSession enabled="false"/>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.web>
    <compilation debug="false"/>
  </system.web>
  <runtime>
    <gcServer enabled="true"/>
  </runtime>