VS2005 Hanging on XML Comments

Link. August 1, 2007. Comments [3]. Posted in: .NET

 While working on my PipelineTesting library code, I'm running into a pretty annoying problem: Visual Studio will hang (with 100% processor usage) every time I try to type a '<' inside a <![CDATA[]]> section in an XML comment (specifically inside the <example/> tag).

Has anyone else seen this before? This is VS2005 with SP1, btw, running on Windows Server 2003.

Regions and Readability

Link. July 30, 2007. Comments [2]. Posted in: .NET | Tools

David Laribee wrote a few days ago about why he dislikes the #region construct in code. Interesting comments, and made me reflect a bit on how I use regions myself. In general, I don't agree with David that using regions is evil per-se. but I do agree they are often overused. In particular, I find the practice of forcing a specific set of regions on each and every code base to be a significant hindrance to readability.

The truth is that small classes don't usually need regions at all. However, I still find them very convenient for classes with a lot of members, even if they are short 1 or 2 liners. What I noticed, however, is that I don't have a hard and fast rule about how I apply regions. Instead I sort of vary my use of them according to the needs of the code I'm working on.

Here are some of the things I keep in mind when applying regions:

Lots of properties

If a class has a lot of properties (common, for example, in some business entities or DTOs), then I do like to wrap properties in it's own region. This is because a lot of cases properties are created once, but not so often modified after wards, and the other thing is that property declarations in C# do take up a lot of space because of the syntax used.

Automatic properties in C# will be nice, but from a syntax perspective, they don't really help as much as one would like. It was unfortunate the C# team decided to go for that syntax instead of the really nice one used by C++/CLI...

Multiple Interfaces Implemented

If a class implements multiple interfaces, each one having more than a couple of methods, I do tend to wrap each one into its own region. If it's only a single interface, or something simple like IDisposable, I don't bother with it.

Lots of Related Methods

Sometimes you have to implement a lot of simple, related methods in a class. We all wish classes had few members and were small and simple, but sometimes you have to do otherwise (this is usually forced when complying with an externally defined interface).

For example, in a lot of cases I've had to deal with there are a lot of simple GetXXX() accessor methods that need to be implemented (e.g. GetInt16(), GetInt32() and so on). Each one usually won't have more than 1 or 2 lines of code in it, but when put together, they take a sizable chunk of space, and if there are other, more significant methods in the class, I like to get the accessors out of the way so I can concentrate on the rest (the important stuff). Regions help out nicely in this case.

Related Test Methods

A case similar to the above one happens in Unit Testing classes: Sometimes you have several test methods that are closely related to one another, so I like to group them together. Here are a couple of examples:

  • I once worked in a code base that, although fairly simple, had tons of methods in a single class: a combination of type-specific Read/Write methods. For each type, I usually had to write four or five test methods to test all possible corner cases, so that meant a hole lot of methods involved. I grouped test methods by type (i.e. "Int32 tests") inside the fixture.
  • I'm currently working on an ADO.NET provider, and writing/testing my IDataReader implementation. The IDataReader class has tons of methods (of the accessor variety mentioned before), which, means lots of test methods in my test fixture. Again I use regions to group certain related tests methods together to make it easier to read and maintain.

There might be a couple of more cases I base my regions on, but I think these cover the basics. I think, in general, these rules give me a set of regions that are far more useful and that really make the code easier to read and maintain than the rigid Using/Fields/Properties/Public Methods/Private Methods stuff a lot of people use; but that's just my opinion :-).

Coincidentally, like David, I use search a lot to go around (though in my case I use '/' for searching and not Ctrl-I), and the other thing I've found is that tend to very rarely use the class/member code navigation drop downs in the Visual Studio Editor. I do use them sometimes, but usually when I'm just getting into a foreign code base I'm not familiar with.

PipelineTesting: Improvements and Standard Components

Link. July 28, 2007. Comments [0]. Posted in: BizTalk

I've been tweaking the PipelineTesting API further as I use it and write the unit tests for it. Here are some of the improvements I've made on the pipeline creation syntax:

  1. The NewReceive()/NewSend() methods were renamed to just Receive() and Send(), across all creation functions. This leads to a slightly shorter and more readable (imho) syntax.
  2. The End() method in the builder classes is now optional; as they now provide an implicit conversion operator to ReceivePipelineWrapper and SendPipelineWrapper respectively. I think this is one change that was really needed to make the syntax more palatable, and means you can now do this:
ReceivePipelineWrapper pipeline = Pipelines.Receive()
   .AddValidator(new XmlValidator());

I think this looks much better.

Creating standard components

One of the problems with the current PipelineTesting version is that while it allows you to use one of the standard assembler/disassembler components on an empty pipeline, it provides no help doing so. Using them can be pretty annoying because there's no easy way to add document and envelope schemas.

The cause for this is that the relevant properties in the standard Xml/FF assembler and disassembler components use types defined in Microsoft.BizTalk.Component.Utilities.dll. The types themselves are public (and even somewhat documented), but the assembly can only be found in the GAC, which means referencing it in tests projects is a pain in the neck.

To save yourself the trouble from having to do this, the new PipelineTesting API will also expose classes to make it easier to create and configure the standard XML and Flat File assembler and disassembler components. Here's an example of the syntax I'm implementing:

XmlAssembler asm = Assembler.Xml()
   .WithDocumentSpec<Schema1_NPP>()
   .WithEnvelopeSpec<SimpleEnv>()
   .WithPreserveBom(true);
SendPipelineWrapper pipeline = Pipelines.Send()
   .AddAssembler(asm);
//   ...

PipelineTesting: Pre-built Pipelines and Messages

Link. July 25, 2007. Comments [0]. Posted in: BizTalk

Here are some more syntax examples for the new library version:

3. Using pre-built pipelines:

If you have existing, already compiled, BizTalk pipelines, I currently have two options for using them:

ReceivePipelineWrapper pipeline = Pipelines.NewReceive(typeof(MyPipeline));

Or:

ReceivePipelineWrapper pipeline = Pipelines.NewReceive<MyPipeline>();

4. Adding Document Specifications:

It's also important to add any necessary document specifications (schemas) to the pipeline before executing it so that disassembler and assembler components can find them. This is now possible as well during construction:

SendPipelineWrapper pipeline = Pipelines.NewReceive()
   .AddAssembler(new XmlAsmComp())
   .WithSpec<MySchemaType>()
   .End();

One thing I'm not quite sure about here is with the standard XML pipelines and prebuilt pipelines. For them, the current factory methods in the Pipelines class don't return a builder object (like the one returned by the empty NewReceive() and NewSend() methods I introduced last time), so if you want to add known document specifications to those, you still need to use the old AddDocSpec() method in the ReceivePipelineWrapper and SendPipelineWrapper classes. It's not much more complexity, but the asymmetry makes me dislike it a bit.

So I'll probably be changing the code so that all pipeline creation methods return builder objects and not the actual pipeline objects. Any objections?

5. Executing Send Pipelines:

One annoying part of the current API is that when executing Send pipelines you need to explicitly create a MessageCollection instance, add your input messages to it and then call Execute() with it. Not too bad, but inconvenient if you only have one or two messages (which is most of the time).

I thought about several possible syntaxes to simplify this, but in the end decided to do the simplest fix: I added a new overload to SendPipelineWrapper.Execute() that has a params array of IBaseMessage instances. So you can now do this:

IBaseMessage output = pipeline.Execute(message1, message2);

Simple, but effective!

Codekana

Link. July 24, 2007. Comments [0]. Posted in: Tools

I just noticed that Jon, the guy behind ViEmu, is talking a bit about an upcoming product: CodeKana. I haven't downloaded or installed it yet, but it looks like it might be a useful tool for Visual Studio. That said, certainly at least part of what it does is already done by CodeRush.

Update: Looks like v1.0 was released.

PipelineTesting: Creating Pipelines

Link. July 24, 2007. Comments [0]. Posted in: BizTalk

Here are some options I'm exploring for creating pipelines for testing.

1. Using default pipelines

To use standard pipelines right now you need to reference Microsoft.BizTalk.DefaultPipelines and do something like this:

using Microsoft.BizTalk.DefaultPipelines;
// ...
ReceivePipelineWrapper receivePipeline =
   PipelineFactory.CreateReceivePipeline(typeof(XMLReceive));

Not hard, but a bit inconvenient. Instead, I'm thinking of:

ReceivePipelineWrapper pipeline = Pipelines.Xml.NewReceive();

2. Creating a pipeline from scratch

To create a pipeline from scratch in the current code you need create an empty pipeline and add each component at the proper stage. Unfortunately, the API here is pretty generic, and thus very verbose. Here's what I'm thinking of:

SendPipelineWrapper pipeline = Pipelines.NewSend()
   .AddAssembler(new XmlAsmComp())
   .AddEncder(new MIME_SMIME_Encoder())
   .End();

I'm also thinking about doing something to make it easier to use built-in assembler/disassembler components with specific schemas, as this is pretty hard to do with the current version without using a pre-compiled pipeline (because of how the properties in the components are defined).

A Better Interface for PipelineTesting

Link. July 24, 2007. Comments [0]. Posted in: BizTalk

Last year I wrote the initial version of my PipelineTesting library, a wrapper library that makes it possible to automate testing of BizTalk Server 2006 pipelines and pipeline components. Since then, I've used the library successfully on several projects and I'm extremely happy I spent the time creating it, as it has made my life a lot easier when working with Pipelines.

However, the original API for the library was not the best. While not hard to use, it was not completely intuitive and it was very verbose, for no good reason except that it resembled (partially) the original API in the PipelineObjects library from Microsoft.

Finally this bothered enough that I decided to do something about it and improve the API with something better. My goals are:

  • Keep the original API compatible. In other words, you should still be able to use the original API if you so want (if only to keep compatibility for existing users).
  • Make it less verbose, but more readable.
  • Fix pain points in the current API.

The current API works, but it is somewhat painful in the following aspects:

  • Creating pipelines from scratch and using default pipelines
  • Executing Send pipelines (since you need to create collections even if you're only going to use one input message)
  • Manipulating messages

I'll be exploring some options to fix these issues in following posts, and I'd sure appreciate any feedback!

Vista: Strike Two

Link. July 22, 2007. Comments [4]. Posted in: Vista

There are things that I dislike about Windows Vista, but also quite a few things that I like. Unfortunately, for the past couple of months I've been having what I consider a "deal-breaker" problem with Vista on my main Dell Latitude D820 laptop.

A few weeks ago, it started happening: I'd be working normally on vista doing the normal stuff: Outlook, maybe word or excel, firefox, maybe a virtual machine opened (usually in a paused state). I'd try to do something simple, like, say, scan a document using Windows Fax and Scan when, suddenly, the machine would become unresponsive and start hitting the hard drive very hard (like really heavy paging going on, though I have 2GB of memory). When this happens, the entire machine simply stopped responding: No cursor movement, no Alt-Tab, no Task Manager; heck, not even the clock on the taskbar would get updated!

Usually, this would happen around once a week and last between 5 and 20 minutes, after which the machine would start going back to normal and become responsive again. Pretty bad, but I could live with it.

After it happened a few times, I started looking at what could be causing the issue; but it was very hard to do since there was no way I could monitor what was going on when the problem hit (since it was unresponsive, no way to investigate). However, the last couple of times it happened I was able to see that the Windows Search processes would be active and using quite a bit of processor and IO when the problem was winding down and I was able to use the machine again.

So about two weeks ago, I disabled all WIndows Search related services (at least I think I got them all). Windows Search never worked well for me (i.e. even with indexing, searches still seem to return partial results and take a long time to complete), so it's not like I was going to miss it much. After this, the problem seemed to go away, and I was pretty happy...

.... until today. It happened again, only this time my machine was completely bogged down by all the disk activity for AN ENTIRE HOUR, and it still wouldn't stop. I had to resort to yanking the power off the machine and reboot, something I really didn't want to do as I had several things opened when it happened.

Getting locked out of my machine for 20 minutes every once in a while is one things, but I can't really justify keeping Vista on my machine if I'm going to loose an entire fucking hour with this shit going on and no idea what's causing it. So if this happens again, it's strike three and I'll just have to go back to XP. This is a deal-breaker.

If anyone has any ideas as to what might be causing the issue; sure would appreciate them...

Garden of Eden - A VS2005 Color Scheme

Link. July 21, 2007. Comments [1]. Posted in: Tools | VS Color Scheme

Here's another Visual Studio 2005 color scheme: Garden of Eden.

Code:

GardenOfEden Code

Xml:

GardenOfEden Xml

This one is based around greenish (teal) colors, and though funky, it is quite usable. Enjoy!

Download Consolas_GardenOfEden.zip

Update: Download the Visual Studio 2008 version here.

Microsoft.BizTalk.Operations

Link. July 19, 2007. Comments [0]. Posted in: .NET | BizTalk

BizTalk Server 2006 comes with a library called Microsoft.BizTalk.Operations that allows you to do common operational queries on the BizTalk message boxes and tracking databases. The concept is very cool and it is something very needed for a product like BizTalk; particularly since the WMI-based API wasn't fully updated in 2006 to reflect model changes.

Unfortunately, while the Operations assembly might seem very nifty at first, the reality is far less interesting: Like many other cases, Microsoft decided here to "play it safe" and only expose a tiny fraction of the library's functionality.

BTSQuery

One of my favorite features in BizTalk Server 2006 is the Group Query page in the Administration Console (it rocks!). Thought you could do the same queries with Microsoft.BizTalk.Operations? I did to. Well, no, you can't. The BizTalkOperations class, unfortunately, only exposes basic enumeration capabilities.

That means you can use M.B.O. to get a list of, say, all Service Instances, but after that, you're on your own filtering them (and good luck if you've got a few thousand instances hanging around). You wanted a list of subscriptions? Nope, you can't; you can only get subscriptions associated with a specific service instance.

All the functionality necessary to create and execute your own custom queries like those in the Administration Console is indeed in M.B.O. and used by MicrosoftMicrosoft.BizTalk.Administration.SnapIn, but it is internal :-(. Why, oh, why?

On a related note, whoever came up with [InternalsVisibleTo] is starting to seriously piss me off. The idea was good, but too many people running around using it for evil purposes

Screwing with VS for Fun and Profit

Link. July 19, 2007. Comments [0]. Posted in: .NET | Tools

Just a little something I was fooling with tonight:

VsPackageMgr

Workflow Types and Prototypes

Link. July 17, 2007. Comments [0]. Posted in: Workflow

Windows Workflow Foundation creates workflow instances either from CLR Types describing the workflow, or from an XmlReader that provides the Workflow description in XAML. In either case, I've always viewed the entire workflow definition + creation as a variation of the prototype pattern. It's a loose interpretation, of course, but it rhymes with the idea that either the CLR type of the XAML workflow are basically ways to describe the initial state of a WF workflow before execution (i.e. they are templates).

Even at runtime, each activity in the workflow definition is used as a prototype to create instances of it to execute in a specific workflow context (see spawned contexts). Cloning of the prototype instance is done in WF by serializing the activity into an in-memory stream and loading it back out into a new CLR instance.

All of this works very well in most cases, but something I was trying to do recently led me to wish the WF team had provided a third way of specifying a workflow definition: As an actual CLR instance of an activity tree; which, after all, is what WF does with the CLR type you provide. This would've been a pretty interesting way of dynamically generating workflow definitions directly through code, without having to resort to either using self-modifying workflows or generating XAML at runtime.

baf:FolderName

Link. July 17, 2007. Comments [0]. Posted in: BizTalk

The BizTalk Adapter Framework handles a lot of the configuration baggage for adapters automatically using property grids and an annotated XSD schema provided by the adapter management classes. Besides this, the framework allows the developer to customize how a configuration property is edited in the property grid by including annotations in the configuration XSD that inject custom type editors or custom type converters.

The Adapter Framework schema (BizTalkAdapterFramework.xsd [1]) also provides some initial editors one can use by simply setting the type of the configuration element to the correct value. One new type that appears to have been introduced in BizTalk Server 2006 is baf:FolderName, which uses the standard Windows Folder Picker dialog to select a file system directory. Pretty useful for properties that must reference a folder name! Here's how to use it:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema 
   elementFormDefault="qualified" 
   id="ReceiveLocation" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:baf="BiztalkAdapterFramework.xsd">
   <xs:import namespace="BiztalkAdapterFramework.xsd" />
   <xs:element name="Config">
    <xs:complexType>
       <xs:sequence>
         ...
         <xs:element name="OutputDirectory" type="baf:FolderName"/>
         ..
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

This seems like a good complement to the baf:FileName type that already existed in BizTalk 2004, which used the WIndows File Open dialog.

[1] For the curious, this schema is embedded as a resource inside the Microsoft.BizTalk.Adapter.Framework.dll assembly.

System.Transactions and Workflows

Link. July 15, 2007. Comments [3]. Posted in: .NET | Architecture | Workflow

Scott Bellware discusses some interesting things here regarding transactions and extensibility hooks and even considering Ruby on Rails as a web front end. I'll ignore the Ruby thing, but I do want to talk about his comments on transactions and workflows.

If I understand right, Scott is basically providing a way to extend his application through user-defined workflows that are executed at specific and controlled extensibility points. This is a very cool scenario for WF that enables very interesting possibilities.

His concern, however, seems to center around controlling what happens when one of those user-defined workflows fails, to ensure the entire system is not left in an inconsistent state. This is certainly a valid concern, but it is one that I feel isn't quite as simple to solve as simply "use transactions".

Let's take WF out of the picture for a moment and assume we were using a good old code-based extensibility model (or even a script-based one). Even with the help of System.Transactions and distributed transactions, there's really no way to guarantee that whatever code users of the system put into the extensibility hooks would still work correctly in the event of failure. This revolves around the fundamental fact that there's no guarantee that whatever is put in there is even transaction-aware. Granted, there's a big chance that code put in there is indeed transaction aware, but that's only because a lot of what comes directly into the core .NET framework is tightly integrated in itself. Indeed, for all you know, the user might have even explicitly bring out his operations out of the transactional context (for example using "Enlist=false" in his connection strings).

So even if you wrapped your extensibility hooks with a transaction scope built with System.Transactions, there's no guarantee that a transaction rollback will really bring the system to a consistent state. That's a constant danger with extensible systems, and one that it is not easily addressed. If you've noticed, most framework facilities focused on extensibility only concern themselves with the security problems, but not with extension behavior in the general sense.

This fundamental issue doesn't really get any better just because your extensions are now written as workflows. Indeed, it can become a bit more complicated. To me, using System.Transactions with WF Workflows used in this matter doesn't really make much sense, for several reasons:

  1. Yes, WF supports System.Transactions (indeed this is what a TransactionScope activity uses underneath), but the same danger exists of someone using an activity that's not transaction-aware.
  2. Wrapping the entire workflow in a System.Transactions transaction limits substantially what the user can do with the extension workflows. Are you willing to restrict your users to running only short-lived, simple workflows?

The second one is to me the most significant one, because putting that restriction in place limits substantially the power of WF for these scenarios, particularly when you allow workflow persistence and tracking as part of your application extensibility.

The one benefit that WF gives you over code-based extensibility for handling errors is indeed mentioned by Scott: Compensations. This is a very powerful mechanism, particularly for long running workflows, and can certainly be leveraged by extension workflows to put the system back into a consistent state.

In the end, just like with code-based extensibility, you still need to put guidelines in place to make sure users extending your system do so in such a way that they don't jeopardize the behavior and consistency of the entire system, but even with WF, it is still hard to put those guidelines in executable form.

In some cases, however, WF can indeed make it easier, if you're willing to live with some restrictions. For example, here are some ideas to think about to improve your chances:

  1. Restrict the vocabulary: WF can be extended through the use of custom Activities. Ideally, you will have devised a set of custom activities specific to your problem domain that the users can use to compose their extension workflows. If you're willing to restrict users a bit, and your activity set is complex enough, consider putting restrictions in place so that users can only compose extension workflows using a set of activities you've "approved" (those on your own set and some basic flow control ones, for example). This won't be a perfect model, but can improve the chances that users don't extend the system incorrectly, and can easily be done.
  2. Use validators: Take advantage of WF's ActivityValidators to enforce rules on your extension workflows. If you've also restricted the vocabulary, you can certainly take advantage of domain=specific knowledge to write the validation rules. For example, if you've got an UpdateXXX activity, you could validate that it always is used within a TransactionScope activity.
  3. Create templates your users can use to get started writing extension workflows. Ideally, make these into top-level workflow activities your users can derive from. So, for example, you could have users create a workflow derived from InsuranceExtensionWorkflowActivity instead of a simple SequenceWorkflowActivity, Your base workflow could also have custom validators enforcing, for example, that a global compensation flow is implemented by the users (if necessary).

None of these are foolproof, but they can improve the odds in your favor when used correctly.

Failed Message Routing and Send Ports

Link. July 15, 2007. Comments [0]. Posted in: BizTalk

I'm putting this one here just in case I forget about it again:

BizTalk Server 2006 introduced a very nice feature called Failed Message Routing. This is usually enabled on Receive Ports to allow the developer to handle failed inbound messages through BizTalk itself, as it allows the failed message to be routed to another port or a dedicated error handling Orchestration. This is a very cool feature you can use to deal with messages that fail processing during the receive pipeline processing or that matched no active subscriptions on the message box.

However, BizTalk 2006 also supports Failed Message Routing on Send Ports! The option to enable them is hidden in the "Transport Advanced Options" section of the Send Port Properties dialog:

SendPortFMR

This option provides an alternative to the use of delivery notifications in a BIzTalk Orchestration, with the following advantages:

  1. It doesn't force an orchestration to wait until retries have been exhausted for the delivery notification, so the sending orchestration can still do other work.
  2. It allows the error condition to be handled in an asynchronous fashion
  3. It is a good replacement for delivery notifications in messaging-only scenarios.

A few things to watch out for:

  1. The message is only routed after all retries configured on the send port have been exhausted.
  2. You can combine Failed Message Routing with Delivery Notifications; the orchestration will gets it's notification and the failed message will still be routed.
  3. Like with Delivery Notifications, failed message routing will only happen if both the primary and secondary transports fail delivery.

BizTalk Server 2006 R2 Pricing

Link. July 15, 2007. Comments [0]. Posted in: BizTalk

It appears that the pricing for BizTalk Server 2006 R2 has been announced, see here, although the main BizTalk site doesn't seem to have the information yet.

It would be interesting to know where the new pricing for Enterprise Edition comes from (35.000 vs 30.000 for BTS06 R1). I wonder if the licensing model is changing... Traditionally, BizTalk licensing has been tied solely to the scalability and performance possibilities of the Enterprise Edition (multiple processors + multiple servers per group). However, I wonder if this is changing in R2 and Enterprise now also brings features not available in Standard edition, because the pricing for the Standard edition doesn't seem to have changed at all!

Articles vs. Blogs

Link. July 13, 2007. Comments [0]. Posted in: Blogging

Larry O'Brien posted an interesting piece as a response to Jackob Nielsen's post on Articles vs. Blog Postings. Jackob Nielsen's opinion was that experts should spend their time writing longer, complete articles instead of blogging. Larry shoots down Nielsen's theories based on his own experience, and I'll agree with Larry this time, if not for the same reasons.

I'd first like to point out that articles and blogs are not at odds with each other; you can do both and still get good results. I've written articles for magazines in the past and I'll say it is a lot of work and can usually take a lot of time. Personally, I admire those that have the drive, guts and patience to do that month after month. Blogging can certainly take a lot of time as well, particularly if you write the occasional long article, but not anywhere on the same scale. I favor blogging now not because it takes less work, but because I find it more useful for myself.

A lot of what I write about on my blog is about stuff I've learned (or am learning) during my own projects, and it's a great resource that I constantly search and refer back to when needed. So, while I try to write so that other people will find my blog useful, my primary drive has always been personal benefit: it provides not only the constant reference (so that I don't forget things), but it's also an excellent way to learn at the same time. When I force myself to write about a topic, I need to make things a lot clearer on my head and thus end up with a better understanding of what I'm writing about.

Monetary gain [1], or leads, while useful, have not been the main motivation for having this blog for me. To be honest, while I've gotten some work from my blog, it hasn't been all that much (I'd sure appreciate any leads :-)). Then again, that might be because I don't have all that many readers...

[1] Yes, I do have some ads on this blog through Google adsense, but if I told you what those ad clicks have amounted to, you'd be laughing ;-)

New Blog Theme

Link. July 13, 2007. Comments [3]. Posted in: Blogging

I've been playing the last couple of days with my blog's dasBlog theme and I've settled on a new design for now. There's still some tweaking left to do, but I'm happy enough with the results for now :-)

NewBlogDesign

Visual DSLs

Link. July 13, 2007. Comments [2]. Posted in: .NET | Architecture

Scott Bellware wrote yesterday on disambiguating fluent interfaces (aka APIs) from domain-specific languages. Rant aside it's an interesting read. Something, however, gave me a chuckle: Scott says:

"At some point in the near future, Microsoft will tell the .NET mainstream that DSL's are visual, that they are drag-and-drop, and that they require a new plug-in to Visual Studio in order to make them and use them."

Hummmm..... sorry to say this Scott, but they already did a couple of years ago :-). I think it started with the whole Software Factories [1] idea that Microsoft pushed some time ago.

I must say, though, that I don't hold any grudges to the idea of Visual DSLs. In fact, they can be very useful tools both to create and visualize software. The problem appears when a) they are not the most productive way of working either because of limitations in the visual language itself, or b) because of poor implementation. The Windows Workflow Foundation Designer strikes me as an example of a concept where the visual thing works very well, though it has an unfortunate implementation (it's slow as molasses, almost unbearable to use at times!).

For many of these tools, what I'd really like to have is the best of both worlds: Having a visual experience can be very useful, but having a productive, effective and efficient textual dsl is, to me, a core requirement. Despite what some people might think, writing text is still a far more efficient means of writing software if you have the right language at your disposal.

[1] I think the Software Factories idea has some good merits as a conceptual concept and vision, but it was unfortunately named (and I believe the term has made substantial damage to our software industry, by the way).

Atomic Soul

Link. July 11, 2007. Comments [0]. Posted in: Personal

I just picked Russell Allen's Atomic Soul CD a couple of days, and I've been loving it; great stuff and highly recommended. The opening song, Blackout, is pretty strong right from the start, and Seasons of Insanity is sure to remind you playing Doom :-).

Wombat

Link. July 11, 2007. Comments [3]. Posted in: Vim

I discovered a few days ago another great color scheme I ran into for Vim: Wombat, by Lars H. Nielsen.

VimWombat

I've been using this one for a few days now and I'm loving it, so for now it will be replacing moria, my previous favorite. Unfortunately, I don't think this one would suit itself too much to trying to clone in Visual Studio (particularly since even in this day and age the VS editor doesn't support italics!).

Suspending Messages and Cleanup

Link. July 5, 2007. Comments [0]. Posted in: BizTalk

Here's another reminder to myself when writing BizTalk Adapters: When creating a receive-side BizTalk adapter, you need to be extra careful about when you can release (clean up) a message part data stream.

There are two particular scenarios that I've seen cause trouble for adapters when trying to implement message suspension on submit failures:

1. You release the message part data streams too early. This mistake is very easy to make when using the base adapter in the BizTalk SDK, because it is not clear about when it is done processing a message. So what might happen is that you end up releasing the data streams after the failed submit batch is done, but before the suspension batch is committed, so that the messaging engine is left with a disposed stream in the middle of an operation.
Be careful about ensuring you're all clear before cleaning up after yourself.

2. Ensure that data streams are readable before suspending messages.

Another common error I've seen is using non-seekable streams as message part data streams. When you first submit a message from your adapter, and it fails, it's very likely that the data stream has been partially or completely consumed during submission (for example, by a disassembler component in the pipeline). If you have a non-seekable data stream, and you simply take the same failed message as is and submit it in a second batch to the suspend queue, it will fail, because the messaging engine cannot read the entire message contents anymore to save them.

So if you find yourself in this scenario, be prepared to recreate the data streams after the initial submission failed and before the second one.

Either of these problems can cause some really weird errors during processing including:

  • The Messaging Engine received an error from transport adapter "XXX" when notifying the adapter with the BatchComplete event. Reason "Exception from HRESULT: 0x80C0169C".
  • The transport batch from adapter "XXX" has been rejected by the messaging engine because the batch is empty. Contact the adapter provider to find out why the transport batch is empty.

One Year

Link. July 5, 2007. Comments [1]. Posted in: Personal

devdeo websiteThis past month of may, our company turned one year old. It's been a pretty interesting year with lots of new challenges and it's been a big learning experience for me, in more ways than one. I'd like to thank all the people that have trusted in us and have allowed us to work with them, you've made it all possible!

 As part of the "celebration", we've just released our redesigned corporate Web site, based on a cleaner layout, and simplified structure. While we still need to clean a few rough edges, we've very happy with the new look of the site, and I hope you like it as well. Do let us know your opinion!

I hope this next year brings us new and more interesting challenges than the one just past! We're also always looking out for new project opportunities, so if you, or anyone you know, is interested in the kind of work we do, please do contact us! 

Failed Message Routing and Message Suspension

Link. July 4, 2007. Comments [2]. Posted in: BizTalk

A long while ago, while BizTalk 2006 was in beta, I mentioned a couple of things about the Failed Message Routing feature and how it related to adapters. Turns out I was a bit off the mark, and wanted to leave this here in case I ever need this information again :-).

A couple of weeks ago I spent some good time troubleshooting an adapter, and was able to understand a bit better the relationship between this feature and an adapter's behavior. Indeed, as I initially stated, failed message routing depends on the ability to suspend messages that fail the submission process.

What can make this a bit confusing is that the BizTalk Messaging Engine can decide to suspend messages on its own without adapter intervention. In cases where this happens, failed message routing will still work, even if the receiving adapter doesn't actually support suspending messages in an explicit way.

For example, under some configurations, when an XML message fails processing in the pipeline because the XML Disassembler component rejects it, the Messaging Engine will suspend the incoming message on its own [1]. When this happen, the adapter will receive an status code in the batch results with the value BTS_S_EPM_MESSAGE_SUSPENDED (0xc00001).

What's interesting about this value is that it is a success status code; so, from the adapter perspective, it looks as if the message submit operation completed without errors. It can, however, be a little confusing if you're not aware of this behavior.

Other than this scenarios, if you want to fully support failed message routing with your adapters, you still need to fully implement suspending messages (through IBTTransportBatch.MoveToSuspendQ()). 

[1] Unexpectedly enough, I haven't seen this behavior with the Flat File disassembler.

About

Tomas Restrepo is co-founder of devdeo. His interests include .NET, Connected Systems, PowerShell and, lately, dynamic programming languages. More...

email: tomas@winterdom.com
msn: tomasr@passport.com
twitter: tomasrestrepo

Technorati Profile

devdeo logo

View my profile on LinkedIn

MVP logo

Syndicate

Ads


Links

Categories

Statistics

Total Posts: 1014
This Year: 84
This Month: 3
This Week: 2
Comments: 776

Blogroll

Post Archive

Other

Copyright © 2002-2008, Tomas Restrepo.

Powered by: newtelligence dasBlog 2.1.8102.813

Sign In