Author Archives: kenny

Mountain Top Dining (Whistler, BC)

Rating:

This weekend Lauren and I were up at Whistler enjoying sunny skies and residual conditions from a record snowfall. After the morning runs, we headed to the Roundhouse Lodge on Whistler mountain. But rather than face the usual ski-lunch frustrations of jockeying for a table and scrutinizing the marginal pickings in the cafeteria, I followed a tip from my friend Stefan. It turns out that both Whistler and Blackcomb mountains have a sit-down restaurant co-located with the main self-serve venues. And as Stefan says, “it’s nice getting served during your lunch break.”

We walked into Steep’s Grill at 6030′ and immediately were seated at a table with a gorgeous view of the mountains (most of the restaurant has amazing views). We had the salmon chowder which, while not earth-shattering, had a good ratio of salmon to potatoes with a hint of lemon.

We also indulged in some comfort food. The macaroni and cheese at Steeps was impressive. Classic elbow macaroni with gruyere, white chedder, parmesan, and baked Okanagan apples. The apples were a nice touch. The next time we make mac & cheese at home I’m going to add some carmelized apples.

The next day we were on Blackcomb and lunched at Christine’s, which is their sit-down restaurant at the Rendezvous. I guess I have a thing for soup when I snowboard: we ordered their wild mushroom soup, and some grilled salmon (for the protein). The mushrooms were better than the salmon chowder, though less photogenic. The salmon hit the spot, and was pretty good for 5000′ up πŸ™‚

Overall, I highly recommend spending a few extra C$$s and indulging in the more relaxed atmosphere and better food offered at Steep’s Grill and Christine’s.

Steep’s Grill at 6030′
Whistler Mountain
Whistler, BC

Christine’s
Blackcomb Mountain
Whistler, BC

Writing Clone-friendly Binding Elements

When writing a custom binding element, you will notice two constructors on the abstract base class:

protected BindingElement()
protected BindingElement(BindingElement elementToBeCloned)

The usage of the first (default) constructor is straightforward. The second one, which takes a BindingElement is a little more subtle. Its purpose is to facilitate proper implementations of BindingElement.Clone(). The recommended pattern is that all non-sealed binding elements expose such a protected ctor, and then call that ctor from their Clone() method. This allows subclasses of your binding element to be able to implement Clone in a chained manner (since you canÒ€ℒt just call base.Clone()). In other words, if I was writing a FooBindingElement, my Clone() method would leverage this constructor as follows:

protected override BindingElement Clone()
{
  
return new FooBindingElement(this);
}

If you then set a breakpoint on your Clone() method, you will see it called a bunch of times when you open a Client or Service. The reasons behind this have to do with the tension between the assurances we can (or cannot make) about side-effects of certain methods and needing to ensure the integrity of the original configured binding. Reading back over that last sentence, it probably sounds a bit obtuse. I’ll try and clarify/go into more details around our CanBuild, Build and GetPropery processes (prime users of Clone) in a future post.

Café Lago (Seattle, WA)

Rating:

On Thursday over lunch I was talking with Ed about the Italian food options available in Seattle. This must have stuck in the back of my mind, as driving home in the evening I turned to Lauren and asked “do you want to go to Café Lago this weekend?” A smile, nod, and a quick phone call secured us a prime 7:30PM Saturday evening reservation.

The Montlake neighborhood is not exactly flush with restaurants. The “main drag” consists of a brand new library branch, Fuel Coffee, the Montlake Bar & Grill, and Café Lago. So it’s no wonder that Lago, which boasts fabulous pastas and pizzas, a small but high quality wine list, and comfortable (almost minimalist chic) ambience packs in the local crowds. The atmosphere is casual but tasteful, and back in the day Gio dubbed it perfect for first dates (for posterity’s sake I’ll note that Lauren and I went there for date#4). On weekends, reservations are a must.

We started our meal with a bottle of Rosso de Montalcino and an order of “Pomodori al Forno.” They make their own variation of sun-dried tomatoes by soaking ripe Roma tomatoes in olive oil and then putting them into their wood-fired oven that they use to cook the pizzas. They are served with oil-soaked crostinis and a wheel of goat cheese, resulting in a delightful set of four create-your-own bruschettas πŸ™‚

Fire Roasted tomatoes

For the main course we ordered the two type of items that keep me addicted to Lago: a pizza and a pasta. The pizzas at Lago easily hold their own against any other restaurant in the city, the famed Via Tribunali included. For those that enjoy sausage, the Salsiccia is fantastic. Otherwise, go for the Caprino or the Giardiniere. We had a Giardiniere, and enjoyed the sweet peppers and onions, garlic, and mozzerella atop Lago’s signature tomato sauce. And with the size of the pizza we had enough to enjoy more for breakfast this morning πŸ™‚

Giardiniere pizza

Usually Lauren and I will order the lasagna every time we dine at Lago, because it is the best lasagna in the city. The sheets of pasta and the marinara sauce are made in house, and the result is an amazingly light dish that you simply have to taste yourself to understand.

Last night we shook things up a little (but only a little) by ordering their ravioli. In many ways the ravioli was a shapeshifter of the lasagna. The pasta was thin, melt-in-your-mouth surrounding a mix of fresh ricotta, mozzerella, and pecorino cheeses. They were topped by the same delightful marinara sauce that is used in their lasagna. Lago’s pastas are arguably the best in Seattle and are definitely the best I’ve had since our return from Italy.

3 cheese ravioli

Even though we had to box up part of our entreés, we still had half a bottle of wine. So when they brought us dessert menus, we took our time and finally succumbed to the siren call of the Chocolate Truffle Cake. Usually we pass on dessert, but have been tempted to try some of the choices at Lago for years. We shouldn’t have waited so long. The Chocolate Truffle Cake lives fully up to its name, with a flaky texture that is firmer than mousse, and more like, well, a chocolate truffle. It’s topped with an espresso sauce and is both sinful and impossible to hold your fork back from just one more bite. I found out that all of the desserts are house-made, and I’m looking forward to sampling some of the other tempations.

Chocolate Truffle Cake

Overall we had a very delightful meal. Chef-owner Jordi Viladas runs a quality operation, and I’ve had consistently top quality experiences at Café Lago, my one suggestion for them would be a little more variety. Not that I’m advocating a larger menu — part of what I love about Lago is the consistency of execution and eye for quality on everything from the wine list to the appetizers to the pizzas and pasts. But more of a rotation, perhaps seasonally, would help keep the choices fresh for the regulars. Just make sure to keep the lasagna on the list year-round!

Café Lago
2305 24TH Ave E (at E Lynn Street)
Seattle, WA 98112
206-329-8005

Closing Down Channels

When using channels, eventually the time comes to say goodbye. You are not going to send any more messages, and you want to close down as gracefully as possible. So you call channel.Close. If it throws, your application goes down since you didn’t add a try/catch clause and you are S.O.L. Maybe you’ve written a chatty peer to peer application and you get a message such as:

System.ServiceModel.ProtocolException: The channel received an unexpected input message with Action ‘my action’ while closing. You should only close your channel when you are not expecting any more input messages.

Or perhaps your channel faulted due to network inactivity or some other transient error. The bottom line is that there are a number of situations where an exception from channel.Close is expected and should be handled gracefully. In these cases, the expected exceptions from close could be subclasses of CommunicationException and TimeoutException. So a more robust call to Close() would look like:
try
{
  
Console.WriteLine(wcfClient.Add(4, 6));
   channel.Close();
}
catch (TimeoutException timeout)
{
  
// Handle the timeout exception
   channel.Abort();
}
catch (CommunicationException communicationException)
{
  
// Handle the communication exception
   channel.Abort();
}

One last note: just because some of our CommunicationObjects are marked as IDisposable, doesn’t mean that you should jump on the using() statement with them. Please read about the issues involved with using and Communication Objects first.

Remedy Teas on Capitol Hill

Last night Lauren and I passed by a very unique new hangout that’s opened up near our place: Remedy Teas. It’s a very comfortable space that not only has 150+ teas (they can give Typhoon a run for their money), but they also serve food, cocktails (some with tea in them), and locally made chocolates by Ivy Chan.

We were just quickly poking our heads in to check out Remedy Teas on the way back from the video store, so a full review is forthcoming later. We did walk away with a signature “Coco Chai” truffle which was fantastic. They also have a tea sampling bar at the front. The one tea I tried was very complex and savory.

It’s tucked away downstairs on the southwest corner of Republican and 15th, and is very easy to miss as you walk on by (this space has a laundry list of failed businesses in the past due to this issue). The front staff were very nice and sociable, and whether you are into tea or not I’d suggest stopping by and checking it out as Remedy Teas seems like a local business worth keeping around!

Remedy Teas
345 15th Ave E (at Republican)
Seattle, WA 98112
206-323-4TEA

Daily: 7:00AM-11:00PM

Agua Verde (Seattle, WA)

Rating:

There aren’t many places in Seattle where you can both rent a kayak and order top-notch tacos in the same breath. The only one I know if is Agua Verde on the north shore of the Montlake cut.

And this is not your average taco stand. Agua Verde boasts some very unique selections, including my two favorites:Camarones and Boniato tacos.

Their Camarones (shrimp) tacos are my new favorite. They are distinguished by the curry-like sauce atop the juicy local prawns.

Camarones!

The Boniato (sweet potato) tacos have stolen the hearts of many of my friends. They are a little variable in texture (I prefer when they are super mushy; occasionally the sweet potato bits are semi-firm), but the combination of sweet potatoes, cojita cheese, and their medium, slightly sweet salsa is certainly delicious.
Boniato!

The blackened halibut is also worth checking out, but avoid the cactus tacos. It’s a great place to take out of towners, though be sure to call ahead if you are going for dinner anywhere close to a weekend night. The waits can be quite extensive, though you can pass the time in the summer sipping margaritas outside πŸ™‚

TIP: The outdoor patio is not only for summer: there are overhead space heaters, making the porch even warmer than the indoor dining room.

TIP: If you’re not dead-set on eating in the dining room for dinner, the take-out line moves very quickly and you can have a nice summer picnic. Alternatively, the crowds are much thinner at lunchtime…

Agua Verde
1303 NE Boat St.
Seattle, WA 98105
206-545-8570

Mon-Sat: 11:00AM-9:00PM (Lunch and Dinner)

On the Wire with channel.Open()/Close()

I got a question the other day about what data goes on the wire when you Open(), Close(), or Abort() our various transport channels. Here are the details in a nutshell (all the comments about net.tcp apply to net.pipe, simply substitute “named pipe” for “socket”):

HTTP Request (Client) Channels

  • Open() — Nothing goes on the wire for HTTP Request channels, as there is no context that they need to establish. HTTP channels use Open() to setup their identity contexts and Token Providers (if necessary).
  • Abort() — Abort will immediately terminate any outstanding calls to channel.SendRequest(). This in turn aborts any underlying TCP sockets (by sending an RST packet).
  • Close() — Close will wait (up to the given timeout) for any outstanding calls to channel.SendRequest() to complete. If they don’t complete within the given timeout then we will abort the requests a la httpChannel.Abort().

HTTP Reply (Server) Channels

  • Open() — As a datagram channel, HTTP reply channels don’t perform any work at Open() time.
  • Abort()/Close() — If the associated HTTP Channel Listener has been disposed, then channel.Abort will in turn call HttpRequestContext.Abort() on any RequestContexts that have not been replied to. This will cause http.sys to abort the underlying TCP socket. If the HTTP Channel Listener has not been disposed then channel.Abort() simply transfers ownership of these outstanding request contexts back to the channel listener. Close() actually performs in the same fashion, since calling requestContext.Close() in this case would have the unexpected side-effect of sending a 202 Accepted response.

Net.Tcp Duplex (Buffered) Channels
Net.Tcp duplex channels have a 1-1 relationship with their associated network resource, and as such there is a more direct correlation between the channel operations and their effect on network traffic.

  • Open() — On the client, channel.Open() will first look for a socket in our connection pool (which reminds me I need to post about our connection pooling behavior). If none exists, then we will create a new client socket (by connecting to the service IP address+port number). Once we have a connected socket, we will perform a handshake using a custom .Net framing protocol. This is where we will validate that the requested endpoint both exists and uses the requested content-type. We will also perform any transport-security handshake here.

    On the server, channel.Open() signals that the server side channel should (if required) respond to any transport-security handshake, and then ACK that the message framing connection has been successfully established.

  • Abort() — Abort will immediately terminate the TCP socket associated with the channel (again by sending an RST packet).
  • Close() — Close will send a framing level “FIN”-style packet, and then wait (up to the given timeout) for a framing level “FIN-ACK”. If the FIN-ACK is received before the timeout expires then we will return the socket into our connection pool. If the receive times out then we will abort the socket.

Net.Tcp Request-Reply (Streamed) Channels
Net.Tcp streaming messages have similar wire handshake requirements, however those manifestations on the wire are associated with individual request-reply operations rather than to channel operations. For the channel operations, Net.Tcp request-reply channels behave in the same manner as HTTP channels.

I haven’t mentioned anything about net.msmq or UDP channels in this post. This is because as datagram channels they don’t have any on-the-wire associations with channel.Open/Close/Abort.