Category Archives: Indigo

Posts related to Indigo and Web Services

WCF: Efficient Buffer Management

In order for a Transport to read and write Messages, it may buffer the serialized message. At the very least, the Headers need to be buffered. And in many cases (such as to avoid head of the line blocking issues), buffering the entire message is necessary.

While the CLR’s garbage collector does a really good job of recycling memory, there are still costs involved with each allocation. These costs include zeroing out the buffer, as well as the GC churn. As our performance dev says “no work is better than some work”. A bunch of Indigo R & D has gone into creating an efficient way to pool buffers given two knobs:

  • MaxBufferPoolSize – the total number of bytes to pool
  • MaxItemSize – maximum size of an item stored in the pool

With proper tuning, large (>10%) increases in performance can be witnessed. This functionality is exposed through System.ServiceModel.Channels.BufferManager. If you are writing a custom channel, you can create a BufferManager through the static method:

BufferManager.CreateBufferManager(long maxBufferPoolSize, int maxSize)

Then instead of calling “new byte[n];“, you can call “bufferManager.TakeBuffer(n);“. Just remember to call bufferManager.ReturnBuffer(buffer) (in a finally block if necessary) when you are finished. Lastly, you can call bufferManager.Clear(); if you ever want to flush the cache (e.g. after a certain amount of idle time).

On the built-in WCF Bindings and Transport Binding Elements, we expose MaxBufferPoolSize as a property for you to control our cache footprint. If you are sending small (< 64K) messages, then the default value of 512K is likely acceptable. For larger messages, it's often best to avoid pooling altogether, which you can accomplish by setting MaxBufferPoolSize=0. You should of course profile your code under different values to determine the settings that will be optimal for your application.

Back From PDC: Have some code!

While others were able to get a number of blog entries together, I spent the majority of my time at the conference either talking to customers, or in final preparation for my talk on Channel Extensibility.

Messaging over RFC 1149Yasser and I went through the basics of extending the channel layer to write a custom transport and a custom layered channel. I walked through writing a custom TCP-based transport channel. I then adapted that channel to interop with WSE 3.0 Beta. I’ve posted the code (along with a brief README) here. As time permits I’ll walkthrough the important pieces in future posts.

Yasser covered writing a custom layered channel (also called a “protocol channel”). He wrote a “chunking channel” that allowed you to fragment a Message into a number of smaller messages (the maximum size of which is controlled through a quota). These chunks would get reassembled on the receiving side, which then enables streaming scenarios over buffered transports. Other implications include that you can use WS-Security (and WS-RM) in conjunction with chunking to reliably and securely stream data over any transport. Very powerful. Code for the chunking channel to be posted in the next few days.

PDC Live and Online

A few quick notes as I’m scrambling to get my final ducks in a row for PDC 05.

If you aren’t able to attend in person, you can still keep up on all the happenings at pdcbloggers.net. They have aggregated feeds from both speakers and attendees, and it’s a good first stop in checking the online pulse of the conference.

And for those of you joining us in LA, you can check out my talk in Room 406 AB, on Thursday, September 15 from 3:45-5PM. I’ll also be roaming around the WCF Track Lounge and Hands on Labs, and at the WCF Extensiblity table during Ask the Experts. See you next week!

"Stuffing" Packets with net.tcp and net.pipe

One performance tuning knob you can use over Indigo’s TCP and Named Pipe transports is our level of batching messages. Sockets programmers may be familiar with this concept as Nagle’s algorithm.

In brief, you can make the tradeoff between latency and maximizing packet usage by setting 3 knobs:

  1. IContextChannel.AllowOutputBatching (or message.Properties.AllowOutputBatching at the Channel layer)
  2. bindingElement.MaxOutputDelay
  3. bindingElement.ConnectionBufferSize

When you set AllowOutputBatching=true, you are saying “hold on to this message in a local buffer to send out with other serialized messages if possible”. ConnectionBufferSize determines the size of the this local buffer (as well as the buffer sizes used by the underlying network objects). MaxOutputDelay specifies the maximum amount of time that we will wait for more data to package with a batched message. The default value of MaxOutputDelay is 200 milliseconds.

One last note: when using the typed programming model, these values only affect OneWay methods. For request-reply, ServiceModel will always optimize for latency and will set AllowOutputBatching = false.

PDC 2005: Learn all about Channels!

PDC'05 - Developer PoweredRight now there are two things that are consuming my life at work. The first is flushing out bugs and polishing off the final details of Indigo Beta 2. In the transports area you’ll see a lot of new HTTP functionality in Beta 2, including HTTP Streaming, cookie support, and fine grained extensibility to support RESTful scenarios. And we’ve made usability improvements across the board based on Beta 1 feedback. Keep the comments/bugs coming and let us know what still needs work for your scenarios!

The second is preparing for Microsoft’s Professional Developer Conference, affectionately known as “PDC”. PDC is Microsoft’s forward-looking developer conference (i.e. what’s coming as opposed to what’s shipped), and has a ton of breakout sessions about Avalon, Indigo, Whidbey, Office, Vista, and more.

If you’re going to be at the PDC, you should come see Yasser and I lift the curtain on Indigo’s Channel Layer. We’ll go over many of the intricacies involved in writing custom transports and custom layered channels. You’ll also be able to pepper me with questions at any point during the conference.

The official abstract describes our talk as follows:

Windows Communications Foundation (“Indigo”): A Deep Dive into Extending the Channel Layer
One of the most powerful ways you can extend the Windows Communications Foundation (formerly codename “Indigo”) is by teaching it to speak additional protocols and transports. Want to use the Windows Communications Foundation to talk directly to a system that understands only proprietary protocols? No problem. Want to use the Windows Communications Foundation to build reusable SOAP-based protocols? We have you covered. This session shows you how to write a custom Windows Communications Foundation transport that can be used as seamlessly as the built-in transports (e.g. HTTP and TCP). It also shows you how to write a custom SOAP-based protocol that composes with the other built-in protocols.

I promise it will be entertaining (if I’m wrong you can bring tomatoes). See you there!

Resolving conflict: Http ports and XPSP2

A giant leap forward in Windows HTTP technologies was introduced with Windows Server 2003, namely http.sys. Http.sys includes a kernel-mode listener that can dispatch to any process on the machine. This was great news to those of us that wanted to share port 80 with other applications (IIS for example). It also has a comprehensive namespace security mechanism which admins can use to delegate sections of the global hierarchical directory space to less-privileged accounts. IIS 6.0 (which shipped with Server 2003) was built on top of http.sys and so did not require exclusive access to its configured port #s.

Indigo’s standalone HTTP IChannelListeners are built on top of http.sys. That means that if you are not hosted in IIS, your process will need to have access to any http addresses that your ServiceHost is configured with. If the process is not running as admin you will need to add a reservation using httpcfg.exe. Alternatively, you can call the HTTP configuration APIs, such as HttpSetServiceConfiguration, directly.

There is one more wrinkle when working on XPSP2. While http.sys was backported to XP as part of Service Pack 2 (yay), IIS 6.0 was not (boo). This means that if you have IIS running on your XP box, then you are using IIS 5.1 which is built on top of a listening socket and thus owns port 80. If you try to open a Service using port 80 while IIS is running you will get the following error:

AddressAlreadyInUseException: HTTP could not register URL http://+:80/myService/ because TCP port 80 is being used by another application.

You have 2 choices to remedy this situation:

  1. Stop IIS (using “net stop w3svc”)
  2. Setup your service to use a different port#

Setting up a different port# is usually a simple matter of changing your Service’s URL. However, a more subtle variation of this failure occurs for clients that use WsDualHttpBinding (or a custom binding with CompositeDuplexBindingElement and HttpTransportBindingElement). Your indication here is the inclusion of “Temporary_Indigo_Addresses” as in:

AddressAlreadyInUseException: HTTP could not register URL http://+:80/Temporary_Listen_Addresses/51E705D5-E7B5-472B-B6B9-A6A60FE93B7A/ because TCP port 80 is being used by another application.

When your client is using a Dual binding, then the system creates a temporary address to listen on, in order to establish two-way communication over two one-way channels. For HTTP, this address by default is setup on a subtree of http://+:80/Temporary_Indigo_Addresses. This has the advantage of being a namespace pre-ACLed by Indigo for access by all processes. You can override this default through the ClientBaseAddress property on WsDualHttpBinding and CompositeDuplexBindingElement. You can do this either through code:

binding.ClientBaseAddress = "http://localhost:8000/myClient/"

or config:

<wsDualHttpBinding clientBaseAddress="http://localhost:8000/myClient/"/>

Good luck on future port conflict avoidance!

Channels 130: Configuration support

The final piece that we need to add to our Transport is configuration support. To expose our transport through config, we need to implement two configuration sections.

Binding Element Extension Section

The first class we add is to configure UdpTransportBindingElement. This is so that custom binding implementations can include udp. In UdpTransportSection we define our configuration section name (how we are referenced from config), the type of our binding element, and how to create our binding element; all with just a few simple overrides. We can then register our extension section in a .config file as follows:

<configuration>
 <system.serviceModel>
  <extensions>
   <bindingelementextensions>
    <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportSection, UdpTransport" />
   </bindingelementextensions>
  </extensions>
 </system>
</configuration>

And it can be referenced from custom bindings to use UDP as their transport:

<configuration>
 <system.serviceModel>
  <bindings>
   <customBinding>
    <binding configurationName=”UdpCustomBinding”>
     <udpTransport/>
    </binding>
   </customBinding>
  </bindings>
 </system.serviceModel>
</configuration>

Binding Section

The second class we add is to configure SampleProfileUdpBinding, our “standard binding”. Through SampleProfileUdpBindingSection we expose this binding to the configuration system. Most of the methods delegate to SampleProfileUdpBindingConfigurationElement, which derives from StandardBindingConfigurationElement.

SampleProfileUdpBindingConfigurationElement has properties that correspond to the properties on SampleProfileUdpBinding, and functions that map from the ConfigurationElement to Binding and vice-versa.

Finally, we need to override the OnApplyConfiguration() function in our SampleProfileUdpBinding:

protected override void OnApplyConfiguration(string configurationName)
{

SampleProfileUdpBindingSection section = (SampleProfileUdpBindingSection)ConfigurationManager.GetSection(UdpConstants.UdpBindingSectionName);
SampleProfileUdpBindingConfigurationElement element = section.Bindings[configurationName];
if (element == null)
{

throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, “There is no binding named {0} at {1}.”, configurationName, section.SectionInformation.Name));

}
else
{

element.ApplyConfiguration(this);

}

}

To register this handler with the configuration system, we add the following section to a .config file:

<configuration>
 <configSections>
  <sectionGroup name=”system.serviceModel”>
   <sectionGroup name=”bindings”>
    <section name="sampleProfileUdpBinding" type="Microsoft.ServiceModel.Samples.SampleProfileUdpBindingSection, UdpTransport" />
   </sectionGroup>
  </sectionGroup>
 </configSections>
</configuration>

It can then be referenced from serviceModel config:

<configuration>
 <system.serviceModel>
  <client>
   <endpoint configurationName=”calculator”

address=”soap.udp://localhost:8080/”
bindingConfiguration=”CalculatorServer”
bindingSectionName="sampleProfileUdpBinding"
contractType= “Microsoft.ServiceModel.Samples.ICalculatorContract”>

   </endpoint>
  </client>
 </system.serviceModel>
</configuration>

The result is a completely functional third party transport that can be used in any Indigo program!

The Indigo "Foundation"

Today we announced the official names for Indigo, Avalon, and our ship vehicle (formerly known as “WAP” or “Windows API Pack”).

It has been decreed that Indigo will henceforth be known as the Windows Communication Foundation. But don’t be surprised if I continue to refer to it as “Indigo” for a little while 🙂

To round out the batch, Avalon is dubbed the Windows Presentation Foundation, and we are all part of the WinFX Runtime Components.

In related news, Windows Vista Beta 1 is now available for MSDN subscribers, and the official Beta 1 drop of WinFx Runtime Components (eerily similar to our May CTP) is also available.

Lastly, check out Windows Vista Developer Center to see lots of pretty pictures and learn how the new branding of Longhorn will bring new clarity to your world 😉

Channels 120: Binding your Factories

Now that our Factories and Channels our built, we need to expose them to the Service/Proxy system. Channels fit into this system through the concept of a Binding. A binding represents the communication stack associated with a service endpoint.

In essense, a Binding is a top-level container for a collection of BindingElements. Each binding element is used to configure (and then build) a layer of the Channel stack. These binding elements are the core of how you configure and build a channel (both transport and layered).

Note that while the Channel interfaces are all free-threaded objects, the BindingElement configuration object is single-threaded.

UdpTransportBindingElement

UdpTransportBindingElement, which derives from BindingElement and IChannelBuilder, is the binding element for our Udp Factories. It overrides 2 methods in order to build the factories associated with our binding:

public IChannelFactory BuildChannelFactory(ChannelBuildContext context)
{

return new UdpChannelFactory();

}

public IListenerFactory BuildListenerFactory(ChannelBuildContext context)
{

return new UdpListenerFactory();

}

If we wanted to expose any other configuration knobs (such as a certain number of retries for added reliability), then these would be exposed as properties on UdpBindingElement and the information would be propagated to UdpChannelFactory and/or UdpListenerFactory at build time.

Bindings fall into two main categories:

Custom Binding usage

The first way our UdpBindingElement can be used is through a Custom Binding. A custom binding allows the user to create their own binding based on an arbitrary set of binding elements. By simply writing a BindingElement for your layer of the channel stack, any developer can now write a custom binding with Udp as its transport.

Custom bindings provide a large amout of flexibility, which is both a blessing and a curse. It’s very easy to shoot yourself in the foot by misconfiguring a custom binding. Usually only certain settings on a transport are compatible with certain settings on Security, Reliable Messaging, Transactions, etc. The way to address this miasma of combinatorics is through predefined bindings (also known as “standard” bindings).

Predefined Binding usage

Indigo provides a number of Predefined Bindings, such as BasicProfileBinding, NetProfileTcpBinding, and WsProfileBinding. Each of these bindings is associated with a well-defined class of services. For example, BasicProfileBinding is for use with ASMX-style services, WsProfileBinding is for WS-* enabled services such as BEA or Websphere, and NetProfileTcpBinding is for Indigo-based TCP services. Each of these predefined bindings is built on top of the same binding elements a custom binding would use, but they provide a simpler programming model that will yield channel stacks conformant with their target usage.

For our Udp experiment, we will create a “sample profile”, which allows for UDP and optional reliability (which will add Composite Duplex and Reliable Messaging to the Channel stack). SampleProfileUdpBinding, which derives from Binding, contains up to three binding elements within it: UdpTransportBindingElement, CompositeDuplexBindingElement, and ReliableSessionBindingElement. It exposes a few high-level knobs, and configures the resulting binding stack in CreateBindingElements():

public override ICollection<BindingElement> CreateBindingElements()
{

Collection<BindingElement> bindingElements = new Collection<BindingElement>();

if (ReliableSessionEnabled)
{

bindingElements.Add(session);
bindingElements.Add(compositeDuplex);

}

bindingElements.Add(transport);

return bindingElements;

}

One more step remains now, and that is to expose our custom transport to the configuration system. Stay tuned 🙂