How I Learned to Stop Worrying and Love WCF

Regular readers of DevHawk are likely aware of my obsession interest in SQL Service Broker (aka SSB). I’ve also been doing a lot of WCF work lately. While there are parts of WCF that I think rock, overall I’ve found WCF lacking due to it’s lack of support for long running services, which SSB excels at.

So it was with great interest that I read this recent article on Integrating WF and WCF. WF is expressly designed for long running systems, so I wanted to see how the article dealt with the WCF’s lack of support for such scenarios. Unfortunately, the article basically sidesteps the issue. While it has lots of great info about hosting WF inside a WCF service, the article uses duplex channels for communication between the service and its clients. As I have pointed out before, this approach is impractical because it requires that both the service and its consumer remain alive in memory until the WF end.

Remember this quote from Essential WF?

“It is wishful thinking to assume that the operating system process (or CLR application domain) in which the program begins execution will survive for the required duration.”

So basically this WCF/WF sample is wishful thinking. Fine for a demo, but given the severe lack of information out there on integrating these two technologies, I’m worried that many people will read this article as best practice guidance, which in my opinion would be a mistake.

But instead of firing up my blog (that is, like last time) to write a scathing post about how broken this sample is, I emailed Paul which led to a concall with Shy to discuss WCF’s lack of support for long running services. Imagine my surprise when Shy agreed with me completely, furthermore saying that support for long running services had been “out of scope” for v1 of WCF. I thought that the whole point of duplex channels was for long running services. But apparently I was wrong.

Shy said to think of the duplex channel in terms of sockets, rather than long running conversations. And just like that, WCF made a ton more sense to me. I had been directly comparing the SSB and WCF communication models, but that’s apples and oranges. It would be like comparing SSB to TCP.

If you think about it, vanilla HTTP works a lot more like UDP, even though it’s layered on top of TCP. Both UDP and HTTP support connectionless operations and neither UDP nor HTTP are reliable or provide message ordering. The comparison isn’t perfect: for example, UDP isn’t limited to a single response for an incoming request. But by and large, HTTP is a very UDP style protocol.

If HTTP is basically UDP, then WS-* is trying to be TCP. Frankly, I never understood the point of WS-ReliableMessaging. I always thought reliability == durability == SSB or MSMQ. But when you realize that HTTP lacks TCP-like reliability and ordering capabilities, suddenly this WS spec makes sense. In fact, Shy made this exact point almost a year ago. At the time, I didn’t get it because I didn’t understand the duplex channel as sockets analogy. Now, I see the value of adding these capabilities to HTTP.

What Shy said was clear and to the point but unfortunately completely missing in the official WCF documentation. For example, the docs on Duplex Services say this:

A duplex service contract is a message exchange pattern in which both endpoints can send messages to the other independently. A duplex service, therefore, can send messages back to the client endpoint, providing event-like behavior. Duplex communication occurs when a client connects to a service and provides the service with a channel on which the service can send messages back to the client.

The docs make no mention that the “event-like behavior” of duplex services only works within a session. And I’m not the only one who mistakenly believed that duplex services could be used for long running services (here’s an article in DDJ that makes the same mistake). Shy used the term “episodic” to describe services that span session boundaries. I’d like to see the docs updated to include that concept.

Taking the TCP/UDP analogy even further, I think it demonstrates how pointless the REST vs. SOAP debate is. As UDP is a thin layer on top of IP, REST is a thin layer on top of HTTP. But nobody argues much about UDP vs. TCP these days. I was in grade school when UDP and TCP were standardized, so maybe there were big TCP vs UDP flame wars at the time. But twenty five years later, it’s pretty clear that TCP vs UDP is not an either-or proposition. Some protocols are better built on UDP while others are better built on TCP. I’m guessing we’ll see a similar evolution with SOAP and REST.

Personally, I would expect that message exchanges between services will become more complex over time. Complex message exchanges would seem to favor stateful SOAP over stateless REST for the same reason complex network protocols favor connection-oriented TCP over connectionless UDP. But SOAP could never displace REST any more than TCP could ever displace UDP. Furthermore, as Larry O’Brien recently wrote “the onus is on the WS-* advocates to prove the need”. TCP standardization only lagged a year behind UDP standardization where WS-* has lagged at least six years behind REST. I wonder if UDP would be more prevalent today if it had gotten a six year head start on TCP.

Finally, this “SOAP as Sockets” flash of understanding has also helped me understand how SSB / WCF can evolve together in the future. Some folks have suggested an SSB transport for WCF and I’ve personally looked into such an approach. But given since SSB is at a higher level of abstraction than WCF, it makes much more sense to layer SSB on top of WCF instead of the other way around. Today, SSB uses two protocol layers: the top level Dialog Protocol, which is built on top of the lower-level Adjacent Broker Protocol (ABP), which in turn is built on TCP. I’d like to see a version of ABP that was built on top of WCF instead of directly on top of TCP. SSB’s Dialog Protocol would tie together the WCF duplex sessions into a long-running conversation the same way that it ties together TCP sessions today.

Eventually, I would love to see something that has the programming semantics of SSB and the interoperability of WCF. That would be like the the Reese’s Peanut Butter Cup of service messaging.

Morning Coffee 25

  • I’m surprised we haven’t seen a laptop with a flash memory hard drive yet. Given the significant power, heat and performance advantage of flash memory over hard drives, I would have expected the laptop companies to have high-end laptops with flash memory hard drives by now. I’m probably getting a new laptop in the next six months, but I’d hold out until the end of the year if it meant being able to get one with a flash memory hard drive.
  • I wrote last month that “The next new language I learn will be F#“. I was wrong. It’s PowerShell.
  • I’ve been listening to Scott gush about CodeRush for years now. His post yesterday about the new free version of Refactor! for ASP.NET finally kicked me into action. I installed the CodeRush trial and will be commence bugging my boss to buy it.
  • Looks like big news brewing in the online identity space.
  • Dale is talking about service heartbeats. I’m pretty stoked that Dale is now spending 100% of his work time (when he’s not blogging about sports, politics or video games anyway) with me building service oriented infrastructure for MSIT.

Hawkeye on Web Service Software Factory

As I wrote the other day, I’ve been investigating the Web Service Software Factory. The WSSF includes four guidance packages: Data Access, ASMX, WCF and WCF Security. The Data Access isn’t service specific (I’m guessing it’s also included in p&p’s other factories) so I didn’t focus on it much. I also didn’t investigate the ASMX package at all.

For the WCF and WCF Security packages, I walked through the tutorial in the documentation. The tutorial contains the usual WCF suspects such as creating a data contract, creating a service contract and implementing a service contract. While you can do these things manually, the WSSF provides wizards for most if not all these operations. This seems like overkill for some of these operations. For example, filling out the grid of data contract members was more cumbersome (for me) then just typing the values in the code file.

Also on the subject of somewhat more complex than necessary, WSSF provides wizards for building type translators. This is pretty standard stuff: given an instance of a given type, the translator returns an instance of a different type. Again, I find it faster to write the code for this directly than to individually select the matching fields in the wizard UI. Somewhere on the complexity scale between CRUD stored procedures and service data contracts is the tipping point where it’s faster and easier to just write the code than it is to manipulate the wizard UI which generates the code.

On the plus side, the WSSF includes snippets which are very convenient to use. For example, WSSF includes the WCFDataMember snippet (short name: wcfDM). It’s a lot like the standard prop snippet, but with the automatic addition of the DataMember attribute.

I had much more success with the main WCF package than I did with the WCF Security package. I wasn’t interested in the anonymous or direct authentication mechanisms, which left only two security recipes that I cared about: kerberos and x.509 certificates. Unfortunately, I couldn’t make either of these tutorials work. For kerberos, the baseline configuration works (i.e. standard wsHttpBinding with no additional configuration), but after running the “Secure a Service Using Kerberos” recipe, I get an exception that “The token provider cannot get tokens for target”. It wasn’t in me to debug the sample to figure out what that meant. For x.509 certificates, I can’t even complete the wizard – I click OK in the certificate selection dialog, but the wizard doesn’t get updated and won’t let me continue.

I really dig the new Guidance Navigator window, especially the history window, but I do have one problem with it. Is there a way to mark a recipe so it doesn’t show up in the history view? The WSSF includes some recipes like “View Service in Browser” and “Run Client” that don’t change the project state and quickly clutter up the history view. It would be great if they didn’t show up there in the first place.

I’m guessing the WSSF is designed primarily new WCF developers, so I’m not exactly in the target demographic. Many of my issues above stem from my deeper than average experience with it (though nowhere near the depth of experience some members of the community have already). But it’s a good start and I’m sure it will get better with successive releases.

Morning Coffee 19

  • I find Jim Kobielus’ “SOA as 50 square miles of fungus” analogy funny and strangely compelling. The “keep in the dark and feed it shit” jokes practically write themselves. (via Joe McKendrick)
  • Politics 2.0 Rising: The number of Americans who got “most of their information” about the 2006 midterm elections was double the number from the 2002 elections.
  • Do you use external/flash drives? Do you have issues when you try to “Safely Remove Hardware” with said drive? I do, all the time. Apparently, unlocker is the answer. (via Paul Andrew)
  • How come there’s no information about LogToTraceListeners in the WF documentation? As far as I can tell, it’s not in the Windows SDK docs at all and the only reference to it on MSDN is this year-old article and this year-old blog post. I only discovered because someone on the internal WF discussion alias asked about it. I’ve added In my SSB/WF work, I subclassed the built-in SQL persistence service in order to add tracing support. If you’re developing a WF host, you need to turn this on. I find it mind-boggling this isn’t included anywhere in the official WF docs.
  • Nice to see Soma bragging about Software Factories. As he writes, our current solution – consisting of the Guidance Automation Toolkit and the DSL Tools - are really just a first step. I’m just starting to experiment with the Web Service Software Factory (WSSF). Aaron Skonnard introduces both the ASMX and WCF version in his two most recent Service Station articles.
  • Michael.NET makes Programming Promises and Ted Neward swears the Oath of the Conscientious Programmer. Why stop there? How about the Architect’s Affidavit to actually implement the shit we draw on the white board? The Technologist’s Testimony of understanding and belief in all things geeky and gadget? Come on, isn’t this just called “doing your job”? Do we really need to make promises and swear oaths to take it seriously and do it to the best of our abilities?

Morning Coffee 18

  • I’m sure glad Heroes is back. And so far, I’m liking this season of 24 better than the last couple. I especially like how they’re introducing Jack’s family to the storyline – very cool.
  • Bill Gates will be onThe Daily Show with Jon Stewart next Monday. I rarely miss an episode (though I typically watch it a day or two later via my DVR) so I’m looking forward to this.
  • Roger Sessions latest ObjectWatch newsletter is available. Roger does his usual brand of relating architectural concepts to everyday situations (this time, planning his daughter’s wedding). This one was funnier than most – especially since I have a 1 year old daughter – though I’m still waiting for one of these that doesn’t contain the words “doppio machiato”. If you’re reading this Roger, don’t worry, I am enjoying every moment.
  • Apparently, I am the keeper of obscure development knowledge on my team. My teammate Buzz was getting an error in shdocvw.dll when trying to open an XSD with the BizTalk editor. He’s on an interim build of BTS06 R2, so bugs are to be expected, but he wasn’t sure what shdocvw was, so he asked me. In case you’re curious, shdocvw is the WebBrowser control.
  • Did I mention that I left my laptop power cord at the office again on Tuesday? That’s three times in four the last five trips to my office (not counting weekends, sick days and training). My boss actually got a spare from his boss that I can leave at the house 24/7.