Author Archives: kenny

Sudafed difficulties

meth?Probably due to the lovely Seattle November weather (i.e. 46 degress and rainy), I’m in the process of fighting a joyous head cold. To aid me in this process, I stopped by Rite Aid to pick up some Sudafed. All I could find was “Sudafed PE”. Finally I found a card for Sudafed to trade in at the pharmacy.

Turns out that while Sudafed is still non-presecription, a recent law requires you to have id checked so that you don’t run home and put it into your meth lab. God forbid you’re buying it because you have a cold, or want to make some jewelry.

You can get the non-Pseudoephedrine version on the shelf, but based on my 1 day side-by-side, I’ve found that phenylephrine is not nearly as effective.

The whole thing is reminiscent of the South Park cough syrup episode….

From Contract to Channel

When you create a client channel through ServiceModel, the shape of the channel is determined by various properties of your contract. Roughly the mapping is as follows:

OneWay Request/Reply Session Callback Channel
Any Any No Yes IDuplexChannel
Any Any No Yes IDuplexSesionChannel
Any Any Yes Yes IDuplexSessionChannel
Yes Yes No No IDuplexChannel
Yes Yes No No IRequestChannel
Yes Yes No No IDuplexSessionChannel
Yes Yes Yes No IDuplexSessionChannel
Yes Yes Yes No IRequestSessionChannel
Yes No No No IOutputChannel
Yes No No No IDuplexChannel
Yes No No No IDuplexSessionChannel
Yes No No No IRequestChannel
Yes No Yes No IOutputSessionChannel
Yes No Yes No IDuplexSessionChannel
Yes No Yes No IRequestSessionChannel
No Yes No No IRequestChannel
No Yes No No IDuplexChannel
No Yes No No IDuplexSessionChannel
No Yes Yes No IRequestSessionChannel
No Yes Yes No IDuplexSessionChannel

ServiceModel also has internal adapters so that, for example, if your stack supports IOutputSessionChannel, then ServiceModel can adapt that channel to a desired IOutputChannel. More on this in a later post.

While my Guitar Gently Weeps

Last Saturday, Driftwood played at Siam’s on Lake Union. We were accompanied by the Blue Scholars, who not only great DJs but really nice guys. The theme for the evening was “Thai me up”, and a few people really got into the leather and lace theme (pictures coming soon I promise!).

Unfortunately, we are now looking for a new guitarist. There’s no “Behind the Music” story here, just that Aaron Goldfeder (our esteemed lead guitar) has left Microsoft and is travelling the world until next October. So if you know any guitarists in Seattle, let me know! Bonus points if your guitarist can double on vocals and has some songwriting inclinations!

In-proc transport thoughts

Every couple of months someone asks: “does Indigo have an in-proc transport?” Which usually means “does Indigo have a way of sending messages so that it doesn’t ever leave the app-domain?” When this request is made of the performance team, Al Lee’s canned response is “why aren’t you using named pipes? Is it not fast enough?” Turns out that our named pipe transport has (so far) been fast enough for all the scenarios that have come to us. That is, in all of these cases, the transport is contributing very little to the overall cost.

All that aside, it’s still an interesting problem (and one I expect we’ll have to solve in the next version or two in order to expand our scope for “near” scenarios). The key thing to remember when writing any transport, even an in-appdomain one, is that boundaries must still be honored. That is, the Message must go through WriteMessage(XmlWriter) and be reconsituted through ReadMessage(XmlReader). As Yasser illustrated in his layered “protocol” channel, a sanctioned extensibility point is wrapping the Message and then performing your actions at Write or Read time. Trying to preempt this step has the same pitfalls as performing a shallow copy where you really need a deep copy: it just doesn’t work!

I do plan on mocking up an in-appdomain transport in the next few weeks. I will of course share the results here. For those interested, my plan of attack would be to first write a basic transport using binary for the encoding and a shared queue for “transport”. Future iterations would optimize both the queue and the format (since we don’t need to serialize strings or other immutable objects for example).

Parents meet the Parents

Lauren and I have 4 sets of parents between us. When we got engaged they all asked when they would get to meet each other. Within a week my Mom, Dad, step-Mom, and step-Dad had booked plane tickets and hotel rooms for a weekend in LA. We hoped this was foreshadowing of logistical ease for the wedding (verdict is still out, but I remain hopeful).

Lauren and I flew down last night, and today was day one of three. So far it’s been quite entertaining (as LL and I expected). Less fiascos, and much more fun than the movie “Meet the Parents” (which was a waste of time). And so far no ultra-embarrassing stories (which I don’t expect to last throughout the weekend). Just a bunch of silliness and wine and vodka! 🙂

502 (Bad Gateway) and Http clients

In the office I get all sorts of interesting questions about our transports. I’ve realized that I really should share the answers with those of you kind enough to be following along. Today’s tidbit deals with an issue encountered on the Microsoft corp-net, but there’s no reason it can’t happen outside of this deployment, especially if ISA Firewall Client is installed.

The issue is with HTTP-based Indigo clients, and manifests itself as follows:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (502) ProxyError (The URL is invalid. The request was not entered correctly. Enter the correct URL and try again.) -> System.Net.WebException: The remote server returned an error: (502) bad gateway.

The likely culprit is your proxy settings, which by default we pick up from the system. If you have autoproxy setup, then your Indigo client will possibly be running an autoproxy detection script, and doing all sorts of other “magic” that can interfere with accessing local sites. To correct this, you have a few options:

  • Set useDefaultWebProxy=false in your binding (available on basicHttpBinding, wsHttpBinding, and httpTransportBindingElement). If you don’t want to use any proxy at all, then this is a viable option for you
  • Fix your system proxy settings (i.e. turn off autoproxy if necessary, etc). This is more the solution if you’re having global HTTP issues
  • Specify a proxy (and optionally proxy authentication scheme) in your binding. You need to do this in conjunction with diabling useDefaultWebProxy so that your settings actually take effect.

Protocol Channel Example: Chunking

In my quick PDC recap I promised to post Yasser‘s demo code. So before I digress: here is the code for a protocol chunking channel.

There is a lot more refinement to be added in order to make this production-level, but it’s a great illustration of the power and flexibility of a layered channel model. We have streaming over some Indigo transports (TCP/Named Pipe datagram, and HTTP requests and responses). However, these streams suffer from connections getting dropped mid-message, and need to be secured, routed, etc at the transport layer.

Yasser’s chunking channel nicely sidesteps all of these issues. By fragmenting/reassembling at the SOAP layer, each SOAP “chunk message” can be secured using WS-Security, reliably sent using WS-RM, and even transacted using WS-Transactions. Even better, this solution works for streaming a Message over any arbitrary transport. Which means you can write a simple streaming media server by adapting the chunking channel and using it in conjunction with a Udp multicast transport. Maybe I’ll mock one up next week even 🙂

For those not on commnet, I’ve posted the slides from my PDC talk here. Enjoy!

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.