- Architect MVP business news keeps on coming. Today it’s Corillian – the company Scott Hansleman works for – getting acquired by CheckFree.
- Los Angeles is looking to provide city-wide low-cost (maybe free) wireless access. My father has often suggested that Internet access be treated like other utilities like water and power. Sounds like LA is heading down that path. I wonder if they’re looking at WiMAX?
- The .NET Micro Framework – which powers the SPOT watch – now has an SDK. For those keeping track, that makes three embedded solution platforms from Microsoft, the Micro FX, Windows CE (which also just shipped a new version) and Windows XP Embedded. (via Larkware)
- BEA’s Bruce Graham talks somewhat obtusely on a topic I am particularly passionate about: putting more power in business people’s hands to build their own systems. (via Joe McKendrick)
- Register for the Windows Home Server beta. Also check out the forums, team blog and SuperSite Preview. Looks pretty sweet (via Scott Hansleman)
- The final version of Live Search for Mobile was released a few days ago. This program rocks. I’m using the Windows Mobile version, but there’s also J2ME version as well. (via Dare Obasanjo)
- Any lingering interest I had in Ruby vanished yesterday as got to chapter 8 of Windows Powershell in Action. Chapter 8 is called “ScriptBlocks and Objects” and it is specifically about meta-programming. After reading that chapter, PS seems more flexible in this space than Ruby, which is the current industry darling for metaprogramming. For example, in Ruby you can optionally pass a block of code to any method. In PS, you can define a ScriptBlock like any other parameter. That means you can tell from the method signature that the ScriptBlock is used. Or you can define a function that takes multiple ScriptBlock parameters. Much more thought on this is needed.
Morning Coffee 31
DevHawk.ColorConsoleTraceListener
As mentioned this morning, I factored the ColorConsoleTraceListener code into a seperate assembly and added config support. It’s pretty simple, but I find it useful. Let me know if you do too.
Morning Coffee 15
- I was checking out the ASP.NET community site, and I noticed a small “Microsoft Communities” toolbar across the top. There’s a little menu that links to other MS community sites like Channel 9 and MSDN Blogs. I’m surprised the NetFx3 community site isn’t included.
- My teammate Dale is blogging about Proper SOA. He lays out 6 Proper SOA principles, and then drills into the first three: meets business needs, requires governance and responds to changing business drivers. I expect to see posts on the remaining principles this week. Maybe Dale should turn this series into an article.
- Speaking of articles about architecture, Architecture Journal 10 is online as a PDF. This issue’s topic is Composite Applications.
- Malbolge
is a programming lanugage that is “specifically designed to be
difficult to program in.” Here’s Hello
World in Malbolge:
(=<`$9]7<5YXz7wT.3,+O/o'K%$H"'~D|#z@b=`{^Lx8%$Xmrkpohm-kNi;gsedcba`_^][ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543s+O<olm
Seriously. Actually, it’s worse than it looks. The effect of any instruction depends on where it is located in memory. Malbolge is so difficult, it took a month to write a Lisp program to generate that program. However, Lou Scheffer thinks we should think about Malbolge as a cryptosystem. I wonder if it could be used for obfuscation? (via Good Math, Bad Math) - Nat Torkington blogs about teaching kids to program. He makes the point about “them to think in terms of small steps”. I was lucky to have a computer teacher in elementary school who did something similar. She had us write down instructions for making a peanut butter and jelly sandwich and she then followed them to the letter. For example, if you wrote, “spread peanut butter on the bread” with out first instructing her to take out a slice, she’d happily spread peanut butter on the entire loaf. (via reddit)
- To this day, my wife thinks the peanut butter and jelly lesson negatively affected my ability to communicate with “normal” people. She’ll even say “peanut butter and jelly” when she thinks I’m being particularly obtuse in my communication.
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.
More Stuff I Didn’t Know About WF
All communication from the host to the workflows goes thru the WorkflowQueuingService. Unlike other WF services, the queuing service is not replaceable. Communication from a workflow activity instance to the host goes thru some other service. There is no “default” activity -> host communication service, though WF ships with the ExternalDataExchangeService. You have to manually add the ExternalDataExchangeService to your workflow runtime instance. WF also includes the wca.exe utility which generates strongly typed HandleExternalEvent and CallExternalMethod activities for your workflow. And according to Jon, the External Data Exchange system was added specifically for SharePoint.
The built-in sequential and state machine workflows are customizable. So if you wanted to have a custom designer or validation experience for an otherwise standard sequential or state machine workflow, you can inherit from the standard workflow type and add the custom validation and / or designer support. For example, as I wrote earlier, you can load a workflow from XAML. XAML workflows can’t support the Code Activity. So if you wanted to use the standard sequence designer but disallow the use of the Code Activity, you wouldn’t have to rewrite the sequence activity from scratch.
You can execute workflows across a farm, similar to how you build a web farm. Workflows that get persisted to the persistence service can be loaded on any node in the farm. Of course, like web servers in a farm, you’d have to have the same bits installed on all the machines in the workflow farm. Sounds like an opportunity for something like Application Center for WF.
The built in SQL Persistence Service is a toy. When you start your workflow engine, the SQL Persistence Service will auto-load all the existing persisted workflows into memory, as an “optimization”. So if you have thousands of order workflows persisted in your database and you decide to bring another workflow processing node online, that new workflow processing node will happily load ALL of the outstanding orders that it can find in the database. This service should have been included as a sample like the file based persistence service sample rather than described as “a fully functional persistence service” in the docs.
WF Web Service integration is also a toy. WF leverages basic ASMX for all it’s web service integration, so your only choice for web services – consuming or exposing – is atomic request/response style services. You can have a workflow with multiple operations, but the default ASMX hosting infrastructure squirrels the WF Instance ID in the ASP.NET session, which will time out in twenty minutes (by default). Furthermore, the built in ASMX workflow host doesn’t provide an option to specify the web service namespace, so it ends up with the default http://tempuri.org namespace. Again, like the SQL Persistence, this should have been included as a sample, not included in the standard activities.
Activities can generate code. In the previous item, I mentioned there’s basic ASMX hosting integration for a workflows. Turns out the WebService Activities generate that hosting code as part of the workflow compilation process. So in other words, if you add a WebService activity to your workflow, the activity will inject the custom ASMX hosting code into your compiled workflow. In this WebService activity case, the injected code isn’t very good, but the fact you can do this at all is very cool.