Tuesday, October 31, 2006
Thursday, October 26, 2006
Correlation and Int64 context properties
If you try to initialize a correlation set that uses a context property of type Int64 you get an "ArgumentOutOfRangeException" with an error similiar to this - "Index and length must refer to a location within the string."
I've created a small test case I'm uploading which has three correlation sets defined - one uses a string property, one uses an Int32 and one uses an Int64.
the first two work fine, but as soon as I select the third one to be intialized as well I get the error mentioned. I am running on a windows 2003 server.
You can download it here
Monday, October 16, 2006
Xpath to select nodes with distinct attribute value
/*[local-name()='MyElement' and namespace-uri()='MyNamespace']/*[not(@MyAttribute=preceding-sibling::*/@MyAttribute)]
"Call orchestration" in an unreachable code error
In a process I have a decision shape.
In it's condition I've put a constant "false" to make sure the code never gets executed (my way of commenting out things temporarily) and under that branch I have a "call orchestration" shape.
When I try to build the assembly with this process I get an “unexpected system exception” error with no details about where it happened (filename, line) or why.
Removing the “call orchestration" shape allows the assembly to build fine.
Same does keeping the "call orchestration" shape but changing the condition to any other false condition (for instance a==57 when I know a is 1)
While this is not really a problem as there's a clear and simple way around this it simply can't be right.
Call to BizTalk web service does not start process
Then, after a while, when you call the web service nothing seems to happen.
you don't get any exception , but the process does not start nor can you see any errors in the event log or suspended instances in the BizTalk Admin console
Try and capture the SOAP body using the network sniffing tool of your choice and validate it against the schema.
Most chances you will find your request is invalid according to the published schema and the deserializaion failed (do you need to update the web reference?).
Wish Biztalk would be kind enough to report this error, but it doesn't.
Tuesday, October 03, 2006
Another important point about enums and web services
This is an importat reason begind the enumerated type conceept - to be able to give a meaningful name to a value.
In the Xml world, however, enumerations are more limited. they are thought of more as a restricted list of allowable values, and less a tranlsation between a value and a name, and so - it is not possible to provide to representations for an enumeration member, you can only specifiy a list of allowed values.
This is useful enough, albeit limited.
The grave danger, though, is when switching between the two.
if you have a web service that returns an enum which is declated as such -
Public Enum MyEnum
X = 2
Y = 87
and you look at the wsdl generated for this enum you will see something like -
As you can see, there is no mentioning of the values 2 and 87.
This means that if you add a reference to this web service the proxy generated will include an enum defined as -
Public Enum MyEnum
And so - when the message get serialised on the web service end Y (for example) goes into the xml, but when it gets deserialised on the client end, Y is deserialised as 1 and not 87 which was it's original value.
You can see, I'm sure, that this can be quite dangerous.
There are two ways around this - one would be to return the underlying value and not the enumeration memeber. you loose your "friendly name" and the well defined list of possible values, but you know the value is absolutely correct.
On the other hand you can ensure you always use ordnial, 0 based, values for your enumeration members (which is exactly like not specifying then to begin with). you loose the ability to have specific values in, but get to keep the enumerations in the picture and that well defined list of possible values
Monday, October 02, 2006
Suspended instance and correlation subscription
We've created a process that starts with a parallel convoy to subscribe to two messages it needs to start with.
As this was a quick test scenario we've used the ReceivePortName as the correlation property, planning to drop both messages (of different types) to the same receive location and seeing them arrive at the orchestration.
It all worked very well. well most of it did. Something further down the process failed which caused the orchestration instance to be suspended, and thats perfectly fine.
What I found out next was the big surprise.
We've fixed our problem (or so we thought), so we've re-gac'ed the assembly (no need to re-deploy) and restarted the host.
We did not terminate the existing instance, but dropped two new messages in the receive location's folder, expecting BizTalk to pick them up (which it did) and start a new instance of the process.
It's the fact that the latter did not happen that surprised us.
Looking a bit more carefully we soon realised the two messages got delivered to the existing, suspended, instance rather then creating a new one.
Once we knew the behaviour we kind of managed to rationalise it, but to be honest, I do not think that is what I would expect.
In my mind a suspended instance's subscriptions should be removed, and when additional messages arrive new instance of the process should be created.
I've already wrote a while back that I believe the fact that correlation subscriptions are not being removed once fulfiled (or that we don't at least haev the ability to explicitly remove them) makes a biztalk developer's life much harder, and "zombies" more likely to occur)
Having to worry about suspended instance subscription's is even harder on more error prone.
I guess a counter argument could be that, when a true unique correlation is used (like conversation id of some sort), and an instance is suspended you may still want it to get routed to the same instance, for the small chance you could resume the process with all the related messages, or at least you will have all the messages grouped in once place (under the same process, as consumed) rather then looking for them between instances or, in the more likely case of non-activating correlation - routing failures.
I think a distinction can be made beween correlations used to activate processes, and specifically parallel ones, and non-activating correlations such as when you simply need to route response(s) back to your process.
If the correlation is used for a parallel convoy to activate a process I think in most cases it is safe to assume a new instacne can and should be started, I agree that in the second case, when a message needs to be routed to an existing process, correlating to suspended instances makes much more sense.
I know suspended instances are not something you should really have long term in the Admin Console, I usually like to refer to them as a to-do list, which is definitely not something you want to see grow too long.
Having said that it is still more then just reasonable to expect a few of the lying around waiting to be treated, and they should not have such a dramatic affect on the health of the system.
By keeping the subscriptions open it is possible that newer instances of the process, which might work if the error that caused the original failure was fixed, will not be started and potentially for messages to disappear (as it is not so obvious where they went to without very careful investigation)
I know the correlation we've used is not the best candidate for a real world example, but in fact I have seen it being used in a couple of places, so I guess it is not that strange, and anyway, I'm sure if one thinks carefully enough it is
possible to find more real-world representations of this error.
I hope this approach would be re-considered at some stage, and potentially changed.
Alternatively it would be useful to use a proeprty on the correlation set or the receive shape to specify the expected behaviour.