Certainly Not Politics As Usual

Today is the Midterm Elections here in the United States. If the pre-election day polls are to be believed, it looks like good news for the Democrats and bad news for the Republicans. The big question is whether the news is good/bad enough for Democrats to take control of one or both houses of Congress. I guess we’ll know by tonight.

But this post isn’t about the midterms. Don’t get me wrong, I hope the Democrats take back both houses of congress. But whoever ends up controlling Congress will have a thin majority at best, which will limit their ability to accomplish much. Frankly, the only area that I would expect to see much traction is on issues where moderate Republicans can reach across the aisle and vote with the Democrats in order to distance themselves from President Bush’s abysmal approval ratings.

I’m much more interested in the 2008 presidential campaign. For the first time in over 50 years, it will be a wide open race for both parties. Neither the sitting president nor the vice president will be running for president in 2008. The last time this happened was in 1952. President Harry Truman (D) dropped out of the race after losing the New Hampshire primary and Vice President Alben Barkley never had enough support to win the nomination. The Democratic nomination went to Illinois Governor Adlai Stevenson who lost to General Eisenhower in a landslide. Since then, the incumbent president or vice president has always been his party’s nominee for president.

Until now. Well, until two years from now at any rate. So while not completely unprecedented, this is the first time we’ve had a completely wide open race since the start of the Information Age. In other words, it’s the first time we’ve had a wide open race since the advent of cable TV, personal computers, 24 news networks, Rush Limbaugh, the Internet, weblogs, Wikipedia and YouTube. I’m sure some have already started calling this Politics 2.0. And while I’m tired of the “2.0″ moniker, certainly big changes is underway in the political arena.

So what happens when you combine the harsh sunlight of a decentralized and demassivied media with a wide open race with no clear favorite from either party? I’m guessing a very ugly race, especially from the Republicans. Both parties do negative ads, but they have become a “key strategy in the Republican political arsenal“. (The NRCC apparently spent “more than 90 percent of its $50 million-plus advertising budget” on negative ads this year.) I expect 2008 will be even worse. And not just the presidential race itself, but also the race for each party’s nomination. In some ways, the nomination race will be worse, since you expect politicians to have bad things to say about candidates from the opposing party.

If the next two years are filled with party infighting with every detail chronicled in the blogosphere and/or the mainstream media – and I fully expect that’s what will happen – we are in for a very ugly campaign ahead. Brace yourselves.

Slight Workflow Annoyance

One of the cool things about WF is that you can specify the GUID it uses to identify a workflow instance. WorkflowRuntime.CreateWorkflow has an overload (actually two) where you can specify said workflow instance identifier. This is awesome for using WF with Service Broker, as Service Broker already has the idea of a conversation group which is roughly analogous to a workflow instance. Conversation groups even use a GUID identifier, so there’s not even any mapping required to go from conversation group to workflow instance.

However, things get less cool when you call WorkflowRuntime.GetWorkflow. If you call GetWorkflow with a GUID that has no corresponding workflow instance, it throws an InvalidOperationException instead of just returning null. That seems like an odd choice. If you’re going to support specifying the instance identifier when you create the workflow instance, doesn’t it make sense that you should also gracefully support the scenario where an instance identifier is invalid?

I see two ways to deal with this:

  • Iterate through the list of loaded and persisted workflow instances looking for the one in question.
  • Call GetWorkflow and swallow the exception.

I ended up picking the “Swallow the Exception” approach as I can’t imagine the iteration thru every loaded and persisted instance would be very performant. But swallowing exceptions always makes me feel icky. I’m a fan of the “exceptions only for exceptional situations” approach and as far as I’m concerned, an invalid instance identifier isn’t that exceptional. Still, it’s a minor annoyance, especially given how cool it is to be able to specify the workflow instance identifier in the first place.

The Two Types of Service Architects

Tomas Restrepo comments on my recent SSB and WCF posts:

Harry Pierson asks how well WCF supports long running tasks. He suggests that WCF does not support them very well, and says that’s one reason he likes SQL Server Service Broker so much. I’d say SSSB is a good match only as long as the long running tasks you’re going to be executing are purely database driven and can be executed completely within the database. Sure, this is an “expanded universe” with the CLR support in SQL Server 2005, but even so it makes me nervous at times 😄

You could also consider using a custom service with MSMQ or something like BizTalk Server for this if you had long running processes that were not completely tied to the DB (or a single DB for that matter).

Sam Gentile follows up:

In that same post, but I needed to call it out separate, Tomas rightfully says, “I’d say SSSB is a good match only as long as the long running tasks you’re going to be executing are purely database driven and can be executed completely within the database,” in response to Harry liking Service Broker so much. Talk about a narrow edge case. That’s way I never really got excited or cared about Service Broker. Its a narrow solution to a special edge case when everything is database driven and can be executed totally inside the database. That’s the old Microsoft Data-Driven Architecture for sure. Me, I’d rather have a rich Domain-Driven architecture most of the time. Then if you have Oracle databases in your architecture too, where does it leave you? Nowhere.

As you might expect, I have a few comments,  clarifications and corrections.

First, Tomas’ statement that Service Broker only supports service logic “executed completely within the database” in flat out wrong. Service Broker can be used from any environment that can connect to SQL Server and execute DML statements. If you can call SELECT/INSERT/UPDATE/DELETE, then you can also call BEGIN DIALOG/SEND/RECEIVE/END CONVERSATION. This includes Windows apps and services, web apps and services, console apps and even Java apps. Of course, you can also access Service Broker from stored procedures if you wish, but you’re not limited to them as Tomas suggested.

Tomas’ misconception may come from a feature of Service Broker called Activation. Activation is a feature of Service Broker that dynamically scales message processing to match demand. For example, Service Broker can be configured to launch a new instance of a specified stored procedure if messaging processing isn’t keeping up with incoming message traffic on a given queue. This is called internal activation and because it uses stored procedures it does execute within the database as Thomas said. Service Broker also supports external activation where it notifies an external application when activation is needed. You do have to build an application to host your service logic and handle these notifications, but that application doesn’t execute within the database. So while you could argue that it’s easier to execute your service logic within the database (no need to build a separate host app), it’s not required.

Given that you don’t have host your service logic in the database, then you’re also not limited to “a single DB” as Tomas suggests. You don’t, in fact, have to put your Service Broker queues in the same database with your business data. So if you have Oracle in your environment, like the scenario Sam mentioned, you would host your service logic in an external application that processed messages from a queue in a SQL 2005 database while accessing and modifying business data from tables in the Oracle database. Using multiple databases does require using distributed instead of local transactions, but if you’re using MSMQ as Tomas recommended, you’re already stuck with the DTC anyway.

Finally, I didn’t get Tomas’ “purely database driven” or Sam’s “everything is database driven” comments at all. While there are exceptions, the vast majority of systems I’ve ever seen/built/designed have essentially been one or more stateless tiers sitting in front of a stateful database. If it’s a traditional three tier web app, there’s a stateless presentation tier, a stateless business logic tier and a stateless data access logic tier. For a web service, there’s no presentation tier, but there’s is the stateless SOAP processing tier typically provided by the web service stack. Does this mean the vast majority of web apps and services are  “purely database driven” too? If so, then I guess it’s a good thing, right?

In the end, maybe there are two types of service architects – those that believe the majority of services will be atomic and those that believe the majority of services will be long running. For atomic services, Service Broker is overkill. But if it turns out that most services are long running, WCF’s lack of support is going to be a pretty big roadblock.

I’m obviously in the long running camp. I’m not sure, but I get the feeling this is the less popular camp, at least for now. We’ll have to wait to see, but I do know is that whenever someone brings me what they think is an atomic business scenario, it doesn’t take much digging to reveal that the atomic scenario is actually a single step of a long running business scenario that also needs to be automated.

Here’s a question for Tomas, Sam and the rest of you: Which group do you self select into? Are most services going to be atomic or long running in the (pardon the pun) long run?

Essential Windows Workflow Foundation

On Don’s recommendation, I picked up Essential WF. In the forward, Don writes “[S]omething big is about to happen.” I’m only part way thru chapter one, and this is already a must read. Go get it. Now.

In the preface, they define the term “Reactive Program”, which I’m adding to my personal lexicon.

“Windows Workflow Foundation (WF) is a general-purpose programming framework for creating reactive programs that act in response to stimulus from external entities. The basic characteristic of reactive programs is that they pause during their execution, for unknown amounts of time, awaiting input.”

That “unknown amounts of time” is the kicker. Here’s a paragraph from early in chapter one that expands on that:

“Real-world processes take a long time – days, weeks, or even months. 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.”

Gee, that sounds familiar doesn’t it?

Is WCF “Straightforward” for Long Running Tasks?

My father sent me a link to this article on SOA scalability. He thought it was pretty good until he got to this paragraph:

Long-running tasks become more complex. You cannot assume that your client can maintain a consistent connection to your web service throughout the life of a task that takes 15 minutes, much less one hour or two days. In this case, you need to implement a solution that follows a full-duplex pattern (where your client is also a service and gets notified when the task is completed) or a polling scheme (where your client checks back later to get the results). Both of these solutions require stateful services. This full-duplex pattern becomes straightforward to implement using the Windows Communications Foundation (Indigo) included with .NET 3.0.

When I first saw duplex channels in WCF, I figured you can use them for long running tasks also. Turns out that of the nine standard WCF bindings, only four support duplex contracts. Of those four, one is designed for peer-to-peer scenarios and one uses named pipes so it doesn’t work across the network, so they’re obviously not usable in the article’s scenario. NetTcp can only provide duplex contracts within the scope of a consistent connection, which the author has already ruled out as a solution. That leaves wsDualHttp, which is implemented much as the author describes, where both client and the service are listening on the network for messages. There’s even a standard binding element – Composite Duplex – which ties two one-way messaging channels into a duplex channel.

Alas, the wsDualHttp solution has a few flaws that render it – in my opinion at least – unusable for exactly these sorts of long running scenarios. On the client side, while you can specify the ClientBaseAddress, you can’t specify the entire ListenUri. Instead, wsDualHttp generates a random guid and tacks it on the end of your ClientBaseAddress, effectively creating a random url every time you run the client app. So if you shut down and restart your client app, you’re now listening on a different url than the one the service is going to send messages to and the connection is broken. Oops.

The issues don’t end there. On the service side of a duplex contract, you get an object you can use to call back to the client via OperationContext.Current.GetCallbackChannel. This works fine, as long as you don’t have to shut down your service. There’s no way to persist the callback channel information to disk and later recreate it. So if you shut down and restart your service, there’s no way to reconnect with the client, even if they haven’t changed the url they’re listening on. Oops.

So in other words, WCF can do long running services using the wsDualHttp binding, as long as you don’t restart the client or service during the conversation. Because that would never ever happen, right?

This is part of the reason why I’m sold on Service Broker. From where I sit, it looks like WCF can’t handle long running operations at all – at least, not with any of the built in transports and bindings. You may be able to build something custom that would work for long running services, I’m not a deep enough expert on WCF to know. From reading what Nicholas Allen has to say about CompositeDuplex, I’m fairly sure you could work around the client url issue if you built a custom binding element to set the ListenUriBaseAddress. But I have no idea how to deal with the service callback channel issue. It doesn’t appear that the* *necessary plumbing is there at all to persist and rehydrate the callback channel. If you can’t do that, I don’t see how you can reliably support long running services.