Author Archives: kenny

2007 Thai Tom Winner: Panang Curry

After 15 “official” trips to Thai Tom over the past year, we have a winner!

Thai Tom Tournament

The inaugural event included all 16 dishes in the name of science. Next year will only include “Division A” (the top 8 dishes). Stay tuned for initial seeding and matchups….

InstanceContextMode, ConcurrencyMode, and Server-side Threading

When trying to write a scalable web service, you need to be aware of a few properties that affect how the WCF runtime will dispatch requests to your service: InstanceContextMode and ConcurrencyMode. In a nutshell, InstanceContextMode controls when a new instance of your service type is created, and ConcurrencyMode controls how many requests can be serviced simultaneously. The default InstanceContextMode is InstanceContextMode.PerSession, and the default ConcurrencyMode is ConcurrencyMode.Single.

Others have covered the details of these two knobs in detail, you can check them out for more background. Here I’m simply going to explain the affect these settings can have on your threading behavior.

If you have set ConcurrencyMode == ConcurrencyMode.Single, then you don’t have to worry about your Service instances being free-threaded (unless you are doing concurrent code within your methods). The only time multiple calls are allowed is when there are multiple instances. For InstanceContextMode.Singleton, you will get one method call at a time since you only have a single instance. For InstanceContextMode.PerCall or PerSession, ServiceModel will spin up extra threads up to a throttle in order to handle extra requests. There’s one possibly unexpected twist here. That is, when using a session-ful binding there will only be one outstanding instance call per-channel. Even with InstanceContextMode.PerCall. This is because WCF strictly maintains the in-order delivery guarantees of the channel with ConcurrencyMode.Single. So when using a session-ful binding (i.e. the default NetTcpBinding or NetNamedPipeBinding) + ConcurrencyMode.Single, InstanceContextMode.PerCall and InstanceContextMode.PerSession will behave the exact same way from a server-side threading/throttling perspective with regards to a single channel.

ConcurrencyMode == ConcurrencyMode.Reentrant is similar, except you can trigger another call to your instance from within your service (let’s say you call into a second service who calls back into you before it returns).

When you have ConcurrencyMode == ConcurrencyMode.Multiple, threading comes heavily into play. WCF will call into your instance on multiple threads unless you are using InstanceContextMode.PerCall. Throttles again will come into play (that’s a topic for another post).

To summarize, here are some basic scenarios for what happens when 100 clients simultaneously hit a service method:

Scenario 1: InstanceContextMode.Single+ConcurrencyMode.Single
Result: 100 sequential invocations of the service method on one thread

Scenario 2: InstanceContextMode.Single+ConcurrencyMode.Multiple
Result: N concurrent invocations of the service method on N threads, where N is determined by the service throttle.

Scenario 3:InstanceContextMode.PerCall+Any ConcurrencyMode
Result: N concurrent invocations of the method on N service instances, where N is determined by the service throttle

More details on MaxConnections

Here are some more “under the hood” details in response to the following question:

How is one supposed to interpret the NetTcpBinding.MaxConnections property on the client? My assumption has been that setting this property at the client only allows this number of concurrent connections, and further connection attempts will be queued until an existing connection is released.

MaxConnections for TCP is not a hard and fast limit, but rather a knob on the connections that we will cache in our connection pool. That is, if you set MaxConnections=2, you can still open 4 client channels on the same factory simultaneously. However, when you close all of these channels, we will only keep two of these connections around (subject to IdleTimeout of course) for future channel usage. This helps performance in cases where you are creating and disposing client channels. This knob will also apply to the equivalent usage on the server-side as well (that is, when a server-side channel is closed, if we have less than MaxConnections in our server-side pool we will initiate I/O to look for another new client channel).

The reason that we don’t have a hard and fast limit on your connection usage is that you already can control the connection usage through your usage of the WCF objects. That is, if you don’t want to use more than two connections, don’t create more than two client channels 🙂 Any additional knobs at the lower layer would only impede debuggability and predictability.

Note that MaxConnections applies across channels. When sending messages over a single channel, you can only send out one message at a time. That is, your second Send() call will not be initiated until your first Send() completes. In this manner, our TCP binding can guarantee in-order delivery. Also, practically speaking there would be a significant amount of complexity (and overall a negative performance hit) if we allowed interleaving of data from multiple messages, as each “chunk” would need to be annotated with a scatter/gather message marker.

Lastly, all of the above comments apply to TransferMode.Buffered (the default). When using Streaming mode, we “check out” a connection for each in-progress send (and not per-channel). So all the above statements will apply to simultaneous sends rather than simultaneous channels. Streaming TCP is a datagram (not a session-ful) channel, and so simultaneous sends are supported since each send will use a separate TCP connection. This is more similar to HTTP’s usage of TCP connections (where each in-flight request-response pair is using a separate TCP connection).

Sostanza (Seattle, WA) – CLOSED

Rating:

Tucked away in Madison Park, around the corner from the madness of Cactus, lies a charming Italian restaurant names Sostanza. I’ve had a number of memorable experiences here over the years, including a celebration of my condo purchase. Last night I discovered that the restaurant is not quite as small as I thought. While I had always dined downstairs in range of the fireplace and dimly-lit atmosphere reminiscent of eggplant napoleanQuattro of Whistler, this time we were seated upstairs. Upstairs lay a bar,about 10 tables, and a few tables on the balcony that are in hot demand during the summer months (the entire level overlooks Lake Washington and the Cascades).

We began the evening with a bottle of Valpolicella and an Eggplant Napolean. I’ve now had both Valpolicellas on Sotanza’s current wine list and have heartily enjoyed them both. This one had strong fruits, but did not overwhelm any of the pastas. As for the Napolean, I can tell you that Buffalo mozzarella + fresh tomatoes + grilled eggplant + olive oil + pesto == tasty appetizer. A solid execution and an enjoyable beginning to our meal.

seafood pasta
Sostanza is deservedly well-known for their house-made pastas. Lauren’s seafood capellini was a delightful mix of grilled scallops, prawns, and al dente capallini in a light garlic-cream sauce. The cream sauce wasn’t too thick, and the prawns were good and meaty. The scallops were a little wimpy, though certainly passable.

I couldn’t resist the option of papardelle and truffle oil that was listed on the specials menu. I can still vividly remember a similar dish I had there years ago and my mouth watered at the memory. But while the papardelle was as delicious as I remembered and the wild mushrooms paired well with the truffle oil, there was an unnecessary addition of cannelloni beans which were little more than filler. Overall it was an enjoyable pasta, but I couldn’t help but think that it was missing a little something (perhaps some goat cheese would have helped or I should have opted for even more parmesan).

papardelle and truffle oil

Our friend Ming heartily enjoyed his Saltimbocca. I stole a bite, and the veal was tender and the fresh sage was a nice touch.
Ming and his Veal

For dessert we indulged in the warm mixed berry cobbler — blackberries, blueberries, and raspberries fresh out of the oven and topped with house-made vanilla gelato. The cobbler was tasty and enormous (easily filled all four of us). I also appreciated the fact that the kitchen did not skimp on the gelato, a common failing at restaurants these days.
mixed berry cobbler w. vanilla gelato

Overall Sostanza provided another fond evening for my memories. A fine location for both 1-1 romantic dates as well as larger celebrations.

Sostanza Trattoria
1927 43rd Avenue East
Seattle, WA 98112
206-324-9701

Mon-Sat: 5:30PM-9:30PM (Dinner only)
Closed Mondays from October to March

Boat Street Café (Seattle, WA)

Rating:

Tonight Lauren and I indulged ourselves with massages at Ananda Spa (which is deserving of its own space for a review). Across the patio of the Northwest Work Lofts from Ananda Spa is the Boat Street Café. It turns out that the name comes from when the café was located on Boat Street (they were forced to relocate when that building was torn down). The food always smelled fantastic, and we often thought of stopping by for a post-massage meal. Tonight (at long last) we were able to check it out.

The menu is French-inspired, as is the café’s ambience — slate tables, fresh flowers, and minimalist touches. The very friendly waitress brought us some fresh bread to start off the meal. Yes this is a common occurrence, but the fresh mini-baguette that came straight from the oven to our table was worth calling out. I was tempted to make a meal of the baguette and butter…

But I needed to save room for the Black Cod with Pickled Peppers. Rich, silky, and buttery, the cod was matched well with the peppers and onions. Very tasty, but not meant for those looking for “lighter fare”.

Our other entree took advance notice (“30 minutes from oven to table” according to the waitress): Leek and Goat Cheese Flan. It was worth the wait, though one look at the overflowing dish that could feed a small family and I knew what we’d be having for breakfast tomorrow 🙂 This souffle contained a relatively mild goat cheese, and a fluffy texture overlaying the leeks and onions.

Overall the food was very good, and the waitstaff very pleasant. Given the richness of the cuisine however, it would be a difficult place to frequent more than once a month or so. Lunch did look like a more casual, order from the counter-based affair. I’ll report back when we have a chance to check that out!

Boat Street Café
3131 Western Ave., Suite 301
Seattle, WA 98121
206-632-4602

Tues-Sat: 11:00AM-2:00PM, 5:00PM-10:00PM (Lunch and Dinner)

Client (TCP and Named Pipe) Connection Pooling

Using the TCP and Named Pipe bindings give you a very clean mapping between IDuplexSessionChannel and the underlying network resource (socket or pipe). Namely, you can effectively treat a channel as 1-1 to a socket (I will use socket as shorthand for the generic “network resource” for the remainder of this post :)).

That being said, the lifetime of the underlying socket is not necessarily 1-1 with the lifetime of the channel. Due to our connection pooling feature in WCF, a connection can be reused over the lifetime of multiple channels. We perform connection pooling for both buffered and streaming channels. Our connection pool is configurable through TcpConnectionPoolSettings/NamedPipeConnectionPoolSettings. These settings include a GroupName that we use for isolation, an upper bound on our cache size (MaxOutboundConnectionsPerEndpoint), and timeout values for reliability and NLB support

The way connection pooling works on the client is as follows:

  • When you open a channel we will first look for a connection in our pool. This lookup is performed based on IP+port for sockets and based on endpoint Uri name for Pipes.
  • If we find an available connection in our pool then we will attempt our open handshake using .Net Framing. If this succeeds then we will associate the connection with the new channel and return from Open. If it fails then we’ll discard the connection. If we have not yet exceeded the binding’s OpenTimeout then we will repeat the “look in pool” process.
  • If no [valid] connections are found in our pool then we will establish a new connection (again, using up to the time remaining in OpenTimeout).
  • When you close a channel, after we perform our close handshake we will consider returning the connection to our pool. If we already have reached MaxOutboundConnectionsPerEndpoint, or the connection’s lifetime has exceeded LeaseTimeout then we will close the connection instead. The connection that is returned to the pool is the “raw” connection (the one that was initially accepted, prior to any security upgrades). In this way we can provide a transparent pool without leaking any security or other information.

I was going to cover the server-side usage of connection pooling in this same post, but the process of accepting and reusing connections on the server is worthy of its own topic next time 😉

Thai Tom Faceoff, Round 2

Eight months ago, Lauren and I started on an NCAA-style tournament through the 16 dishes on Thai Tom’s menu. Today began round 2, and I expect the last few meals to come out in rapid succession. This is an inexact science, as 3 chefs rotate through Thai Tom’s burners. For example, while #10 was a clear favorite based on previous tastings, today it fell short. Was it due to the change in chefs? A bad delivery of eggplant? Who knows, but it just didn’t have the gusto needed to hold up against the sassy Swimming Rama’s peanut sauce.

It is becoming clear that there are two classes of dishes at Thai Tom (Division I and Division II if you will). Dishes such as Sweet and Sour Chicken are solidly in division II, and Garlic Beansprouts is permanently disqualified (a mini-dead kenny for it). If we decide to re-stage the tournament again, we would restrict entry to Division I (I’ll provide a full breakdown when all is said and done). A recap of the current state of affairs follows:

Thai Tom Tournament

UPDATE (04/11/2007): After a break for Passover, Panang Curry handly overran #4 (Thai Sauce Chicken) as the quarter finals continue.

UPDATE (04/17/2007): Cashew Chicken cruised to an easy win over the popular, but less exciting, Pad Thai.

UPDATE (04/24/2007): Completing round 2 was a close match between #9 and #12. At the end the garlic was king for Garlic Pepper Chicken.

UPDATE (05/02/2007): They were out of Panang Curry (next time I’m instituting a forfeit rule!). So it was a back-to-back Garlic Pepper Chicken appearance, but it was no match for Cashew Chicken.

UPDATE (05/12/2007): In the closest match yet, Panang Curry squeaked by Swimming Rama (probably #1 and #2 seeds in next year’s match :))

UPDATE (06/20/2007): The winner of the 2006-07 Thai Tom crown is….Panang Curry!

Boilerplate code for custom Encoder Binding Elements

Part of the process involved in writing a custom MessageEncoder is hooking your encoder up to a binding stack. This is accomplished using a subclass of MessageEncodingBindingElement. The way our build process works is that we will take the first BindingElement within a Binding, and call [Can]CreateChannel[Factory|Listener]() on it. By default, these 4 calls will simply delegate to the BindingElement “below” them in the stack.

This default behavior is not exactly what you want in your MessageEncodingBindingElement. While most binding elements add an item to the channel stack, Message Encoders are an “adjunct” binding element. That is, they provide parameters to other binding elements (in this case the transport). The way that parameters are provided to other parts of the build process is through BindingParameters. For example, a MessageEncodingBindingElement can add itself to the BindingParameters collection:

context.BindingParameters.Add(this);

And later the TransportBindingElement can fish out the encoder when it is building the relevant factory/listener:

Collection<MessageEncodingBindingElement>messageEncoderBindingElements
= context.BindingParameters.FindAll<
MessageEncodingBindingElement>();

Unfortunately, the base MessageEncodingBindingElement does not take care of adding itself to the BindingParameters collection in its default [Can]Build methods. Therefore, every subclass needs to add the following four boilerplate overrides. Furthermore, it will be a breaking change to fix this in V2, so it’s unclear if we will be able to fix this in the next release 🙁

public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
  
if (context == null)
  {
    
throw new ArgumentNullException("context");
  }

  context.BindingParameters.Add(this);
  
return context.BuildInnerChannelFactory<TChannel>();
}

public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
  
if (context == null)
  {
    
throw new ArgumentNullException("context");
  }

  context.BindingParameters.Add(this);
  
return context.BuildInnerChannelListener<TChannel>();
}

public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
{
  
if (context == null)
  {
    
throw new ArgumentNullException("context");
  }

  context.BindingParameters.Add(this);
  
return context.CanBuildInnerChannelFactory<TChannel>();
}

public override bool CanBuildChannelListener<TChannel>(BindingContext context)
{
  
if (context == null)
  {
    
throw new ArgumentNullException("context");
  }

  context.BindingParameters.Add(this);
  
return context.CanBuildInnerChannelListener<TChannel>();
}