Blog Stats
  • Posts - 10
  • Articles - 0
  • Comments - 14
  • Trackbacks - 7

 

Tuesday, March 28, 2006

Performance Testing at MS DAY 1

The morning was spent completing the biztalk build and config on the dev boxes being used. The sourcesafe repository was copied over and by mid morning we were up and running with builds on the dev boxes.

During the afternoon we tested each of the 3 designs against a standard "out of the box" config - this ran on a single 4-way biztalk box and a super fast sql box. As a recap, the following are the designs

Async Design - designed to return processing to the payment flow asap, by launching the final accounting writes and summarisation as an async orchestration.

All in one - this design complete the entire process in a single synchronous orchestration - all processing is completed before returning to the payment flow.

Dispatch Message - this design completes the final accounting in a similar way to the Async design, but rather than call the orchestration using a "start", a message is dispatched as a trigger.

Our initial tests were all based around 10,000 payments in a single file, on a single biztalk box. A harness was built around BAM to extract timings based on the number of accounting message posted between the first payment BAM activity and the last accounting BAM activity being written. This benchmark takes out the "loading" of the messagebox with the payment messages and so gives us a purer "throughput" figure (it also took account of the buffered BAM writing)

During the day we saw a number of problems with rules engines timeouts. Config changes were made to increase translation timeouts and also increase the rules policy cache. We also made some changes to the code that instantiates and executes the policy to improve its use of the cache - this improved performance. We saw significant troughs of performance during what looked like the rules loading. Darren took a number of dumps and these were sent to the US to review.

Our day 1 tests started on 1 box showed performance ranging from 28 to 120 accounting entries per second. The best performing design was the "all in one" at this point, with 120 aeps (accounting entries per second) on a singe box and 169 on a two box config.

At the end of the day we started off 1 million payments with a 2 box config to see if we saw the same type of performance.
 
Summary : Best performance today: 169 eps on 2 boxes.

Thursday, September 15, 2005

Biztalk is dead !! Long live WWF (No, not the wrestling...)

Windows Workflow Foundation has been officially announced at the PDC. Get a load of this, from Darren Jeffords blog;

For those of you familiar with BizTalk Server 2004, Windows Workflow Foundation is analogous to the Orchestration Designer and Orchestration Runtime (XLANG) in BizTalk.  It allows you express your “workflow” using a designer and then have this executed by a runtime.

The Orchestration designer in BizTalk was fairly heavy-weight and not really suitable to be hosted and used in other applications (memory footprint, etc.), Windows Workflow Foundation is light-weight and re-hostable allowing you to integrate workflow functionality into your application.

I wonder what this means?

Business Rules are built into the designer allowing you to encode any flexible rules separate from the implementation allowing for easy modification.

WWF provides a framework for building and hosting workflows inside Windows apps.  It will be part of the WinXF namespace along with Indigo and Avalon.

OK, no need to panic - from the horses mouth;

Future versions of BizTalk Server, MBS Applications and Office "12" will use this technology.  As of today workflow is a new player in the middle tier for application development.  Every application includes some workflow and with Windows Workflow Foundation you can capture that workflow in a model.


Monday, June 06, 2005

Facts and Slots: XPath Selector and XPath Field

The following is an extract from a thread at msnusers.com/biztalkserverstuff. Charles Young explains with great clarity the subtle differences in the rules engine parsing of facts expressed using XPath Selector and XPath Field combinations (or “facts” and “slots”);

This causes so much confusion.
 
The rules engine works by asserting 'facts' into its working memory.   A 'fact' is some object, and therefore contains fields, commonly called 'slots' in the world of rule engines.   The exception is thrown because the rule engine is attempting to access a slot in a fact in order to evaluate a condition within a rule.   The engine is attempting to do this evaluation because the relevant fact has been asserted.   However, when it looks for the slot, it can't find it.
 
This translates into the world of XML as follows.   When you create a vocabulary definition for a node in your schema, there are two properties that are set.   These are 'XPath Selector' and 'XPath Field'.   Thinks of these as the technical terms that refer to some data item.   The vocabulary definition is mapping these to business-friendly terms defined by the Name and Display Name properties.
 
The XPath Selector is used to define and select a 'fact'.   Vocabulary definitions can refer to a fact, rather than a slot, and in this case the XPath Field property is empty.   However, in your case, there will be an additional XPath expression in the XPath Field property.   This will typically be used to select a descendant node of the fact.   The exception is happening because the 'fact' (the programId element) exists (i.e., the XML Selector addresses at least one programId element - if it addresses more than one programId element, multiple facts will be asserted into memory), but the 'slot' (the id element) does not.
 
If the programId element did not exist, no error would occur.   Very simply, the engine would not be able to assert the programId fact and would therefore realise that it could not evaluate any rule conditions that depends on this fact.   Because the programId element exists, the engine assumes that the id child element exists, and throws an error when it finds it doesn't.
 
One way to deal with this is to edit your XPath Selector so that it only selects programId elements that contain an id element.   XPath support filters, so you could amend your selector as follows (addition shown in bold):
 
"/*[local-name()='SOA_Message' and namespace-uri()='http://schemas.test.com/20050307/SoaMessageSchema']/*[local-name()='products' and namespace-uri()='']/*[local-name()='clients' and namespace-uri()='']/*[local-name()='client' and namespace-uri()='']/*[local-name()='programs' and namespace-uri()='']/*[local-name()='program' and namespace-uri()='']/*[local-name()='programId' and namespace-uri()=''][id]"
 
You might want to further improve on this with the following filter [id = ""].   This would only select programId nodes as facts if they contain an id child element with a non-empty text node.
 
The key to running the rules engine effectively over XML is to understand XPath and the difference between 'facts' and 'slots', and to edit your XPath Selectors and XPath Fields accordingly to meet your needs.

Rolling Thunder

It’s been a busy week. I’ve been on holiday for only a week and it’s going to take the best part of a day to catch up with voicemails, emails, and blogs via bloglines. Apart from almost breaking my foot in NJ (long story) and the Yankees going down to their biggest defeat at the hands of the Red Sox, it was a nice break.

Some essential catch ups;

Wednesday, May 25, 2005

The Vocabulary: after thought for API?

The more I work with the Rules API the more I'm convinced that the Vocabulary element was only created for the BRC. The most generous I can be is that someone came up with a good idea for the BRC and "retrofitted" it for the API. There are two reasons for this;

  1. The API is unsupported and undocumented.
  2. The BRL (Business Rules Language) can function happily without it - in fact a rule can reference directly the document element / .NET method etc.

If you take a look at the following two bites from the exported rule store, UI think you'll see why I come to this conclusion;

The following is in effect a definition of a string literal in the export vocabulary

  <vocabularydefinition id="54e58c56-e279-4729-b0d4-2e7bfbef989e" name="TransferControlAccount" description="">

      <literaldefinition type="string">

        <string>222222</string>

      </literaldefinition>

      <formatstring language="en-US" string=" Transfer Control Account" />

   </vocabularydefinition>

The following is taken from an extract of an action. This interesting thing to note is that the literal value "222222" is also specified, along side the link to the vocab entry specifying it;

        <function>

          <vocabularylink uri="2e2bb376-b4ac-4d42-9573-cdf42088f681"

element="453cb556-e96e-4e10-b456-96bf6d1313c6" />

          <classmember classref="Accounting" member="AddAccountingEntries" sideeffects="true">

            <argument>

              <constant>

                <vocabularylink uri="2e2bb376-b4ac-4d42-9573-cdf42088f681"

element="54e58c56-e279-4729-b0d4-2e7bfbef989e" />

                <string>222222</string>

              </constant>

            </argument>

          </classmember>

        </function>

So why would this redundant data be here? Performance? I doubt it. The whole "immutability" of Rules and Vocabularies makes sense from a version management perspective until you actually start using them. Imagine the scenario; You have defined your Vocabulary before starting your rules (This is required because you can't reference a Vocabulary from your rules until that Vocabulary has been published - this in itself is predicated on knowing all the terms up front - big assumption!). You define 25+ rules, using multiple references to your vocabulary. Fine. You now publish the rule policy. At this point the world is still in order - version 1.0 of both rules and vocabulary are in a lotus type harmony. But what happens when you want to extend or amend the vocabulary? You create a new version of the Vocabulary (cut & paste!),make your amendments and publish it. Of course NONE of your rules will reference this new vocabulary (1.1) as all links reference 1.0 of the vocabulary. The only way to reference the new vocabulary is to create a new version of your rules (cut & paste!), and edit EACH AND EVERY reference to the vocabulary to repoint to the new version.

This isn't new of course, and tools do exist to deal with it.

The BRC has been criticised for this "cut & paste" mentality, but in fact some of the problem goes back to the design of the rules system itself.

Thursday, May 19, 2005

IRuleSetTrackingInterceptor: tracing rules execution

I don’t know about you but I find the best way to understand how something is working is from reading the code and then stepping through its execution, with VS’s trusty local and immediate windows. A friend of mine calls this  “developers documentation”, and whilst I certainly wouldn’t go as far as saying it’s a substitute for good docs (and by that Chris, I mean “living models”!), I always end up doing it during any maintenance code cycles (unintended consequences and all that).

 

Unfortunately the execution of a BizTalk rule policy isn’t quite as straight forward. It’s not a set of simple sequential steps that you can step through. If it was it would probably be far less useful as a rules engine – and certainly far less performant.. Instead it implements a RETE algorithm for small rulesets and some propriety one for large rules sets according to the man himself. Anyway the long and the short of this is that rules processing is done behind closed doors, which makes for a tough time in understanding what happened during the policy being executed. I’m sure a good understanding of the RETE process would help – Dummies guide to RETE anyone?

 

The Microsoft Business Rules Composer (BRC) does allow rule “testing” by implementing the Tracking Interceptor DebugTrackingInterceptor. The following is a sample output produced by the BRC for the Loans Processing policy (from the Loans Sample in the SDK. 

 

RULE ENGINE TRACE for RULESET: LoanProcessing 5/19/2005 12:46:13 PM

 

FACT ACTIVITY 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Operation: Assert

Object Type: DataConnection:Northwind:CustInfo

Object Instance Identifier: 782

 

FACT ACTIVITY 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Operation: Assert

Object Type: TypedXmlDocument:Microsoft.Samples.BizTalk.LoansProcessor.Case

Object Instance Identifier: 778

 

FACT ACTIVITY 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Operation: Assert

Object Type: TypedXmlDocument:Microsoft.Samples.BizTalk.LoansProcessor.Case:Root

Object Instance Identifier: 777

 

CONDITION EVALUATION TEST (MATCH) 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Test Expression: NOT(TypedXmlDocument:Microsoft.Samples.BizTalk.LoansProcessor.Case:Root.Income/BasicSalary > 0)

Left Operand Value: 12

Right Operand Value: 0

Test Result: False

 

CONDITION EVALUATION TEST (MATCH) 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Test Expression: NOT(TypedXmlDocument:Microsoft.Samples.BizTalk.LoansProcessor.Case:Root.Income/OtherIncome > 0)

Left Operand Value: 10

Right Operand Value: 0

Test Result: False

 

CONDITION EVALUATION TEST (MATCH) 5/19/2005 12:46:13 PM

Rule Engine Instance Identifier: fb330399-15f0-4dc7-9137-4463a32f580e

Ruleset Name: LoanProcessing

Test Expression: TypedXmlDocument:Microsoft.Samples.BizTalk.LoansProcessor.Case:Root.PlaceOfResidence/TimeInMonths >= 3

Left Operand Value: 15

Right Operand Value: 3

Test Result: True

[.. cut for brevity ..]

 

This implements the IRuleSetTrackingInterceptor interface which you can use to produce you own custom debugging/tracing of rule processing.

 

Most of the information is there (although I’m still troubled that the tracing of the process doesn’t allow you to examine the facts i.e., the data rows, xml docs etc), but it’s not exactly easy to see what’s happened. Understanding the match-conflict resolution-action helps considerably.

 

If you are executing your policy outside of BizTalk, or in a component consumed within BizTalk you can specify an alternative IRuleSetTrackingInterceptor. This has the advantage of allowing you to step through the rule processing if you wish, and also allows you to view fact details (through the facts you pass to the policy). The following code demonstrates how to invoke your MyInterceptorClass().

 

xmlDocument = IncomingXMLMessage.XMLCase;

typedXmlDocument = new Microsoft.RuleEngine.TypedXmlDocument("Microsoft.Samples.BizTalk.LoansProcessor.Case",xmlDocument);

policy = new Microsoft.RuleEngine.Policy("LoanProcessing");

policy.Execute(typedXmlDocument,new MyInterceptorClass());

OutgoingXMLMessage.XMLCase = xmlDocument;

policy.Dispose();

 

Once you understand the various stages to the rule engine, you soon yearn for a better way to visualise a complex processing of rules. To this end I started thinking about how I’d like to see what was happening. In the past I’ve used UML sequence diagrams to demonstrate how messages are sent between object and also object lifetime.

 

Initially , I though that each fact would “constructed” by assertion and “destructed” by retraction. The same would happen with the rules placed into and out of the Agenda. This is sort of how it would look;

 

 

The problem with this approach is that it makes a very complex picture when many facts are asserted and many rules get passed onto the agenda. In the end I settled for a “swim lanes” type approach, separating each phase (facts asserting/retracting, condition matching, adding to agenda and firing actions) in a lane and then just processing sequentially. I think it works quite well, but you can see the loans processing sample output here.

 

 

The TrackingInterceptor also outputs to XML. If anyone’s interested in a copy of the source/component you can drop me a note here.

 

After my experiences I have the following request for MS

 

Request 1: Allow the BRC to use a difference Tracking Interceptor

Request 2: Allow the Tracking Interceptor to get hold of the full facts – i.e., let me dump out the xmldoc.

Request 3: Allow the “Call Rules” shape to specify a tracking interceptor

Tuesday, May 17, 2005

Missing Vocabulary API

Has anybody seen a Vocabulary API for the rule engine? No? That's probably because it seems to either be on its way out or never made it in the first place. According to the BizTalk SDK  "The following objects are exposed by Microsoft(r) BizTalk(r) Server 2004, but are not used in BizTalk Server programming." These include the following from the Microsoft.RuleEngine Namespace

  • Vocabulary
  • VocabularyDefinition
  • VocabularyDefinitionDictionary
  • VocabularyDictionary
  • VocabularyInfo
  • VocabularyInfoCollection
  • VocabularyLink

All under the heading of "Unsupported BizTalk Classes". So, I guess that means not to use them! Our guys are in the middle of doing a Biztalk Proof of Concept with MS at Reading, so I hope to get an answer on this!

Monday, May 16, 2005

Forward Chaining ?

The BizTalk 2004 rules execution engine is "a discrimination network-based forward-chaining inference engine designed to optimize in-memory operation". Apparently.

What I understand this to mean is that it can arrive at a decision based on reasoning of facts against conditions (inference), and that it reacts to new facts being "asserted" in a way which means that only rules which are relevant are re-examined (forward chaining). Facts get put into working memory. This triggers rules whose conditions match the new data. These rules then perform their actions. The actions may add new data/facts to memory, thus triggering more rules. And so on. The wikipedia has a pretty good summary.

 

Whilst this sounds pretty academic, it's also important. Without understanding this, you can get yourself in a real buggers muddle - I'm proof of this! The rules engine has 3 stages to execution. The first stage is "matching" - if you've done some tracing of rules execution in the BRC this stuff will sound familiar. This stage checks its rules "conditions" against current "in memory" facts. These facts being loaded into memory are the "asserts" you see in the debug output. Once a condition is evaluated as true it gets added to the rule "agenda" (Agenda Update in the trace output). This is a sort of wait area until the engine has been through all the rules in the policy. Next stage is "Conflict Resolution" (don't you just love that!). This is where the order of the rule firing is determined based upon the priority you have set for the rule. In the next "Action" stage, the actions of the rule are fired.

 

What's important to remember here is that the "Action" stage could assert some more facts into memory. So what? Well to quote MSDN;

 

"Note that rule actions can assert new facts into the rule engine, which causes the cycle to continue. This is also known as forward chaining. It is important to note that the algorithm never pre-empts the currently executing rule. All actions for the rule that is currently firing will be executed before the match phase is repeated. However, other rules on the agenda will not be fired before the match phase begins again. The match phase may cause those rules on the agenda to be removed from the agenda before they ever fire. "

 

This is essentially what you would expect to happen I guess, but as most of the rules processing is done "behind closed doors" it can be hard to get a handle on what's causing this type of effect. The tracing/debugging leaves a little to be desired. That's where I'm off to next ...

Optimize Thyself

OK, so tell me we haven’t all done this at least once. We come across a way to improve our output efficiency, and at the same time to enforce good design and standards – we figure we should provide the rest of the team with a tool that can help them achieve the same. We feel, for a small and fleeting moment, that warm glow.

 

Until someone comes along and points out a far better implementation of your optimisation, and delivers up a tool that’s more extensible, better integrated and (more importantly) finished. Don’t you just hate that?

 

Well you shouldn’t, and I don’t anymore. Bill Jones makes a good case for why you should be looking at CodeSmith 3.0 (Erics site was temporarily down when this was posted).

 

I found myself frequently writing the same CRUD code for my data layer objects. After looking at some great DAL generators (nTierGen.Net from Gavin Joyce is in my opinion one of the best), I threw together a DAL generator based around a code templating system. CodeSmith takes that idea and implements it beautifully. Really, take a look!

Friday, May 13, 2005

Move along, nothing to see

I suppose my first entry in this blog should be some insightful post about the BizTalk Rules Engine (BRE). Sorry, move along please, nothing to see.

 

You see, I want to record my journey through a whole new technology. The BRE is that technology. I’m lucky – I’ve been given the opportunity to specialise in one facet of a BizTalk, and I want to share that experience – even the good, bad and ugly times.

 

 

Copyright © Jason Hyland