<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Clemens Vasters.</title><link>http://blogs.msdn.com/b/clemensv/</link><description>Tales from the land of cloud computing. From, well, how shall I say - up here?</description><dc:language>en</dc:language><generator>Telligent Community 5.6.583.19431 (Build: 5.6.583.19431)</generator><item><title>4 Questions</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/12/01/4-questions.aspx</link><pubDate>Thu, 01 Dec 2011 08:38:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10243424</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10243424</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/12/01/4-questions.aspx#comments</comments><description>&lt;P&gt;I answered 4 questions in Richard Seroter’s series of interviews with folks working on connect systems. See the &lt;A href="http://seroter.wordpress.com/2011/12/01/interview-series-four-questions-with-clemens-vasters/"&gt;Q&amp;amp;A here&lt;/A&gt;.&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=45ae933a-3c7e-4863-98e9-c017673b3b55"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10243424" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Architecture/">Architecture</category></item><item><title>Achieving Transactional Behavior with Messaging</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/10/06/achieving-transactional-behavior-with-messaging.aspx</link><pubDate>Thu, 06 Oct 2011 12:10:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10221311</guid><dc:creator>clemensv</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10221311</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/10/06/achieving-transactional-behavior-with-messaging.aspx#comments</comments><description>&lt;P&gt;Elastic and dynamic multitenant cloud environments have characteristics that make traditional failure management mechanisms using coordinated 2-phase transactions a suboptimal choice. The common 2-phase commit protocols depend on a number of parties enlisted into a transaction making hard promises on the expected outcome of their slice a transaction. Those promises are difficult to keep in an environment where systems may go down at any time with their local state vanishing, where not all party trust each other, where significant latency may be involved, and network connectivity cannot be assumed to be reliable. 2-phase-commit is also not a good choice for operations that take significant amounts of time and span a significant amount of resources, because such a coordinated transaction may adversely affect the availability of said resources, especially in cases where the solution is a high-density multitenant solution where virtualized, and conceptually isolated resources are collocated on the same base resources. In such a case, database locks and locks on other resources to satisfy coordinated transaction promises may easily break the isolation model of a multitenant system and have one tenant affect the other.&lt;/P&gt;
&lt;P&gt;Therefore, failure management – and this is ultimately what transactions are about – requires a somewhat different approach in cloud environments and other scalable distributed systems with similar characteristics. &lt;/P&gt;
&lt;P&gt;To find a suitable set of alternative approaches, let’s quickly dissect what goes on in a distributed transaction: &lt;/P&gt;
&lt;P&gt;To start, two or more parties ‘enlist’ into a shared transaction scope performing some coordinated work that’s commonly motivated by a shared notion of a ‘job’ that&amp;nbsp; needs to be executed. The goal of having a shared transaction scope is that the overall system will remain correct and consistent in both the success and the failure cases. Consistency in the success case is trivial. All participating parties could complete their slice of the job that had to be done. Consistency in the failure case is more interesting. If any party fails in doing their part of the job, the system will end up in a state that is not consistent. If you were trying to book a travel package and ticketing with the airline failed, you may end up with a hotel and a car, but no flight. In order to prevent that, a ‘classic’ distributed transaction asks the participants to make promises on the outcome of the transaction as the transaction is going on. &lt;/P&gt;
&lt;P&gt;As all participating parties have tentatively completed but not finalized their work, the distributed transaction goes into a voting phase where every participant is asked whether it could tentatively complete its portion of the job and whether it can furthermore guarantee with a very high degree of certainty that it can finalize the job outcome and make it effective when asked to do so. Imagine a store clerk who puts an item on the counter that you’d like to purchase – you’ll show him your $10 and ask for a promise that he will hand you the item if you give him the money – and vice versa. &lt;/P&gt;
&lt;P&gt;Finally, once all parties have made their promises and agreed that the job can be finalized, they are told to do so.&lt;/P&gt;
&lt;P&gt;There are two big interesting things to observe about the 2-phase-commit (2PC) distributed transaction model that I just described: First, It’s incredibly simple from a developer’s perspective because the transaction outcome negotiation is externalized and happens as ‘magic’. Second, it’s not resembling anything that happens in real life and that should be somewhat suspicious. You may have noticed that there was no neutral escrow agent present when you bought the case of beverages at the store for $10 two paragraphs earlier. &lt;/P&gt;
&lt;P&gt;The grand canonical example for 2PC transactions is a bank account transfer. You debit one account and credit another. These two operations need to succeed or fail together because otherwise you are either creating or destroying money (which is illegal, by the way). So that’s the example that’s very commonly used to illustrate 2PC transactions. The catch is – that’s not how it really works, at all. Getting money from one bank account to another bank account is a fairly complicated affair that touches a ton of other accounts. More importantly, it’s not a synchronous fail-together/success-together scenario. Instead, principles of accounting apply (surprise!). When a transfer is initiated, let’s say in online banking, the transfer is recorded in form of a message for submission into the accounting system and the debit is recorded in the account as a ‘pending’ transaction that affects the displayed balance. From the user’s perspective, the transaction is ’done’, but factually nothing has happened, yet. Eventually, the accounting system will get the message and start performing the transfer, which often causes a cascade of operations, many of them yielding further messages, including booking into clearing accounts and notifying the other bank of the transfer. The principle here is that all progress is forward. If an operation doesn’t work for some technical reason it can be retried once the technical reason is resolved. If operation fails for a business reason, the operation can be aborted – but not by annihilating previous work, but by doing the inverse of previous work. If an account was credited, that credit is annulled with a debit of the same amount. For some types of failed transactions,&amp;nbsp; the ‘inverse’ operation may not be fully symmetric but may result in extra actions like imposing penalty fees. In fact, in accounting, annihilating any work is illegal – ‘delete’ and ‘update’ are a great way to end up in prison. &lt;/P&gt;
&lt;P&gt;As all the operations occur that eventually lead to the completion or failure of the grand complex operation that is a bank transfer, the one thing we’ll be looking to avoid is to be in any kind of ‘doubt’ of the state of the system. All participants must be able to have a great degree of confidence in their knowledge about the success or failure of their respective action. No shots into the dark. There’s no maybe. Succeed or fail. &lt;/P&gt;
&lt;P&gt;That said, “fail” is a funny thing is distributed systems because it happens quite a bit. In many cases “fail” isn’t something that a bit of patience can’t fix. Which means that teaching the system some patience and tenacity is probably a good idea instead of giving up too easily. So if an operation fails because it runs into a database deadlock or the database is offline or the network is down or the local machine’s network adapter just got electrocuted that’s all not necessarily a reason to fail the operation. That’s a reason to write an alert into a log and call for help for someone to fix the environment condition. &lt;/P&gt;
&lt;P&gt;If we zoom into an ‘operation’ here, we might see a message that we retrieve from some sort of reliable queue or some other kind of message store and subsequently an update of system state based on message. Once the state has been successfully updated, which may mean that we’ve inserted a new database record, we can tell the message system that the message has been processed and that it can be discarded. That’s the happy case. &lt;/P&gt;
&lt;P&gt;Let’s say we take the message and as the process wants to walk up the database the power shuts off. Click. Darkness. Not a problem. Assuming the messaging system supports a ‘peek/lock’ model that allows the process to first take the message and only remove it from the queue once processing has been completed, the message will reappear on the queue after the lock has expired and the operation can be retried, possibly on a different node. That model holds true for all failures of the operation through to and in the database. If the operation fails due to some transient condition (including the network card smoking out, see above), the message is either explicitly abandoned by the process or returns into the queue by ways of a lock timeout.&amp;nbsp; If the operation fails because something is really logically wrong, like trying to ship a product out of the inventory that’s factually out of stock, we’ll have to take some forward action to deal with that. We’ll get to that in a bit. &lt;/P&gt;
&lt;P&gt;Assuming the operation succeeded, the next tricky waypoint is failure after success, meaning that the database operation succeeded, but the message subsequently can’t be flagged as completed and thus can’t be removed from the queue. That situation would potentially lead to another delivery of the message even though the job has already been completed and therefore would cause the job to be executed again – which is only a problem if the system isn’t expecting that, or, in fancier terms, if it’s not ‘idempotent’. If the job is updating a record to absolute values and the particular process/module/procedure is the only avenue to perform that update (meaning there are no competing writers elsewhere), doing that update again and again and again is just fine. That’s natural idempotency. If the job is inserting a record, the job should contain enough information, such as a causality or case or logical transaction identifier that allows the process to figure out whether the desired record has already been inserted and if that’s the case it should do nothing, consider its own action a duplicate and just act as if it succeeded. &lt;/P&gt;
&lt;P&gt;Checkpoint: With what I said in the last two paragraphs, you can establish pretty good confidence about failure or success of individual operations that are driven by messages. You fail and retry, you fail and take forward action, or you succeed and take steps to avoid retrying even if the system presents the same job again. There’s very little room for doubt. So that’s good.&lt;/P&gt;
&lt;P&gt;The ‘forward action’ that results from failure is often referred to as ‘compensation’, but that’s a bit simplistic. The forward action resulting from running into the warehouse with the belief that there’s still product present while the shelf is factually empty isn’t to back out and cancel the order (unless you’re doing a firesale of a touch tablet your management just killed). Instead, you notify the customer of the shipping delay, flag a correction of the inventory levels, and put the item on backorder. For the most part, pure ‘compensation’ doesn’t really exist. With every action, the system ends up in a consistent state. It’s just that some states are more convenient than others and there are some state for which the system has a good answer and some states for which it doesn’t. If the system ends up in a dead end street and just wants to sit down and cry because nobody told it what to do now, it should phone home and ask for human intervention. That’s fine and likely a wise strategy in weird edge cases. &lt;/P&gt;
&lt;P&gt;Initiating the ‘forward action’ and, really, any action in a system that’s using messaging as its lifeline and as a backplane for failure resilience as I’m describing it here is not entirely without failure risk in itself. It’s possible that you want to initiate an action and can’t reach the messaging system or sending the message fails for some other reason. Here again, patience and tenacity are a good idea. If we can’t send, our overall operation is considered failed and we won’t flag the initiating message as completed. That will cause the job to show up again, but since we’ve got idempotency in the database that operation will again succeed (even if by playing dead) or fail and we will have the same outcome allowing us to retry the send. If it looks like we can send but sending fails sometime during the operation, there might be doubt about whether we sent the message. Since doubt is a problem and we shouldn’t send the same message twice, duplicate detection in the messaging system can help suppressing a duplicate so that it never shows up at the receiver. That allows the sender to confidently resend if it’s in doubt about success in a prior incarnation of processing the same message.&lt;/P&gt;
&lt;P&gt;Checkpoint: We now also can establish pretty good confidence about initiating forward action or any other action in the system given if the ‘current’ action is following the principles described above.&lt;/P&gt;
&lt;P&gt;So far I’ve talked about individual actions and also about chains of actions, albeit just in the failure case. Obviously the same applies to success cases where you want to do something ‘next’ once you’re done with ‘this’. &lt;/P&gt;
&lt;P&gt;Now let’s assume you want to do multiple things in parallel, like updating multiple stores as part of executing a single job – which gets us back to the distributed transaction scenario discussed earlier. What helps in these cases is if the messaging system supports ‘topics’ that allow dropping a message (the job) into the messaging system once and serve the message to each participant in the composite activity via their own subscription on the topic. Since the messaging system is internally transactional it will guarantee that each message that is successfully submitted will indeed appear on each subscription so it ensures the distribution. With that, the failure handling story for each slice of the composite job turns into the same model that I’ve been explaining above. Each participant can be patient and tenacious when it comes to transient error conditions. In hard failure cases, the forward action can be a notification to the initiator that will then have to decide how to progress forward, including annulling or otherwise invoking forward actions activities that have been executed in parallel. In the aforementioned case of a ticketing failure that means that the ticketing module throws its hands up and the module responsible for booking the travel package either decides to bubble the case to the customer or an operator leaving the remaining reservations intact or to cancel the reservations for the car and the hotel that have been made in parallel. Should two out of three or more participants’ operations fail and each report up to the initiator, the initiator can either keep track of whether it already took corrective forward action on the third participant or, in doubt, the idempotency rule should avoid doing the same thing twice.&lt;/P&gt;
&lt;P&gt;The model described here is loosely based on the notion of ‘Sagas’, which were first described in a 1987 ACM paper by Hector Garcia-Molina and Kenneth Salem, so this isn’t grand news. However, the notion of such Sagas is only now really gaining momentum with long-running and far distributed transactions becoming more commonplace, so it’s well worth to drag the model further out into the limelight and give it coverage. The original paper on Sagas is still assuming that the individual steps can be encapsulated in a regular transaction, which may not even be the case in the cloud and with infrastructures that don’t have inherent transaction support. The role of the messaging system with the capabilities mentioned above is to help compensate for the absence of that support. &lt;/P&gt;
&lt;P&gt;… to be continued …&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=b2e9e279-8ab3-4126-905a-25650c57a468"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10221311" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Architecture/">Architecture</category></item><item><title>Service Bus Relay Load Balancing–The Missing Feature (But Not For Much Longer!)</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/09/20/service-bus-relay-load-balancing-the-missing-feature-but-not-for-much-longer.aspx</link><pubDate>Tue, 20 Sep 2011 14:54:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10214424</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10214424</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/09/20/service-bus-relay-load-balancing-the-missing-feature-but-not-for-much-longer.aspx#comments</comments><description>&lt;P&gt;Load Balancing on the Service Bus Relay is by far our #1 most requested feature now that we’ve got Queues and Topics finally in production. It’s reasonable expectation for us deliver that capability in one of the next production updates and the good news is that we will. I’m not going to promise any concrete ship dates here, but it’d be sorely disappointing if that wouldn’t happen while the calendar still says 2011. &lt;/P&gt;
&lt;P&gt;I just completed writing the functional spec for the feature and it’s worth communicating how the feature will show up, since there is a tiny chance that the behavioral change may affect implementations that rely on a particular exception to drive the strategy of how to perform failover. &lt;/P&gt;
&lt;P&gt;The gist of the Load Balancing spec is that the required changes in your code and config to get load balancing are zero. With either the NetTcpRelayBinding or any of the HTTP bindings (WebHttpRelayBinding, etc) as well as the underlying transport binding elements, you’ll just open up a second (and third and fourth … up to 25) listener on the same name and instead of getting an AddressAlreadyInUseException as you get today, you’ll just get automatic load balancing. When a request for your endpoints shows up at Service Bus, the system will roll the dice on which of the connected listeners to route the request or connection/session to and perform the necessary handshake to make that happen.&lt;/P&gt;
&lt;P&gt;The bottom line is that we’re effectively making the AddressAlreadyInUseException go away for the most part. It’ll still be thrown when the listener’s policy settings don’t match up, i.e. when one listener wants to have Access Control enabled and the other one doesn’t, but otherwise you’ll just won’t see it anymore. &lt;/P&gt;
&lt;P&gt;The only way this way of just lighting up the feature may get anyone in trouble is if your application were to rely on that exception in a situation where you’ve got an active listener on Service Bus on one node and a ‘standby’ listener on another node that keeps trying to open up a listener into the same address to create a hot/warm cluster failover scheme &lt;EM&gt;and&lt;/EM&gt; if the two nodes were tripping over each other if they were getting traffic concurrently. That doesn’t seem too likely. If you have questions about this drop me a line here in the comments, by email to clemensv at microsoft.com or on Twitter @clemensv.&amp;nbsp; &lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=bb1fc000-b441-445b-8909-104bd754f60d"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10214424" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category></item><item><title>Securing Service Bus with the Access Control Service</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/09/19/securing-service-bus-with-the-access-control-service.aspx</link><pubDate>Mon, 19 Sep 2011 10:00:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10213664</guid><dc:creator>clemensv</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10213664</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/09/19/securing-service-bus-with-the-access-control-service.aspx#comments</comments><description>&lt;P&gt;This session explains how to secure Service Bus using the Access Control Service. This is also an extension session for &lt;A href="http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-862T"&gt;my session at BUILD&lt;/A&gt;, but watching the BUILD session is not a strict prerequisite.&lt;/P&gt;&lt;IFRAME style="WIDTH: 512px; HEIGHT: 288px" src="http://channel9.msdn.com/posts/Securing-Service-Bus-with-ACS/player?w=512&amp;amp;h=288" frameBorder=0 scrolling=no&gt;&lt;/IFRAME&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=13a56656-e8f4-4154-8cf9-cf2480536389"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10213664" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category></item><item><title>Service Bus Topics and Queues – Advanced</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/09/18/service-bus-topics-and-queues-advanced.aspx</link><pubDate>Sun, 18 Sep 2011 17:15:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10213253</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10213253</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/09/18/service-bus-topics-and-queues-advanced.aspx#comments</comments><description>&lt;P&gt;This session is a followup to the Service Bus session &lt;A href="http://vasters.com/clemensv/2011/09/16/Building+Looselycoupled+Apps+With+Windows+Azure+Service+Bus+Topics+And+Queues.aspx"&gt;that I did at the build conference&lt;/A&gt; and explains advanced usage patterns:&lt;/P&gt;
&lt;P&gt;&lt;IFRAME style="WIDTH: 512px; HEIGHT: 288px" src="http://channel9.msdn.com/posts/ServiceBusTopicsAndQueues/player?w=512&amp;amp;h=288" frameBorder=0 scrolling=no&gt;&lt;/IFRAME&gt;&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=44c95cba-0951-4f92-96e2-1366b516f72c"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10213253" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category></item><item><title>Building loosely-coupled Apps with Windows Azure Service Bus Topics and Queues</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/09/16/building-loosely-coupled-apps-with-windows-azure-service-bus-topics-and-queues.aspx</link><pubDate>Fri, 16 Sep 2011 05:49:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10212444</guid><dc:creator>clemensv</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10212444</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/09/16/building-loosely-coupled-apps-with-windows-azure-service-bus-topics-and-queues.aspx#comments</comments><description>&lt;P&gt;From //build in Anaheim&lt;/P&gt;&lt;IFRAME style="WIDTH: 960px; HEIGHT: 544px" src="http://channel9.msdn.com/Events/BUILD/BUILD2011/SAC-862T/player?w=960&amp;amp;h=544" frameBorder=0 scrolling=no&gt;&lt;/IFRAME&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=981f28ab-0743-4c34-9130-8811a8d523da"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10212444" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category></item><item><title>Understanding Windows Azure AppFabric Queues (and Topics)</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/06/10/understanding-windows-azure-appfabric-queues-and-topics.aspx</link><pubDate>Fri, 10 Jun 2011 16:29:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10173554</guid><dc:creator>clemensv</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10173554</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/06/10/understanding-windows-azure-appfabric-queues-and-topics.aspx#comments</comments><description>&lt;P&gt;Our team’s Development Manager MK (Murali Krishnaprasad) and me were interviewed by Michael Washam on May 2011 CTP release of Windows Azure AppFabric. We discuss new technologies such as Topics, Queues, Subscriptions and how this relates to doing async development in the cloud.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;IFRAME style="WIDTH: 512px; HEIGHT: 288px" src="http://channel9.msdn.com/Blogs/Server-Side/Understanding-Windows-Azure-AppFabric-Queues/player?w=512&amp;amp;h=288" frameBorder=0 scrolling=no&gt;&lt;/IFRAME&gt;&lt;/P&gt;
&lt;P&gt;Republished from &lt;A href="http://channel9.msdn.com/Blogs/Server-Side/Understanding-Windows-Azure-AppFabric-Queues" target=_blank&gt;Channel 9&lt;/A&gt;&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=d41ef7d0-63cd-42ad-8455-ccfcd40997a6"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10173554" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Service Bus May 2011 CTP Client Bits now on NuGet</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/05/23/service-bus-may-2011-ctp-client-bits-now-on-nuget.aspx</link><pubDate>Mon, 23 May 2011 04:42:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10167314</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10167314</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/05/23/service-bus-may-2011-ctp-client-bits-now-on-nuget.aspx#comments</comments><description>&lt;P&gt;(This post has been written by my coworker Eric Lam who pulled this all together – he wrote it as an email to the team – I’m just ripping that off) &lt;/P&gt;
&lt;P&gt;NuGet (&lt;A href="http://www.nuget.org/"&gt;http://www.nuget.org/&lt;/A&gt;) is an open source package manager for .NET started by Microsoft. For some context there is a &lt;A href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV338" target=_blank&gt;really good TechEd talk here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;To install:&lt;/P&gt;
&lt;P&gt;1. Unless you have it (for instance as a side-effect of installing ASP.NET MVC3), get NuGet installed (it’s an VS extension) &lt;A href="http://visualstudiogallery.msdn.microsoft.com/27077b70-9dad-4c64-adcf-c7cf6bc9970c" target=_blank&gt;from here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;2. Right click on the project you want to add Service bus support to and select “Add Library Package Reference”&lt;/P&gt;
&lt;P&gt;&lt;A href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Service-bus-now-on-NuGet_DB9C/clip_image001_2.jpg"&gt;&lt;IMG style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px" title=clip_image001 border=0 alt=clip_image001 src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Service-bus-now-on-NuGet_DB9C/clip_image001_thumb.jpg" width=244 height=214&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;3. The NuGet manager will show up, and search for “AppFabric”, which will show all our AppFabric packages available right now (note: Cache is there too!)&lt;/P&gt;
&lt;P&gt;&lt;A href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Service-bus-now-on-NuGet_DB9C/clip_image002_2.jpg"&gt;&lt;IMG style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px" title=clip_image002 border=0 alt=clip_image002 src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Service-bus-now-on-NuGet_DB9C/clip_image002_thumb.jpg" width=244 height=132&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;4. Click install, and that’s it! The package do a number of things&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Copy Microsoft.ServiceBus.dll and Microsoft.ServiceBus.Messaging.dll to your local project directories 
&lt;LI&gt;Add the references to your project 
&lt;LI&gt;If you have a App.Config and/or Web.Config, it will add the necessary WCF bindings/extensions for project consumption. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Some things to note for the package:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The packages require the projects to use the .Net 4.0 Full Profile (Client profile doesn’t work). 
&lt;LI&gt;For sample code you will need to install it on a C# Console Application project. 
&lt;LI&gt;This is only available for the CTP right now, not yet for the production SDK. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Let us know if you have any feedback or comments.&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=245eaca1-ec23-4d8e-b9e0-8b0c0e5b438a"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10167314" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Audio clips recorded on the road</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/05/20/audio-clips-recorded-on-the-road.aspx</link><pubDate>Fri, 20 May 2011 12:11:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10166851</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10166851</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/05/20/audio-clips-recorded-on-the-road.aspx#comments</comments><description>&lt;P&gt;I’ve been starting to use &lt;A href="http://www.cinchcast.com/clemensv/"&gt;Cinchcast&lt;/A&gt; to post little audio clips that I record while driving from and to work about things that come up with regards to Service Bus on the forums or on Twitter or elsewhere. The RSS feed is at &lt;A title=http://www.cinchcast.com/clemensv.rss href="http://www.cinchcast.com/clemensv.rss"&gt;http://www.cinchcast.com/clemensv.rss&lt;/A&gt;&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=11723535-12aa-4c51-bd29-6f9cf96f89e0"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10166851" width="1" height="1"&gt;</description></item><item><title>Service Bus May 2011 CTP Resources</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/05/19/service-bus-may-2011-ctp-resources.aspx</link><pubDate>Thu, 19 May 2011 07:33:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10166368</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10166368</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/05/19/service-bus-may-2011-ctp-resources.aspx#comments</comments><description>&lt;P&gt;Here’s a (incomplete) snapshot of what’s out there in terms of material for the new Service Bus CTP:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;First read &lt;A href="http://msdn.microsoft.com/en-us/library/gg278340.aspx" target=_blank&gt;the release notes&lt;/A&gt; where we provide a summary of what’s new and what changed and also point out some areas of caution on parallel installs of the CTP and production SDKs.&amp;nbsp;&amp;nbsp; 
&lt;LI&gt;You can get the SDK bits &lt;A href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=D89640FC-C552-446E-AEAD-B1E0D940F31B" target=_blank&gt;from here&lt;/A&gt;. Get the right set of binaries for your machine (x64 or x86) and the right set of samples (CS or VB) and definitely get the user guide. We will have a NuGet package shortly that will allow you integrating the Service bus assembly and all necessary config incantations straight into your apps without even having the SDK on your machine. 
&lt;LI&gt;The reference docs &lt;A href="http://msdn.microsoft.com/en-us/library/gg278353.aspx" target=_blank&gt;are located here&lt;/A&gt;. This is a CTP and the documentation is likewise in CTP state, so there are some gaps that we try to fill. 
&lt;LI&gt;My &lt;A href="http://blogs.msdn.com/b/appfabric/archive/2011/05/13/introducing-the-windows-azure-appfabric-service-bus-may-2011-ctp.aspx" target=_blank&gt;introduction to the CTP&lt;/A&gt; is on the new AppFabric blog here. 
&lt;LI&gt;At the same location you’ll find &lt;A href="http://blogs.msdn.com/b/appfabric/archive/2011/05/17/an-introduction-to-service-bus-queues.aspx" target=_blank&gt;David Ingham’s primer on Queues&lt;/A&gt;. 
&lt;LI&gt;My TechEd talk on the new features &lt;A href="http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/MID312" target=_blank&gt;is now posted on Channel 9&lt;/A&gt;. 
&lt;LI&gt;We have &lt;A href="http://www.microsoft.com/windowsazure/appfabric/teched/default.aspx" target=_blank&gt;a video series&lt;/A&gt; providing high-level overviews on Service Bus. 
&lt;LI&gt;Neudesic’s Rick Garibay &lt;A href="http://www.rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx" target=_blank&gt;provides a community insider’s perspective&lt;/A&gt; on the new features. Matt Davey also &lt;A href="http://mdavey.wordpress.com/2011/05/19/windows-azure-may-ctp-service-bus-gets-interesting/" target=_blank&gt;likes&lt;/A&gt; what he sees. 
&lt;LI&gt;&lt;A href="http://social.msdn.microsoft.com/Forums/en-US/appfabricctp/" target=_blank&gt;The forums.&lt;/A&gt; Go there for questions or suggestions. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;There’s more on the way. Let me know if you write a blog post about what you find out so I can link to it. &lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=317c8922-8a03-4a0f-9c1d-f26a13dfad89"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10166368" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Introducing the Windows Azure AppFabric Service Bus May 2011 CTP</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/05/16/introducing-the-windows-azure-appfabric-service-bus-may-2011-ctp.aspx</link><pubDate>Mon, 16 May 2011 08:31:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10165007</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10165007</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/05/16/introducing-the-windows-azure-appfabric-service-bus-may-2011-ctp.aspx#comments</comments><description>&lt;P&gt;A lot of partners and customers we talk to are telling us that they think of Service Bus as one of the key differentiators of the Windows Azure platform because it enables customers to build and interconnect applications that reflect the reality of where things stand with regard to moving workloads to cloud infrastructures: Today and for years to come, applications and solutions will straddle desktop and devices, customer-owned and operated servers and datacenters, and private and public cloud assets. &lt;/P&gt;
&lt;P&gt;After a decade and more of application integration and process streamlining, no line-of-business application is and should ever again be an island. &lt;/P&gt;
&lt;P&gt;If applications move to the cloud or if cloud-based SaaS solutions are to be integrated into enterprise solutions for individual customers, integration invariably requires capabilities like seamless access to services and secure, reliable message flow across network and trust boundaries. Also, as more and more applications are federated across trust boundaries and are built to work for multiple tenants, classic network federation technologies such as VPNs are often no longer adequate since they require a significant degree of mutual trust between parties as they permit arbitrary network traffic flow that needs to be managed.&lt;/P&gt;
&lt;P&gt;We just released a new Community Technology Preview that shows that we’re hard at work and committed to expand Service Bus into a universal connectivity, messaging, and integration fabric for cloud-hosted and cloud-connected applications – and we invite you to take a look at our &lt;A href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=D89640FC-C552-446E-AEAD-B1E0D940F31B"&gt;Windows Azure AppFabric SDK V2.0 CTP – May Update&lt;/A&gt; and accompanying samples. &lt;/P&gt;
&lt;P&gt;Service Bus is already unique amongst platform-as-a-service offerings in providing a rich services relay capability that allows for global endpoint federation across network and trust boundaries. &lt;/P&gt;
&lt;P&gt;As of today, we’re adding a brand-new set of cloud-based, message-oriented-middleware technologies to Service Bus that provide reliable message queuing and durable publish/subscribe messaging both over a simple and broadly interoperable REST-style HTTPS protocol with long-polling support and a throughput-optimized, connection-oriented, duplex TCP protocol. &lt;/P&gt;
&lt;P&gt;The new messaging features, built by the same team that owns the MSMQ technology, but on top of a completely new technology foundation, are (of course) integrated with Service Bus’s naming and discovery capabilities and the familiar management protocol surface and allow federated access control via the latest release of the Windows Azure AppFabric Access Control service. &lt;/P&gt;
&lt;H4&gt;Queues&lt;/H4&gt;
&lt;P&gt;Service Bus Queues are based on a new messaging infrastructure backed by a replicated, durable store. &lt;/P&gt;
&lt;P&gt;Each queue can hold up to 100MB of message content in this CTP, which is a quota we expect to expand by at least an order of magnitude as the service goes into production. Messages can have user-defined time-to-live periods with no enforced maximum lifetime.&lt;/P&gt;
&lt;P&gt;The size of any individual message is limited to 256KB, but the session feature allows creating unlimited-size sequences of related messages whereby sessions are pinned to particular consumers and therefore enabling chunking of payloads of arbitrary sizes. The session state facility furthermore allows transactional recording of the progress a process makes as it consumes messages from a session and we also support session-based correlation, meaning that you can build multiplexed request/reply paths in a straightforward fashion. &lt;/P&gt;
&lt;P&gt;Queues support reliable delivery patterns such as Peek/Lock both on the HTTP API and the .NET API that help ensuring processing integrity across trust boundaries where common mechanisms like distributed 2-phase transactions are challenging. Along with that, we have built-in detection of inbound message duplicates, allowing clients to re-send messages without adverse consequences if they’re ever in doubt whether a message has been logged in the queue due to intermittent network issues or an application crash.&lt;/P&gt;
&lt;P&gt;In addition to a dead-letter facility for messages that cannot be processed or expire, Queues also allow deferring messages for later processing, for instance when messages are received out of the scheduled processing order and need to be safely put on the side while the process waits for a particular message to permit further progress.&lt;/P&gt;
&lt;P&gt;Queues also support scheduled delivery – which means that you can hand a message to the queue infrastructure, but the message will only become available at a predetermined point in time, which is a very elegant way to build simple timers. &lt;/P&gt;
&lt;H4&gt;Topics&lt;/H4&gt;
&lt;P&gt;Service Bus Topics provide a set of new publish-and-subscribe capabilities and are based on the same backend infrastructure as Service Bus Queues – and have all the features I just outlined for Queues. &lt;/P&gt;
&lt;P&gt;A Topic consists of a sequential message store just like a Queue, but allows for many (up to 2000 for the CTP) concurrent and durable Subscriptions that can independently yield copies of the published messages to consumers. &lt;/P&gt;
&lt;P&gt;Each Subscription can define a set of rules with simple expressions that specify which messages from the published sequence are selected into the Subscription; a Subscription can select all messages or only messages whose user-or system defined properties have certain values or lie within certain value ranges. Rules can also include Actions, which allow modifying message properties as messages get selected; this allows, for instance, selecting messages by certain criteria and affinitizing those messages with sessions or to stamp messages with partitioning keys, amongst many other possible patterns. &lt;/P&gt;
&lt;P&gt;The filtered message sequence represented by each Subscription functions like a virtual Queue, with all the features of Queues mentioned earlier. Thus, a Subscription may have a single consumer that gets all messages or a set of competing consumers that fetch messages on a first-come-first-served basis. &lt;/P&gt;
&lt;P&gt;To name just a few examples, Topics are ideal for decoupled message fan-out to many consumers requiring the same information, can help with distribute work across partitioned pools of workers, and are a great foundation for event-driven architecture implementations. &lt;/P&gt;
&lt;P&gt;Topics can always be used just like Queues by setting set up a single, unfiltered subscription and having multiple competing consumers pull messages from the subscription. The great advantage of Topics over Queues is that additional subscriptions can be added at any time to allow for additional taps on the message sequence for any purpose; audit taps that log pre-processing input messages into archives are a great example here. &lt;/P&gt;
&lt;H4&gt;Access Control Integration&lt;/H4&gt;
&lt;P&gt;This new CTP federates with the appfabriclabs.com version of the Access Control service, which is compatible with the Access Control “V2” service that is in available commercially since April. The current commercially available version of Service Bus federates with Access Control “V1”. &lt;/P&gt;
&lt;P&gt;The Service Bus API to interact with Access Control for acquiring access tokens has not changed, but we are considering changes to better leverage the new federation capabilities of Access Control “V2”. &lt;/P&gt;
&lt;P&gt;Customers who are setting up access control rules for Service Bus programmatically will find that there are significant differences between the management APIs of these two versions of the Access Control service. The current plan is to provide a staged migration for customers with custom access control rules on their Service Bus namespaces; migration will be an option for some period of time when we will operate the V1 and V2 versions of the Access Control Service side-by-side. We will publish concrete guidance for this migration over the next several months with initial details coming this week here on this blog.&lt;/P&gt;
&lt;H4&gt;What Changed and What’s Coming?&lt;/H4&gt;
&lt;P&gt;We believe that providing these capabilities in the cloud – paired with the features we already have available in Service Bus – will open up a whole new range of possibilities for cloud-hosted and cloud-enhanced applications. We have seen amazing business solutions built on Service Bus and based on customer feedback we’re convinced that the addition of a fully featured set of message-oriented middleware capabilities will enable even more powerful solutions to be built. Our intention is to make all capabilities contained in this preview commercially available in the second half of 2011.&lt;/P&gt;
&lt;P&gt;The load balancing and traffic optimization features for the Relay capability of Service Bus that were added in the PDC’10 CTP of Service Bus have been postponed and are no longer available in this CTP. However, “postponed” does not mean “removed” and we are planning on getting these features back into a CTP release soon. We’ve traded these features for capabilities that we expect will be even more important for many customers: Full backwards compatibility between the current production release of Service Bus and the new version we’re presenting in this CTP, even though we have changed a very significant portion of the Service Bus backend. We are committed to provide full backwards compatibility for Service Bus when the capabilities of this CTP go into production, including backwards compatibility with the Microsoft.ServiceBus.dll that you already have deployed.&lt;/P&gt;
&lt;P&gt;To help customers writing apps on platforms other than .NET we will also release Java and PHP samples for the new messaging capabilities in the next few weeks. These samples will be versions of the chat client implemented in the Silverlight and Windows Phone chat samples included in the SDK for this CTP release. &lt;/P&gt;
&lt;P&gt;Lastly, and most importantly, the purpose of a Community Technology Preview is to collect feedback from the community. If you have suggestions, critique, praise, or questions, please let us know at &lt;A href="http://social.msdn.microsoft.com/Forums/en-US/appfabricctp/"&gt;http://social.msdn.microsoft.com/Forums/en-US/appfabricctp/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;You can also Twitter me personally at @clemensv and I’ll let the team know what you have to say.&lt;/P&gt;
&lt;P&gt;For the Service Bus Team,&lt;/P&gt;
&lt;P&gt;Clemens Vasters &lt;BR&gt;Principal Technical Lead &lt;BR&gt;Windows Azure AppFabric Service Bus&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=d1f62d44-d9e0-4717-8aba-73ca1f29c5f9"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10165007" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/App+Fabric/">App Fabric</category></item><item><title>A Bit Of Service Bus NetTcpRelayBinding Latency Math</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/05/12/a-bit-of-service-bus-nettcprelaybinding-latency-math.aspx</link><pubDate>Thu, 12 May 2011 05:50:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10163814</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10163814</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/05/12/a-bit-of-service-bus-nettcprelaybinding-latency-math.aspx#comments</comments><description>&lt;P&gt;&lt;A name=_MailOriginal&gt;&lt;B&gt;From:&lt;/B&gt;&lt;/A&gt; John Doe&amp;nbsp; &lt;BR&gt;&lt;B&gt;Sent:&lt;/B&gt; Thursday, May 12, 2011 3:10 AM &lt;BR&gt;&lt;B&gt;To:&lt;/B&gt; Clemens Vasters &lt;BR&gt;&lt;B&gt;Subject:&lt;/B&gt; What is the average network latency for the AppFabric Service Bus scenario? &lt;BR&gt;&lt;B&gt;Importance:&lt;/B&gt; High &lt;/P&gt;
&lt;P&gt;Hi Clemens, &lt;/P&gt;
&lt;P&gt;A rough ballpark range in milliseconds per call will do. This is a very important metric for us to understand performance overhead. &lt;/P&gt;
&lt;P&gt;Thanks, &lt;BR&gt;John&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;&lt;B&gt;From:&lt;/B&gt; Clemens Vasters &lt;BR&gt;&lt;B&gt;Sent:&lt;/B&gt; Thursday, May 12, 2011 7:47 AM &lt;BR&gt;&lt;B&gt;To:&lt;/B&gt; John Doe &lt;BR&gt;&lt;B&gt;Subject:&lt;/B&gt; RE: What is the average network latency for the AppFabric Service Bus scenario?&lt;/P&gt;
&lt;P&gt;Hi John,&lt;/P&gt;
&lt;P&gt;Service Bus latency depends mostly on network latency. The better you handle your connections, the lower the latency will be. &lt;/P&gt;
&lt;P&gt;Let’s assume you have a client and a server, both on-premise somewhere. The server is 100ms avg roundtrip packet latency from the chosen Azure datacenter and the client is 70ms avg roundtrip packet latency from the chosen datacenter. Packet loss also matters because it gates your throughput, which further impacts payload latency. Since we’re sitting on a ton of dependencies it’s also worth telling that a ‘cold start’ with JIT impact is different from a ‘warm start’.&lt;/P&gt;
&lt;P&gt;With that, I’ll discuss NetTcpRelayBinding:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;There’s an existing listener on the service. The service has a persistent connection (control channel) into the relay that’s being kept alive under the covers. 
&lt;LI&gt;The client connects to the relay to create a connection. The initial connection handshake (2) and TLS handshake (3) take about 5 roundtrips or 5*70ms = 350ms. With that you have a client socket. 
&lt;LI&gt;Service Bus then relays the client’s desire to connect to the service down the control channel. That’s one roundtrip, or 100ms in our example; add 50ms for our internal lookups and routing. 
&lt;LI&gt;The service then sets up a rendezvous socket with Service Bus at the machine where the client socket awaits connection. That’s just like case 2 and thus 5*100ms=500ms in our case. Now you have an end-to-end socket. 
&lt;LI&gt;Having done that, we’re starting to pump the .NET Framing protocol between the two sites. The client is thus theoretically going to get its first answer after a further 135ms. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;So the handshake takes a total of 1135ms in the example above. That’s excluding all client and service side processing and is obviously a theoretical number based on the latencies I picked here. You mileage can and will vary and the numbers I have here are the floor rather than the ceiling of relay handshake latency.&lt;/P&gt;
&lt;P&gt;Important: Once you have a connection set up and are holding on to a channel all subsequent messages are impacted almost exclusively by the composite roundtrip network latency of 170ms with very minimal latency added by our pumps. So you want to make a channel and keep that alive as long as you can.&lt;/P&gt;
&lt;P&gt;If you use the Hybrid mode for NetTcpRelayBinding and the algorithm succeeds establishing the direct socket, further traffic roundtrip time can be reduced to the common roundtrip latency between the two sites as the relay gets out of the way completely. However, the session setup time will always be there and the Hybrid handshake (which follows establishing a session and happens in parallel) may very well up to 10 seconds until the direct socket is available.&lt;/P&gt;
&lt;P&gt;For HTTP the story is similar, with the client side socket (not the request; we’re routing the keepalive socket) with overlaid SSL/TLS triggering the rendezvous handshake.&lt;/P&gt;
&lt;P&gt;I hope that helps, &lt;BR&gt;Clemens&lt;/P&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=c943fb86-631c-4ee8-9ad9-fce6938d27a6"&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10163814" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Reading ATAPI SMART Data from Drives using .NET; Temperature Anyone?</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/04/11/reading-atapi-smart-data-from-drives-using-net-temperature-anyone.aspx</link><pubDate>Mon, 11 Apr 2011 07:21:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10152131</guid><dc:creator>clemensv</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10152131</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/04/11/reading-atapi-smart-data-from-drives-using-net-temperature-anyone.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN: 0px 0px 0px 6px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: right; BORDER-TOP: 0px; BORDER-RIGHT: 0px; PADDING-TOP: 0px" title=image border=0 alt=image align=right src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/Reading-ATAPI-SMART-Data-from-Drives.NET_7851/image_thumb.png" width=502 height=319 /&gt;&lt;/a&gt;I’ll admit this is an odd topic for me to write about since my job pretty far away from that part of the world, but our PM team at MS is building a set of demos for which we need some semi-random and fun input data that doesn’t change all that rapidly. So we thought that reading the temperature off hard drives would be a nice input. But how to get at it? &lt;/p&gt;
&lt;p&gt;The solution is to use the WMI interface for ATAPI to get at the SMART data. Binging the subject you’ll find a ton of little snippets that have one thing in common: ‘magic’. Somehow, you get at the ‘VendorSpecific’ structure of the SMART data using WMI and then you believe that byte number 115 is the one that holds the temperature. Of course that’s not what someone who’s doing protocol in their day-job would ever settle for. So I’ve been digging around a little and found a &lt;a href="http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf" target=_blank&gt;description of the structure&lt;/a&gt; and grabbed the &lt;a href="http://en.wikipedia.org/wiki/S.M.A.R.T." target=_blank&gt;attribute value list&lt;/a&gt; from Wikipedia, shook it all up a little and out came the little program below.&lt;/p&gt;
&lt;p&gt;The app grabs the vendor specific array from the ATAPI data, shreds it into a set of structures, and dumps it out. Code here, zip file at the bottom.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt;// (c) Microsoft Corporation&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=rem&gt;// Author: Clemens Vasters (clemensv@microsoft.com)&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt;// Code subject to MS-PL: http://opensource.org/licenses/ms-pl.html &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class=rem&gt;// SMART Attributes and Background: http://en.wikipedia.org/wiki/S.M.A.R.T.&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt;// SMART Attributes Overview: http://www.t13.org/Documents/UploadedDocuments/docs2005/e05171r0-ACS-SMARTAttributes_Overview.pdf&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;namespace&lt;/span&gt; SmartDataApp&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Management;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; System.Runtime.InteropServices;&lt;/pre&gt;&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;enum&lt;/span&gt; SmartAttributeType : &lt;span class=kwrd&gt;byte&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;    {&lt;/pre&gt;&lt;pre&gt;        ReadErrorRate = 0x01,&lt;/pre&gt;&lt;pre class=alt&gt;        ThroughputPerformance = 0x02,&lt;/pre&gt;&lt;pre&gt;        SpinUpTime = 0x03,&lt;/pre&gt;&lt;pre class=alt&gt;        StartStopCount = 0x04,&lt;/pre&gt;&lt;pre&gt;        ReallocatedSectorsCount = 0x05,&lt;/pre&gt;&lt;pre class=alt&gt;        ReadChannelMargin = 0x06,&lt;/pre&gt;&lt;pre&gt;        SeekErrorRate = 0x07,&lt;/pre&gt;&lt;pre class=alt&gt;        SeekTimePerformance = 0x08,&lt;/pre&gt;&lt;pre&gt;        PowerOnHoursPOH = 0x09,&lt;/pre&gt;&lt;pre class=alt&gt;        SpinRetryCount = 0x0A,&lt;/pre&gt;&lt;pre&gt;        CalibrationRetryCount = 0x0B,&lt;/pre&gt;&lt;pre class=alt&gt;        PowerCycleCount = 0x0C,&lt;/pre&gt;&lt;pre&gt;        SoftReadErrorRate = 0x0D,&lt;/pre&gt;&lt;pre class=alt&gt;        SATADownshiftErrorCount = 0xB7,&lt;/pre&gt;&lt;pre&gt;        EndtoEnderror = 0xB8,&lt;/pre&gt;&lt;pre class=alt&gt;        HeadStability = 0xB9,&lt;/pre&gt;&lt;pre&gt;        InducedOpVibrationDetection = 0xBA,&lt;/pre&gt;&lt;pre class=alt&gt;        ReportedUncorrectableErrors = 0xBB,&lt;/pre&gt;&lt;pre&gt;        CommandTimeout = 0xBC,&lt;/pre&gt;&lt;pre class=alt&gt;        HighFlyWrites = 0xBD,&lt;/pre&gt;&lt;pre&gt;        AirflowTemperatureWDC = 0xBE,&lt;/pre&gt;&lt;pre class=alt&gt;        TemperatureDifferencefrom100 = 0xBE,&lt;/pre&gt;&lt;pre&gt;        GSenseErrorRate = 0xBF,&lt;/pre&gt;&lt;pre class=alt&gt;        PoweroffRetractCount = 0xC0,&lt;/pre&gt;&lt;pre&gt;        LoadCycleCount = 0xC1,&lt;/pre&gt;&lt;pre class=alt&gt;        Temperature = 0xC2,&lt;/pre&gt;&lt;pre&gt;        HardwareECCRecovered = 0xC3,&lt;/pre&gt;&lt;pre class=alt&gt;        ReallocationEventCount = 0xC4,&lt;/pre&gt;&lt;pre&gt;        CurrentPendingSectorCount = 0xC5,&lt;/pre&gt;&lt;pre class=alt&gt;        UncorrectableSectorCount = 0xC6,&lt;/pre&gt;&lt;pre&gt;        UltraDMACRCErrorCount = 0xC7,&lt;/pre&gt;&lt;pre class=alt&gt;        MultiZoneErrorRate = 0xC8,&lt;/pre&gt;&lt;pre&gt;        WriteErrorRateFujitsu = 0xC8,&lt;/pre&gt;&lt;pre class=alt&gt;        OffTrackSoftReadErrorRate = 0xC9,&lt;/pre&gt;&lt;pre&gt;        DataAddressMarkerrors = 0xCA,&lt;/pre&gt;&lt;pre class=alt&gt;        RunOutCancel = 0xCB,&lt;/pre&gt;&lt;pre&gt;        SoftECCCorrection = 0xCC,&lt;/pre&gt;&lt;pre class=alt&gt;        ThermalAsperityRateTAR = 0xCD,&lt;/pre&gt;&lt;pre&gt;        FlyingHeight = 0xCE,&lt;/pre&gt;&lt;pre class=alt&gt;        SpinHighCurrent = 0xCF,&lt;/pre&gt;&lt;pre&gt;        SpinBuzz = 0xD0,&lt;/pre&gt;&lt;pre class=alt&gt;        OfflineSeekPerformance = 0xD1,&lt;/pre&gt;&lt;pre&gt;        VibrationDuringWrite = 0xD3,&lt;/pre&gt;&lt;pre class=alt&gt;        ShockDuringWrite = 0xD4,&lt;/pre&gt;&lt;pre&gt;        DiskShift = 0xDC,&lt;/pre&gt;&lt;pre class=alt&gt;        GSenseErrorRateAlt = 0xDD,&lt;/pre&gt;&lt;pre&gt;        LoadedHours = 0xDE,&lt;/pre&gt;&lt;pre class=alt&gt;        LoadUnloadRetryCount = 0xDF,&lt;/pre&gt;&lt;pre&gt;        LoadFriction = 0xE0,&lt;/pre&gt;&lt;pre class=alt&gt;        LoadUnloadCycleCount = 0xE1,&lt;/pre&gt;&lt;pre&gt;        LoadInTime = 0xE2,&lt;/pre&gt;&lt;pre class=alt&gt;        TorqueAmplificationCount = 0xE3,&lt;/pre&gt;&lt;pre&gt;        PowerOffRetractCycle = 0xE4,&lt;/pre&gt;&lt;pre class=alt&gt;        GMRHeadAmplitude = 0xE6,&lt;/pre&gt;&lt;pre&gt;        DriveTemperature = 0xE7,&lt;/pre&gt;&lt;pre class=alt&gt;        HeadFlyingHours = 0xF0,&lt;/pre&gt;&lt;pre&gt;        TransferErrorRateFujitsu = 0xF0,&lt;/pre&gt;&lt;pre class=alt&gt;        TotalLBAsWritten = 0xF1,&lt;/pre&gt;&lt;pre&gt;        TotalLBAsRead = 0xF2,&lt;/pre&gt;&lt;pre class=alt&gt;        ReadErrorRetryRate = 0xFA,&lt;/pre&gt;&lt;pre&gt;        FreeFallProtection = 0xFE,&lt;/pre&gt;&lt;pre class=alt&gt;    }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;class&lt;/span&gt; SmartData&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;readonly&lt;/span&gt; Dictionary&amp;lt;SmartAttributeType, SmartAttribute&amp;gt; attributes;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; structureVersion;&lt;/pre&gt;&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartData(&lt;span class=kwrd&gt;byte&lt;/span&gt;[] arrVendorSpecific)&lt;/pre&gt;&lt;pre class=alt&gt;        {&lt;/pre&gt;&lt;pre&gt;            attributes = &lt;span class=kwrd&gt;new&lt;/span&gt; Dictionary&amp;lt;SmartAttributeType, SmartAttribute&amp;gt;();&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;for&lt;/span&gt; (&lt;span class=kwrd&gt;int&lt;/span&gt; offset = 2; offset &amp;lt; arrVendorSpecific.Length; )&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                var a = FromBytes&amp;lt;SmartAttribute&amp;gt;(arrVendorSpecific, &lt;span class=kwrd&gt;ref&lt;/span&gt; offset, 12);&lt;/pre&gt;&lt;pre&gt;                &lt;span class=rem&gt;// Attribute values 0x00, 0xfe, 0xff are invalid&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;if&lt;/span&gt; (a.AttributeType != 0x00 &amp;amp;&amp;amp; (&lt;span class=kwrd&gt;byte&lt;/span&gt;)a.AttributeType != 0xfe &amp;amp;&amp;amp; (&lt;span class=kwrd&gt;byte&lt;/span&gt;)a.AttributeType != 0xff)&lt;/pre&gt;&lt;pre&gt;                {&lt;/pre&gt;&lt;pre class=alt&gt;                    attributes[a.AttributeType] = a;&lt;/pre&gt;&lt;pre&gt;                }&lt;/pre&gt;&lt;pre class=alt&gt;            }&lt;/pre&gt;&lt;pre&gt;            structureVersion = (&lt;span class=kwrd&gt;ushort&lt;/span&gt;)(arrVendorSpecific[0] * 256 + arrVendorSpecific[1]);&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; StructureVersion&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            get&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.structureVersion;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartAttribute &lt;span class=kwrd&gt;this&lt;/span&gt;[SmartAttributeType v]&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            get&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.attributes[v];&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; IEnumerable&amp;lt;SmartAttribute&amp;gt; Attributes&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            get&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.attributes.Values;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;static&lt;/span&gt; T FromBytes&amp;lt;T&amp;gt;(&lt;span class=kwrd&gt;byte&lt;/span&gt;[] bytearray, &lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;int&lt;/span&gt; offset, &lt;span class=kwrd&gt;int&lt;/span&gt; count)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            IntPtr ptr = IntPtr.Zero;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                ptr = Marshal.AllocHGlobal(count);&lt;/pre&gt;&lt;pre&gt;                Marshal.Copy(bytearray, offset, ptr, count);&lt;/pre&gt;&lt;pre class=alt&gt;                offset += count;&lt;/pre&gt;&lt;pre&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (T)Marshal.PtrToStructure(ptr, &lt;span class=kwrd&gt;typeof&lt;/span&gt;(T));&lt;/pre&gt;&lt;pre class=alt&gt;            }&lt;/pre&gt;&lt;pre&gt;            &lt;span class=kwrd&gt;finally&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;            {&lt;/pre&gt;&lt;pre&gt;                &lt;span class=kwrd&gt;if&lt;/span&gt; (ptr != IntPtr.Zero)&lt;/pre&gt;&lt;pre class=alt&gt;                {&lt;/pre&gt;&lt;pre&gt;                    Marshal.FreeHGlobal(ptr);&lt;/pre&gt;&lt;pre class=alt&gt;                }&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    [StructLayout(LayoutKind.Sequential)]&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;struct&lt;/span&gt; SmartAttribute&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; SmartAttributeType AttributeType;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;ushort&lt;/span&gt; Flags;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;byte&lt;/span&gt; Value;&lt;/pre&gt;&lt;pre&gt;        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;byte&lt;/span&gt;[] VendorData;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; Advisory&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            get&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x1) == 0x0; &lt;span class=rem&gt;// Bit 0 unset?&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; FailureImminent&lt;/pre&gt;&lt;pre class=alt&gt;        {&lt;/pre&gt;&lt;pre&gt;            get&lt;/pre&gt;&lt;pre class=alt&gt;            {&lt;/pre&gt;&lt;pre&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x1) == 0x1; &lt;span class=rem&gt;// Bit 0 set?&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;            }&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;bool&lt;/span&gt; OnlineDataCollection&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            get&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;return&lt;/span&gt; (Flags &amp;amp; 0x2) == 0x2; &lt;span class=rem&gt;// Bit 0 set?&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;class&lt;/span&gt; Program&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;public&lt;/span&gt; &lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; Main()&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                var searcher = &lt;span class=kwrd&gt;new&lt;/span&gt; ManagementObjectSearcher(&lt;span class=str&gt;"root\\WMI"&lt;/span&gt;, &lt;span class=str&gt;"SELECT * FROM MSStorageDriver_ATAPISmartData"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;                &lt;span class=kwrd&gt;foreach&lt;/span&gt; (ManagementObject queryObj &lt;span class=kwrd&gt;in&lt;/span&gt; searcher.Get())&lt;/pre&gt;&lt;pre&gt;                {&lt;/pre&gt;&lt;pre class=alt&gt;                    Console.WriteLine(&lt;span class=str&gt;"-----------------------------------"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                    Console.WriteLine(&lt;span class=str&gt;"MSStorageDriver_ATAPISmartData instance"&lt;/span&gt;);&lt;/pre&gt;&lt;pre class=alt&gt;                    Console.WriteLine(&lt;span class=str&gt;"-----------------------------------"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;                    var arrVendorSpecific = (&lt;span class=kwrd&gt;byte&lt;/span&gt;[])queryObj.GetPropertyValue(&lt;span class=str&gt;"VendorSpecific"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;                    &lt;span class=rem&gt;// Create SMART data from 'vendor specific' array&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    var d = &lt;span class=kwrd&gt;new&lt;/span&gt; SmartData(arrVendorSpecific);&lt;/pre&gt;&lt;pre class=alt&gt;                    &lt;span class=kwrd&gt;foreach&lt;/span&gt; (var b &lt;span class=kwrd&gt;in&lt;/span&gt; d.Attributes)&lt;/pre&gt;&lt;pre&gt;                    {&lt;/pre&gt;&lt;pre class=alt&gt;                        Console.Write(&lt;span class=str&gt;"{0} :{1} : "&lt;/span&gt;, b.AttributeType, b.Value);&lt;/pre&gt;&lt;pre&gt;                        &lt;span class=kwrd&gt;foreach&lt;/span&gt; (&lt;span class=kwrd&gt;byte&lt;/span&gt; vendorByte &lt;span class=kwrd&gt;in&lt;/span&gt; b.VendorData)&lt;/pre&gt;&lt;pre class=alt&gt;                        {&lt;/pre&gt;&lt;pre&gt;                            Console.Write(&lt;span class=str&gt;"{0:x} "&lt;/span&gt;, vendorByte);&lt;/pre&gt;&lt;pre class=alt&gt;                        }&lt;/pre&gt;&lt;pre&gt;                        Console.WriteLine();&lt;/pre&gt;&lt;pre class=alt&gt;                    }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;                }&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;catch&lt;/span&gt; (ManagementException e)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class=alt&gt;                Console.WriteLine(&lt;span class=str&gt;"An error occurred while querying for WMI data: "&lt;/span&gt; + e.Message);&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class=alt&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/SmartDataProgram.zip"&gt;SmartDataProgram.zip (2.25 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=30d7ab71-6985-4917-bb70-665970a49738" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10152131" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/SMART/">SMART</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Code/">Code</category></item><item><title>What I do at work – Cloud and Service Bus for Normal People</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/03/18/what-i-do-at-work-cloud-and-service-bus-for-normal-people.aspx</link><pubDate>Fri, 18 Mar 2011 21:06:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10143346</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10143346</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/03/18/what-i-do-at-work-cloud-and-service-bus-for-normal-people.aspx#comments</comments><description>&lt;iframe title="YouTube video player" height="390" src="http://www.youtube.com/embed/EqDKRCucIL8" frameborder="0" width="640" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=d2926b39-5935-449b-927a-2a2421c1aaeb" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10143346" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Cloud/">Cloud</category></item><item><title>Why would anyone ever use a (Message) Queue?</title><link>http://blogs.msdn.com/b/clemensv/archive/2011/03/18/why-would-anyone-ever-use-a-message-queue.aspx</link><pubDate>Fri, 18 Mar 2011 21:04:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10143347</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10143347</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2011/03/18/why-would-anyone-ever-use-a-message-queue.aspx#comments</comments><description>&lt;p&gt;For programmers writing distributed systems and are not using queues in them just yet. If you are a message-oriented middleware veteran - move along ;-)&lt;/p&gt;  &lt;object width="400" height="224" &gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="movie" value="http://www.facebook.com/v/10150174116899187" /&gt;&lt;embed src="http://www.facebook.com/v/10150174116899187" type="application/x-shockwave-flash" allowfullscreen="true" width="400" height="224"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=b44ee538-4b3d-4d20-a265-9ec7d7b2c7f3" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10143347" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Service+Bus/">Service Bus</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Queues/">Queues</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/MSMQ/">MSMQ</category></item><item><title>Windows Azure AppFabric October 2010 CTP - Service Bus Samples from my PDC Talk (Part 1)</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/11/03/windows-azure-appfabric-october-2010-ctp-service-bus-samples-from-my-pdc-talk-part-1.aspx</link><pubDate>Wed, 03 Nov 2010 07:05:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10085481</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10085481</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/11/03/windows-azure-appfabric-october-2010-ctp-service-bus-samples-from-my-pdc-talk-part-1.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://player.microsoftpdc.com/Session/1f7d009e-29cb-4a15-a1bf-91ffd115c54d"&gt;In my PDC talk&lt;/a&gt; I’m showing a few little samples that are not in &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d89640fc-c552-446e-aead-b1e0d940f31b"&gt;the SDK for the CTP release&lt;/a&gt;.&amp;nbsp; I’ve bundled them up and they’re attached to this post. &lt;/p&gt;
&lt;p&gt;The solution contains three samples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SBMT &lt;/strong&gt;is the ‘Service Bus Management Tool’, a small command line utility to create/view/delete ConnectionPoints and MessageBuffers using the new management model for Service Bus. I’ll explain the options of the tool below and will drill into the inner workings of the tool and the ideas behind the new management interface in the next post of this series. 
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;EchoService/EchoClient &lt;/strong&gt;are versions of the meanwhile probably familiar ‘Echo’ sample for Service Bus that illustrates the new load balancing capability with session affinity. 
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;DurableMessageBufferSample&lt;/strong&gt; is a variation of the SDK sample for the new durable message buffer that sends a sequence of 200 messages and fetches them back. &lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;The SBMT project/tool is the probably most interesting one, because we’re looking to change the way how connection points are managed on Service Bus and that requires a tiny bit of tooling. &lt;/p&gt;
&lt;p&gt;In the current version of Service Bus, creating a listener is an implicit operation. The service (listener) picks a name (or address) in the namespace, binds that name to an endpoint, and opens the ServiceHost holding the endpoint. That’s extremely convenient, but what we’ve found is that this kind of implicit management makes it hard for us to create consistent behavior for eventing (NetEventRelayBinding) and for one of our most-requested ‘missing’ features, which is load balancing and/or failover. For eventing, the majority of customers that we’ve heard feedback from is expecting the the fabric will absorb sent events with no error message even if no event subscribers are present. For the new load balancing capability we’d like to appropriately return an error message in the case that no listener is connected, but differentiate that from the case where the connection point isn’t known, at all.&lt;/p&gt;
&lt;p&gt;The implicit model causes no connection point to exist when there are no listeners, so we can’t solve either of these puzzles without making a change. The good thing is that we’ve got a model that works quite well and we’re building on that: Our message buffers already need to be created using an explicit AtomPub operation on the namespace, so what we’re doing is to make connection points explicit by requiring that you create them beforehand just as you create message buffers. We believe that’s the right model long-term, especially also because the &amp;lt;MessageBuffer/&amp;gt; and &amp;lt;ConnectionPoint/&amp;gt; descriptions are going to have more siblings over time and we’d like to have a consistent model. If you take a deeper look at the slides for the PDC talk, you can already infer a few of the siblings.&lt;/p&gt;
&lt;p&gt;In the talk I also give a few reasons for why we’re splitting off the management and runtime namespaces as we’re doing this. It turns out that our longer term plans for how to enable rich monitoring and control for connection points and message buffers and other messaging artifacts on Service Bus will require quite a bit space in terms of protocol surface and that’s difficult to create in a single namespace. If I have a connection point at &lt;strong&gt;sb://clemens.servicebus.appfabriclabs.com/foo&lt;/strong&gt;, any right-side extensions of that URI belong to the listener. If we were&amp;nbsp; now looking to give you a protocol surface to enumerate the current sessions that are active and suspend/terminate the individually or summarily, for instance, it’s difficult to get that slotted into the same place without resorting to stunts like special escape characters in URIs. Instead, we’d like to provide a straightforward mechanism where you can get at the session connection with &lt;strong&gt;https://clemens-mgmt.servicebus.appfabriclabs.com/Resources/ConnectionPoints(foo)/Sessions/.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If that begs the question how those two addresses are related – I explain it in the talk. The resource has a projection into the runtime namespace. Resources are organized by their type (there will be other taxonomy pivots in the future) and you can project them into the runtime address space as you see it fit. &lt;/p&gt;
&lt;p&gt;The SBMT tool allows interacting with the management namespace to create connection points and message buffers. The call structure is:&lt;/p&gt;
&lt;p&gt;sbmt.exe –n &amp;lt;namespace&amp;gt; –a &amp;lt;account-name&amp;gt;–s &amp;lt;account-secret&amp;gt; &amp;lt;type&amp;gt; &amp;lt;command&amp;gt; &amp;lt;resource-name&amp;gt; &amp;lt;uri&amp;gt; [&amp;lt;args&amp;gt; ..]&amp;lt;/&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;-n &amp;lt;namespace&amp;gt;&amp;nbsp; - the Service Bus namespace created via &lt;a href="http://portal.appfabriclabs.com"&gt;http://portal.appfabriclabs.com&lt;/a&gt; 
&lt;/li&gt;&lt;li&gt;-a &amp;lt;account-name&amp;gt;– the service account name that’s set up in Access Control (defaults to ‘owner’) 
&lt;/li&gt;&lt;li&gt;-s &amp;lt;account-secret&amp;gt;– the service account key set up in Access Control (the key you find on the portal) 
&lt;/li&gt;&lt;li&gt;&amp;lt;type&amp;gt;– ‘cp’ for connection points, ‘mb’ for message buffers 
&lt;/li&gt;&lt;li&gt;&amp;lt;command&amp;gt;– ‘create’, ‘get’, or ‘delete’ (see below) 
&lt;/li&gt;&lt;li&gt;&amp;lt;resource-name&amp;gt;– a unique, friendly name for the resource (eg. ‘crm-leads’) 
&lt;/li&gt;&lt;li&gt;&amp;lt;uri&amp;gt;– the URI projection into the runtime namespace (e.g. ‘sb://&amp;lt;NAMESPACE&amp;gt;.servicebus.appfabriclabs.com/crm/leads/’) 
&lt;/li&gt;&lt;li&gt;&amp;lt;args&amp;gt;– further arguments (see below) &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a connection point. ‘cp create’ requires a trailing argument after the URI that indicates the number of concurrent listeners (max. 20): &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;cp create&lt;/strong&gt; crm-leads sb://clemens.servicebus.appfabriclabs.com/crm/leads/&amp;nbsp; 10 
&lt;/li&gt;&lt;li&gt;Delete a connection point: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;cp delete&lt;/strong&gt; crm-leads 
&lt;/li&gt;&lt;li&gt;Show a connection point: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;cp get &lt;/strong&gt;crm-leads 
&lt;/li&gt;&lt;li&gt;Enumerate all connection points: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;cp get&lt;/strong&gt; 
&lt;/li&gt;&lt;li&gt;Create a message buffer: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;mb create&lt;/strong&gt; jobs &lt;a href="https://clemens.servicebus.appfabriclabs.com/jobs/"&gt;https://clemens.servicebus.appfabriclabs.com/jobs/&lt;/a&gt;&amp;nbsp; 10 
&lt;/li&gt;&lt;li&gt;Delete a message buffer: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;mb delete&lt;/strong&gt; jobs 
&lt;/li&gt;&lt;li&gt;Show a message buffer: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;mb get &lt;/strong&gt;jobs 
&lt;/li&gt;&lt;li&gt;Enumerate all message buffers: &lt;br /&gt;sbmt.exe –n clemens –a owner –s […] &lt;strong&gt;mb get&lt;/strong&gt; &lt;!--endfragment--&gt;&lt;/!--endfragment--&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;The Echo sample requires that you create a connection point in your namespace like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sbmt.exe –n &lt;namespace&gt;–a owner –s […] &lt;strong&gt;cp create&lt;/strong&gt; cp1 sb://&amp;lt;namespace&amp;gt;.servicebus.appfabriclabs.com/services/echo/&amp;nbsp; 10 &lt;/namespace&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The Message Buffer sample requires this setup, whereby the friendly name is asked for by the sample itself (‘mb1’, so you can choose that freely)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sbmt.exe –n &lt;namespace&gt;–a owner –s […] &lt;strong&gt;mb create&lt;/strong&gt; mb1 https://&amp;lt;namespace&amp;gt;.servicebus.appfabriclabs.com/mybuf/&amp;nbsp; &lt;/namespace&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The good news here is that you do this exactly once for your namespace. There is no renewal. A connection point that’s created sticks around like an object in the file system. &lt;/p&gt;
&lt;p&gt;In the next post I’ll drill into what happens at the protocol level. &lt;/p&gt;
&lt;p&gt;Since this is a CTP, we’re keenly interested in your feedback on all the things we’re doing here – making connection points explicit, splitting the namespace, what’s the tooling experience you’d like. This tool here is obviously just something I wrote to get going on demos; you can probably see that having a&amp;nbsp; durable namespace is begging for tooling and it’s one of the reasons we do it.&lt;/p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/pdc10-servicebus-oct10-ctp.zip"&gt;pdc10-servicebus-oct10-ctp.zip (24.65 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=2049b0f4-e46e-4839-bef8-7aa3c88d978f" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10085481" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>PDC10 Windows Azure AppFabric - Service Bus Futures</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/10/29/pdc10-windows-azure-appfabric-service-bus-futures.aspx</link><pubDate>Fri, 29 Oct 2010 09:20:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10083164</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10083164</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/10/29/pdc10-windows-azure-appfabric-service-bus-futures.aspx#comments</comments><description>&lt;p&gt;My PDC10 session is available online (it was pre-recorded). I talk about the new ‘Labs’ release that we released into the datacenter this week and about a range of future capabilities that we’re planning for Service Bus. Some of those future capabilities that are a bit further out are about bringing back some popular capabilities from back in the .NET Services incubation days (like Push and Service Orchestration), some are entirely new.&lt;/p&gt;
&lt;p&gt;One important note about the new release at &lt;a href="http://portal.appfabriclabs.com"&gt;http://portal.appfabriclabs.com&lt;/a&gt; – for Service Bus, this is a focused release that provides mostly only new features and doesn’t provide the full capability scope of the production system and SDK. The goal here is to provide insight into an ongoing development process and opportunity for feedback as we’re continuing to evolve AppFabric. So don’t derive any implications from this release on what we’re going to do with the capabilities already in production.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://player.microsoftpdc.com/Session/1f7d009e-29cb-4a15-a1bf-91ffd115c54d"&gt;Click here to go to the talk.&lt;/a&gt;&lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=f5707b54-5d11-4b5a-a1c4-cfc65faca55e" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10083164" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Windows Azure AppFabric Datacenter IP ranges</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/10/25/windows-azure-appfabric-datacenter-ip-ranges.aspx</link><pubDate>Mon, 25 Oct 2010 08:11:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10080433</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10080433</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/10/25/windows-azure-appfabric-datacenter-ip-ranges.aspx#comments</comments><description>&lt;p&gt;We know that there’s a number of you out there who have outbound firewall rules in place on your corporate infrastructures that are based on IP address whitelisting. So if you want to make Service Bus or Access Control work, you need to know where our services reside. Below is the current list of where the services are deployed as of today, but be aware that it’s in the nature of cloud infrastructures that things can and will move over time.IP address whitelisting strategy isn’t really the right thing to do when the other side is a massively multi-tenant infrastructure such as Windows Azure (or any other public cloud platform, for that matter)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Asia (SouthEast): 207.46.48.0/20, 111.221.16.0/21, 111.221.80.0/20 
&lt;/li&gt;&lt;li&gt;Asia (East): 111.221.64.0/22, 65.52.160.0/19 
&lt;/li&gt;&lt;li&gt;Europe (West): 94.245.97.0/24, 65.52.128.0/19 
&lt;/li&gt;&lt;li&gt;Europe (North): 213.199.128.0/20, 213.199.160.0/20, 213.199.184.0/21, 94.245.112.0/20, 94.245.88.0/21, 94.245.104.0/21, 65.52.64.0/20, 65.52.224.0/19 
&lt;/li&gt;&lt;li&gt;US (North/Central): 207.46.192.0/20, 65.52.0.0/19, 65.52.48.0/20, 65.52.192.0/19, 209.240.220.0/23 
&lt;/li&gt;&lt;li&gt;US (South/Central): 65.55.80.0/20, 65.54.48.0/21, 65.55.64.0/20, 70.37.48.0/20, 70.37.64.0/18, 65.52.32.0/21, 70.37.160.0/21&lt;/li&gt;&lt;/ul&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=1772c4e3-2eed-4c74-b716-fe073a44adc8" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10080433" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Blobber– A trivial little tool for uploading/listing/deleting Windows Azure Blob Storage files</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/10/09/blobber-a-trivial-little-tool-for-uploading-listing-deleting-windows-azure-blob-storage-files.aspx</link><pubDate>Sat, 09 Oct 2010 17:56:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10073735</guid><dc:creator>clemensv</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10073735</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/10/09/blobber-a-trivial-little-tool-for-uploading-listing-deleting-windows-azure-blob-storage-files.aspx#comments</comments><description>&lt;p&gt;There must be dozens of these things, but I didn’t find one online last week and I needed a tool like this to prep a part of my keynote demo in Poland last week – and thus I wrote one. It’s a simple file management utility that works with the Windows Azure Blob store. No whistles, no bells, 344 lines of code if you care to look, both exe and source downloads below, MS-PL license.&lt;/p&gt;
&lt;p&gt;Examples: &lt;br /&gt;&amp;nbsp;&amp;nbsp; List all files from the 'images' container: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o list -c images -a MyAcct -k &amp;lt;key&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List all files matching *.jpg from the 'images' container: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o list -c images -a MyAcct -k &amp;lt;key&amp;gt; *.jpg &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; List all files matching *.jpg from the 'images' container (case-insensitive): &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o list -l -c images -a MyAcct -k &amp;lt;key&amp;gt; *.jpg &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Delete all files matching *.jpg from the 'images' container: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o deletefile -l -c images -a MyAcct -k &amp;lt;key&amp;gt; *.jpg &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Delete 'images' container: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o deletectr -c images -a MyAcct -k &amp;lt;key&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Upload all files from the c:\pictures directory into 'images' container: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o upload -c images -a MyAcct -k &amp;lt;key&amp;gt; c:\pictures\*.jpg &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Upload like above and include all subdirectories: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o upload -s -c images -a MyAcct -k &amp;lt;key&amp;gt; c:\pictures\*.* &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Upload like above and convert all file names to lower case: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o upload -l -s -c images -a MyAcct -k &amp;lt;key&amp;gt; c:\pictures\*.* &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Upload all files from the c:\pictures directory into 'images' container on dev storage: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Blobber.exe -o upload -l -s -c images -d c:\pictures\*.* &lt;br /&gt;Arguments: &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -o &amp;lt;operation&amp;gt; upload, deletectr, deletefile, list (optional, default:'list') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -o list [options] -c &amp;lt;container&amp;gt;&amp;nbsp; &amp;lt;relative-uri-suffix-pattern&amp;gt; (* and ? wildcards) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -o upload [options] [-s] -c &amp;lt;container&amp;gt; &amp;lt;local-path-file-pattern&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -o deletefile [options] -c &amp;lt;container&amp;gt; &amp;lt;relative-uri-suffix-pattern&amp;gt; (* and ? wildcards) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -o deletectr [options] -c &amp;lt;container&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -c &amp;lt;container&amp;gt; Container (optional, default:'files') &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -s Include local file subdirectories (optional, upload only) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -p Make container public (optional) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -l Convert all paths and file names to lower case (optional) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -d Use the local Windows Azure SDK Developer Storage (optional) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -b &amp;lt;baseUri&amp;gt; Base URI (optional override) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -a &amp;lt;accountName&amp;gt; Account Name (optional if specified in config) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -k &amp;lt;key&amp;gt; Account Key&amp;nbsp; (optional if specified in config) &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;You can also specify your account infomation in blobber.exe.config and omit the -a/-k arguments.&lt;/p&gt;
&lt;p&gt;Executable: &lt;a href="http://vasters.com/clemensv/content/binary/Blobber-exe.zip"&gt;Blobber-exe.zip (133.4 KB)&lt;/a&gt;&lt;br /&gt;Source: &lt;a href="http://vasters.com/clemensv/content/binary/Blobber-src.zip"&gt;Blobber-src.zip (5.41 KB)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[Update: I just find that I unintentionally&amp;nbsp;used the same name as a similar utility from Codeplex: &lt;a href="http://blobber.codeplex.com/"&gt;http://blobber.codeplex.com/&lt;/a&gt;. Sorry.] &lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=9ae49403-5948-4157-9f55-7c995c8babc8" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10073735" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category></item><item><title>Cloud Architecture: The Scheduler-Agent-Supervisor Pattern</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/09/27/cloud-architecture-the-scheduler-agent-supervisor-pattern.aspx</link><pubDate>Mon, 27 Sep 2010 16:55:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10068496</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10068496</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/09/27/cloud-architecture-the-scheduler-agent-supervisor-pattern.aspx#comments</comments><description>&lt;p align=justify&gt;As our team was starting to transform our parts of the Azure Services Platform from a CTP ‘labs’ service exploring features into a full-on commercial service, it started to dawn on us that we had set ourselves up for writing a bunch of ‘enterprise apps’. The shiny parts of Service Bus and Access Control that we parade around are all about user-facing features, but if I look back at the work we had to go from a toy service to a commercial offering, I’d guess that 80%-90% of the effort went into aspects like infrastructure, deployment, upgradeability, billing, provisioning, throttling, quotas, security hardening, and service optimization. The lesson there was: when you’re boarding the train to shipping a V1, you don’t load new features on that train –&amp;nbsp; you rather throw some off. &lt;/p&gt;
&lt;p align=justify&gt;The most interesting challenge for these infrastructure apps sitting on the backend was that we didn’t have much solid ground to stand on. Remember – these were very early days, so we couldn’t use SQL Azure since the folks over in SQL were on a pretty heroic schedule themselves and didn’t want to take on any external dependencies even from close friends. We also couldn’t use any of the capabilities of our own bits because building infrastructure for your features on your features would just be plain dumb. And while we could use capabilities of the Windows Azure platform we were building on, a lot of those parts still had rough edges as those folks were going through a lot of the same that we went through. In those days, the table store would be very moody, the queue store would sometimes swallow or duplicate messages, the Azure fabric controller would occasionally go around and kill things. All normal –&amp;nbsp; bugs.&lt;/p&gt;
&lt;p align=justify&gt;So under those circumstances we had to figure out the architecture for some subsystems where we need to do a set of coordinated action across a distributed set of resources – a distributed transaction or saga of sorts. The architecture had a few simple goals: when we get an activation request, we must not fumble that request under any circumstance, we must run the job to completion for all resources and, at the same time, we need to minimize any potential for required operator intervention, i.e. if something goes wrong, the system better knows how to deal with it – at best it should self-heal. &lt;/p&gt;
&lt;p align=justify&gt;My solution to that puzzle is a pattern I call “Scheduler-Agent-Supervisor Pattern” or, short, “Supervisor Pattern”. We keep finding applications for this pattern in different places, so I think it’s worth writing about it in generic terms – even without going into the details of our system.&lt;/p&gt;
&lt;p align=justify&gt;The pattern foots on two seemingly odd and very related assumptions: &lt;em&gt;‘&lt;/em&gt;&lt;strong&gt;&lt;em&gt;the system is perfect’&lt;/em&gt; &lt;/strong&gt;and&lt;strong&gt; &lt;em&gt;‘all error conditions are transient’&lt;/em&gt;.&lt;/strong&gt; As a consequence, the architecture has some character traits of a toddler. It’s generally happily optimistic and gets very grumpy, very quickly when things go wrong – to the point that it will simply drop everything and run away screaming. It’s very precisely like that, in fact.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb.png" width=600 height=290 /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align=justify&gt;The first picture here shows all key pieces except the &lt;em&gt;Supervisor&lt;/em&gt; that I’ll introduce later. At the core we have a &lt;em&gt;Scheduler&lt;/em&gt; that manages a simple state machine made up of &lt;em&gt;Jobs&lt;/em&gt; and those jobs have &lt;em&gt;Steps&lt;/em&gt;. The steps may have a notion of interdependency or may be completely parallelizable. There is a &lt;em&gt;Job Store&lt;/em&gt; that holds jobs and steps and there are &lt;em&gt;Agents&lt;/em&gt; that execute operations on some resource.&amp;nbsp; Each &lt;em&gt;Agent&lt;/em&gt; is (usually) fronted by a queue and the &lt;em&gt;Scheduler&lt;/em&gt; has a queue (or service endpoint) through which it receives reply messages from the &lt;em&gt;Agents&lt;/em&gt;.&lt;/p&gt;
&lt;p align=justify&gt;Steps are recorded in a durable storage table of some sort that has at least the following fields: &lt;em&gt;Current State&lt;/em&gt; (say: Disabled, Active), &lt;em&gt;Desired State&lt;/em&gt; (say: Disabled, Active), &lt;em&gt;LockedUntil&lt;/em&gt; (Date/Time value), and &lt;em&gt;Actor&lt;/em&gt; plus any step specific information you want to store and eventually submit with the job to the step agent.&lt;/p&gt;
&lt;h3&gt;When Things Go Right&lt;/h3&gt;
&lt;p&gt;The initial flow is as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;(1)a&lt;/strong&gt; – Submit a new job into the Scheduler (and wait) &lt;br /&gt;&lt;strong&gt;(2)a&lt;/strong&gt; – The Scheduler creates a new job and steps with an initial current state (&lt;em&gt;‘Disabled’&lt;/em&gt;) in the job store&amp;nbsp; &lt;br /&gt;&lt;strong&gt;(2)b&lt;/strong&gt; – The Scheduler sets ‘desired state’ of the job and of all schedulable steps (dependencies?) to the target state (&lt;em&gt;‘Active’&lt;/em&gt;) and sets the ‘locked until’ timeout of the step to a value in the near future, e.g. ‘Now’ + 2 minutes. &lt;br /&gt;&lt;strong&gt;(1)b&lt;/strong&gt; – Job submission request unblocks and returns&lt;/p&gt;&lt;/blockquote&gt;
&lt;p align=justify&gt;If all went well, we now have a job record and, here in this example, two step records in our store. They have a current state of &lt;em&gt;‘Disabled’&lt;/em&gt; and a desired state of &lt;em&gt;‘Active’&lt;/em&gt;. If things didn’t go well, we’d have incomplete or partially wedged records or nothing in the job store, at all. The client would also know about it since we’ve held on to the reply until we have everything done – so the client is encouraged to retry. If we have nothing in the store and the client doesn’t retry – well, then the job probably wasn’t all that important, after all. But if we have at least a job record, we can make it all right later. We’re optimists, though; let’s assume it all went well.&lt;/p&gt;
&lt;p align=justify&gt;For the next steps we assume that there’s a notion of dependencies between the steps and the second steps depends on the first. If that were not the case, the two actions would just be happening in parallel.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;(3)&lt;/strong&gt; – Place a step message into the queue for the actor for the first step; Agent 1 in this case. The message contains all the information about the step, including the current and desired state and also the &lt;em&gt;LockedUntil&lt;/em&gt; that puts an ultimatum on the activity. The message may further contain an action indicator or arguments that are taken from the step record. &lt;br /&gt;&lt;strong&gt;(4)&lt;/strong&gt; – After the agent has done the work, it places a completion record into the reply queue of the Scheduler. &lt;br /&gt;&lt;strong&gt;(5)&lt;/strong&gt; – The Scheduler records the step as complete by setting the current state from ‘Disabled’ to ‘Active’; as a result the desired and the current state are now equal. &lt;br /&gt;&lt;strong&gt;(6)&lt;/strong&gt; – The Scheduler sets the next step’s desired state to the target state (&lt;em&gt;‘Active’&lt;/em&gt;) and sets the &lt;em&gt;LockedUntil&lt;/em&gt; timeout of the step to a value in the near future, e.g. ‘Now’ + 1 minute. The lock timeout value is an ultimatum for when the operation is expected to be complete and reported back as being complete in a worst-case success case. The actual value therefore depends on the common latency of operations in the system. If operations usually complete in milliseconds and at worst within a second, the lock timeout can be short – but not too short. We’ll discuss this&amp;nbsp; value in more detail a bit later. &lt;br /&gt;&lt;strong&gt;(7)&lt;/strong&gt;, &lt;strong&gt;(8)&lt;/strong&gt;, &lt;strong&gt;(9)&lt;/strong&gt; are equivalent to &lt;strong&gt;(3)&lt;/strong&gt;, &lt;strong&gt;(4)&lt;/strong&gt;, &lt;strong&gt;(5)&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p align=justify&gt;Once the last step’s current state is equal to the current state, the job’s current state gets set to the desired state and we’re done. So that was the “99% of the time” happy path.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_4.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 0px 3px 10px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_1.png" width=591 height=286 /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;When Things Go Wrong&lt;/h3&gt;
&lt;p align=justify&gt;So what happens when anything goes wrong? Remember the principle &lt;strong&gt;‘all errors are transient’&lt;/strong&gt;. What we do in the error case – anywhere – is to log the error condition and then promptly drop everything and simply hope that time, a change in system conditions, human or divine intervention, or – at worst – a patch will heal matters. That’s what the second principle &lt;strong&gt;‘the system is perfect’&lt;em&gt;&amp;nbsp;&lt;/em&gt;&lt;/strong&gt;is about; the system obviously isn’t really perfect, but if we construct it in a way that we can either wait for it to return from a wedged state into a functional state or where we enable someone to go in and apply a fix for a blocking bug while preserving the system state, we can consider the system ‘perfect’ in the sense that pretty much any conceivable job that’s already in the system can be driven to completion.&lt;/p&gt;
&lt;p align=justify&gt;In the second picture, we have Agent 2 blowing up as it is processing the step it got handed in &lt;strong&gt;(7)&lt;/strong&gt;. If the agent just can’t get its work done since some external dependency isn’t available – maybe a database can’t be reached or a server it’s talking to spews out ‘server too busy’ errors – it may be able to back off for a moment and retry. However, it must not retry past the &lt;em&gt;LockedUntil&lt;/em&gt; ultimatum that’s in the step record. When things fail and the agent is still breathing, it may, as a matter of courtesy, notify the scheduler of the fact and report that the step was completed with no result, i.e. the desired state and the achieved state don’t match. That notification may also include diagnostic information. Once the &lt;em&gt;LockedUntil&lt;/em&gt; ultimatum has passed, the Agent no longer owns the job and must drop it. It must even not report failure state back to the Scheduler past that point. &lt;/p&gt;
&lt;p align=justify&gt;If the agent keels over and dies as it is processing the step (or right before or right after), it is obviously no longer in a position to let the scheduler know about its fate. Thus, there won’t be any message flowing back to the scheduler and the job is stalled. But we expect that. In fact, we’re ok with any failure anywhere in the system. We could lose or fumble a queue message, we could get a duplicate message, we could have the scheduler die a fiery death (or just being recycled for patching at some unfortunate moment) – all of those conditions are fine since we’ve brought the doctor on board with us: the &lt;em&gt;Supervisor.&lt;/em&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align=justify&gt;&lt;a href="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_6.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; MARGIN: 3px 10px 3px 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: ; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=image border=0 alt=image src="http://vasters.com/clemensv/content/binary/Windows-Live-Writer/d4c99e27e28d_1248C/image_thumb_2.png" width=558 height=297 /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;The Supervisor&lt;/h3&gt;
&lt;p&gt;The Supervisor is a schedule driven process (or thread) of which one or a few instances may run occasionally. The frequency depends on much on the average duration of operations and the expected overall latency for completion of jobs. &lt;/p&gt;
&lt;p&gt;The Supervisor’s job is to recover steps or jobs that have failed – and we’re assuming that failures are due to some transient condition. So if the system would expect a transient resource failure condition that prevented a job from completing just a second ago to be healed two seconds later, it’d depend on the kind of system and resource whether that’d be a good strategy.&amp;nbsp; What’s described here is a pattern, not a solution, so it depends on the concrete scenario to get the&amp;nbsp; timing right for when to try operations again once they fail.&lt;/p&gt;
&lt;p&gt;This desired back-off time manifests in the &lt;em&gt;LockedUntil&lt;/em&gt; value.&amp;nbsp; When a step gets scheduled, the &lt;em&gt;Scheduler&lt;/em&gt; needs to state how long it is willing to wait for that step to complete; this includes some back-off time padding. Once that ultimatum has passed and the step is still in an inconsistent state (desired state doesn’t equal the current state)&amp;nbsp; the &lt;em&gt;Supervisor&lt;/em&gt; can pick it up at any time and schedule it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;(1)&lt;/strong&gt; – Supervisor queries the job store for any inconsistent steps whose &lt;em&gt;LockedUntil&lt;/em&gt; value has expired. &lt;br /&gt;&lt;strong&gt;(2) – &lt;/strong&gt;The Supervisor schedules the step again by setting the &lt;em&gt;LockedUntil &lt;/em&gt;value to a new timeout and submitting the step into the target actor’s queue &lt;br /&gt;&lt;strong&gt;(3)&lt;/strong&gt; – Once the step succeeds, the step is reported as complete on the regular path back to the &lt;em&gt;Scheduler&lt;/em&gt;&amp;nbsp; where it completes normally as in steps &lt;strong&gt;(8)&lt;/strong&gt;, &lt;strong&gt;(9)&lt;/strong&gt; from the happy-path scenario above. If it fails, we simply drop it again. For failures that allow reporting an error back to the &lt;em&gt;Scheduler&lt;/em&gt; it may make sense to introduce an error counter that round-trips with the step so that the system could detect poisonous steps that fail ‘forever’ and have the &lt;em&gt;Supervisor&lt;/em&gt; ignore those after some threshold.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The Supervisor can pursue a range of strategies for recovery. It can just take a look at individual steps and recover them by rescheduling them – assuming the steps are implemented as idempotent operations. If it were a bit cleverer, it may consider error information that a cooperative (and breathing) agent has submitted back to the Scheduler and even go as far as to fire an alert to an operator if the error condition were to require intervention and then take the step out of the loop by marking it and setting the &lt;em&gt;LockedUntil&lt;/em&gt; value to some longer timeout so it’s taken out of the loop and someone can take a look. &lt;/p&gt;
&lt;p&gt;At the job-scope, the Supervisor may want to perform recovery such that it first schedules all previously executed steps to revert back to the initial state by performing compensation work (all resources that got set to active are getting disabled again here in our example) and then scheduling another attempt at getting to the desired state. &lt;/p&gt;
&lt;p&gt;In step &lt;strong&gt;(2)b&lt;/strong&gt; up above, we’ve been logging current and desired state at the job-scope and with that we can also always find inconsistent jobs where all steps are consistent and wouldn’t show up in the step-level recovery query. That situation can occur if the &lt;em&gt;Scheduler&lt;/em&gt; were to crash between logging one step as complete and scheduling the next step. If we find inconsistent jobs with all-consistent steps, we just need to reschedule the next step in the dependency sequence whose desired state isn’t matching the desired state of the overall job.&lt;/p&gt;
&lt;p&gt;To be thorough, we could now take a look at all the places where things can go wrong in the system. I expect that survey to yield that at as long we can successfully get past step &lt;strong&gt;(2)b &lt;/strong&gt;from the first diagram, the &lt;em&gt;Supervisor&lt;/em&gt; is always in a position to either detect that a job isn’t making progress and help with recovery or can at least call for help. The system always knows what its current &lt;strong&gt;intent&lt;/strong&gt; is, i.e. which state transitions it wants to drive, and never forgets about that intent since that intent is logged in the job store at all times and all progress against that intent is logged as well.&amp;nbsp; The submission request &lt;strong&gt;(1)&lt;/strong&gt; depends on the outcome of &lt;strong&gt;(2)a/b &lt;/strong&gt;to guard against failures while putting a job and its steps into the system so that a client can take corrective action. In fact, once the job record is marked as inconsistent in step &lt;strong&gt;(2)b&lt;/strong&gt;, the scheduler could already report success back to the submitting party even before the first step is scheduled, because the &lt;em&gt;Supervisor&lt;/em&gt; would pick up that inconsistency eventually.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=83f937f7-b838-43d0-ad61-74605eceafa2" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10068496" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Architecture/">Architecture</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Cloud/">Cloud</category></item><item><title>The Magical Input Queue Of T (aka InputQueue&lt;T&gt;)</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/09/12/the-magical-input-queue-of-t-aka-inputqueue-lt-t-gt.aspx</link><pubDate>Sat, 11 Sep 2010 22:29:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10060831</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10060831</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/09/12/the-magical-input-queue-of-t-aka-inputqueue-lt-t-gt.aspx#comments</comments><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post explains an essential class for asynchronous programming that lurks in the depths of the WCF samples: InputQueue&amp;lt;T&amp;gt;. If you need to write efficient server-side apps, you should consider reading through this and add InputQueue&amp;lt;T&amp;gt; to your arsenal.&amp;nbsp; &lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Let me start with: This blog post is 4 years late. Sorry! – and with that out of the way:&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/wcf"&gt;WCF&lt;/a&gt; samples ship with several copies of a class that’s marked as internal in the &lt;em&gt;System.ServiceModel.dll&lt;/em&gt; assembly: &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt;. Why are these samples – mostly those implementing channel-model extensions – bringing local copies of this class with them? It’s an essential tool for implementing the asynchronous call paths of many aspects of channels correctly and efficiently. &lt;/p&gt;
&lt;p&gt;If you look closely enough, the WCF channel infrastructure resembles the Berkeley Socket model quite a bit – especially on the server side. There’s a channel listener that’s constructed on the server side and when that is &lt;a href="http://msdn.microsoft.com/en-us/library/ms195524.aspx"&gt;opened&lt;/a&gt; (usually under the covers of the WCF ServiceHost) that operation is largely equivalent to calling ‘listen’ on a socket – the network endpoint is ready for business.&amp;nbsp; On sockets you’ll then call ‘accept’ to accept the next available socket connection from a client, in WCF you call ‘&lt;a href="http://msdn.microsoft.com/en-us/library/ms195572.aspx"&gt;AcceptChannel&lt;/a&gt;’ to accept the next available (session-) channel. On sockets you then call ‘receive’ to obtain bytes, on a channel you call ’&lt;a href="http://msdn.microsoft.com/en-us/library/ms195339.aspx"&gt;Receive&lt;/a&gt;’ to&amp;nbsp; obtain a message. &lt;/p&gt;
&lt;p&gt;Before and between calls to '’AcceptChannel’ made by the server-side logic,&amp;nbsp; client-initiated connections – and thus channels – may be coming in and queue up for a bit before they handed out to the next caller of ‘AcceptChannel’, or the asynchronous equivalent ‘Begin/EndAcceptChannel’ method pair. The number of channels that may be pending is configured in WCF with the ‘&lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.nettcpbinding.listenbacklog.aspx"&gt;ListenBacklog&lt;/a&gt;’ property that’s available on most bindings. &lt;/p&gt;
&lt;p&gt;I wrote ‘queue up’ there since that’s precisely what happens – those newly created channels on top of freshly accepted sockets or HTTP request channels are enqueued into an &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; instance and (Begin-)Accept is implemented as a dequeue operation on that queue. There are two particular challenges here that make the regular &lt;em&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/7977ey2c.aspx"&gt;Queue&amp;lt;T&amp;gt;&lt;/a&gt;&lt;/em&gt; class from the &lt;em&gt;System.Collections.Generic&lt;/em&gt; namespace unsuitable for use in the implementation of that mechanism: Firstly, the &lt;a href="http://msdn.microsoft.com/en-us/library/1c8bzx97.aspx"&gt;&lt;em&gt;Dequeue&lt;/em&gt;&lt;/a&gt; method there is only available as a synchronous variant and also doesn’t allow for specifying a timeout. Secondly, the queue implementation doesn’t really help much with implementing the &lt;em&gt;ListenBacklog&lt;/em&gt; quota where not only the length of the queue is limited to some configured number of entries, but accepting further connections/channels from the underlying network is also suspended for as long as the queue is at capacity and needs to resume as soon as the pressure is relieved, i.e. a caller takes a channel out of the queue. &lt;/p&gt;
&lt;p&gt;To show that &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; is a very useful general purpose class even outside of the context of the WCF channel infrastructure, I’ve lifted a version of it from one of the most recent WCF channel samples, made a small number of modifications that I’ll write about later, and created a little sample around it that I’ve attached to this post. &lt;/p&gt;
&lt;p&gt;The sample I’ll discuss here is simulating parsing/reading IP addresses from a log-file and then performing a reverse DNS name resolution on those addresses – something that you’d do in a web-server log-analyzer or as the background task in a blog engine wile preparing statistics. &lt;/p&gt;
&lt;p&gt;Reverse DNS name resolution is quite interesting since it’s embarrassingly easy to parallelize and each resolution commonly takes a really long time (4-5 seconds) –whereby all the work is done elsewhere. The process issuing the queries is mostly sitting around idle waiting for the response.&amp;nbsp; Therefore, it’s a good idea to run a number of DNS requests in parallel, but it’s a terrible idea to have any of these requests execute as a blocking call and burning a thread. Since we’re assuming that we’re reading from a log file that requires some parsing, it would also be a spectacularly bad idea to have multiple concurrent threads compete for access to that file and get into each other’s way. And since it is a file and we need to lift things up from disk, we probably shouldn’t do that ‘just in time’ as a DNS resolution step is done, but there should rather be some data readily waiting for processing.&amp;nbsp; &lt;em&gt;InputQueue&amp;lt;T&amp;gt; &lt;/em&gt;is enormously helpful in such a scenario.&lt;/p&gt;
&lt;p&gt;The key file of the sample code – the implementation of the queue itself aside – is obviously Program.cs. Here’s Main() :&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;static&lt;/span&gt; &lt;span class=kwrd&gt;void&lt;/span&gt; Main(&lt;span class=kwrd&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue = 10;&lt;/pre&gt;&lt;pre&gt;    InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue = &lt;span class=kwrd&gt;new&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt;();&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; numResolverLoops = 20;&lt;/pre&gt;&lt;pre&gt;    ManualResetEvent shutdownCompleteEvent = &lt;span class=kwrd&gt;new&lt;/span&gt; ManualResetEvent(&lt;span class=kwrd&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;pre class=alt&gt;    List&amp;lt;IPAddressResolverLoop&amp;gt; resolverLoops = &lt;span class=kwrd&gt;new&lt;/span&gt; List&amp;lt;IPAddressResolverLoop&amp;gt;();&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    Console.WriteLine(&lt;span class=str&gt;"You can stop the program by pressing ENTER."&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We’re setting up a new &lt;em&gt;InputQueue&amp;lt;IPAddress&amp;gt;&lt;/em&gt; here into which we’ll throw the parsed addresses from our acquisition loop that simulates reading from the log. The queue’s capacity will be limited to just 10 entries (&lt;em&gt;maxItemsInQueue&lt;/em&gt; is the input value) and we will run 20 'resolver loops’, which are logical threads that process IP-to-hostname resolution steps.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    Console.WriteLine(&lt;span class=str&gt;"You can stop the program by pressing ENTER."&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=rem&gt;// set up the loop termination callback&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    WaitCallback loopTerminationCallback = o =&amp;gt;&lt;/pre&gt;&lt;pre class=alt&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (Interlocked.Decrement(&lt;span class=kwrd&gt;ref&lt;/span&gt; numResolverLoops) == 0)&lt;/pre&gt;&lt;pre class=alt&gt;        {&lt;/pre&gt;&lt;pre&gt;            shutdownCompleteEvent.Set();&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;    };&lt;/pre&gt;&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=rem&gt;// set up the resolver loops&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;for&lt;/span&gt; (&lt;span class=kwrd&gt;int&lt;/span&gt; loop = 0; loop &amp;lt; numResolverLoops; loop++)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=rem&gt;// add the resolver loop 'i' and set the done flag when the&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=rem&gt;// last of them terminates&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;        resolverLoops.Add(&lt;/pre&gt;&lt;pre&gt;            &lt;span class=kwrd&gt;new&lt;/span&gt; IPAddressResolverLoop(&lt;/pre&gt;&lt;pre class=alt&gt;                logDataQueue, loop, &lt;/pre&gt;&lt;pre&gt;                loopTerminationCallback, &lt;span class=kwrd&gt;null&lt;/span&gt;));&lt;/pre&gt;&lt;pre class=alt&gt;    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we’re kicking off the resolver loops – we’ll look at these in detail a bit later. We’ve got a &lt;em&gt;ManualResetEvent&lt;/em&gt; lock object that guards the program’s exit until all these loops have completed and we’re going to set that to signaled once the last loop completes – that’s what the &lt;em&gt;loopTerminationCallback&lt;/em&gt; anonymous method is for.&amp;nbsp; We’re registering the method with each of the loops and as they complete the method gets called and the last call sets the event. Each loop gets a reference to the &lt;em&gt;logDataQueue &lt;/em&gt;from where it gets its work.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&amp;nbsp;&amp;nbsp; &lt;span class=rem&gt;// set up the acquisition loop; the loop auto-starts&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;using&lt;/span&gt; (LogDataAcquisitionLoop acquisitionLoop =&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;new&lt;/span&gt; LogDataAcquisitionLoop(logDataQueue, maxItemsInQueue))&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=rem&gt;// hang main thread waiting for ENTER&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        Console.ReadLine();&lt;/pre&gt;&lt;pre class=alt&gt;        Console.WriteLine(&lt;span class=str&gt;"*** Shutdown initiated."&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Finally we’re starting the acquisition loop that gets the data from the log file. The loop gets a reference to the &lt;em&gt;logDataQueue&lt;/em&gt; where it places the acquired items and it’s passed the &lt;em&gt;maxItemsInQueue &lt;/em&gt;quota that governs how many items may be read ahead into the queue. Once the user presses the ENTER key, the acquisition loop object is disposed by ways of exiting the &lt;em&gt;using&lt;/em&gt; scope, which stops the loop.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=rem&gt;    // shut down the queue; the resolvers will auto-close&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=rem&gt;// as the queue drains. We don't need to close them here.&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;    logDataQueue.Shutdown();&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=rem&gt;// wait for all work to complete&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    shutdownCompleteEvent.WaitOne();&lt;/pre&gt;&lt;pre class=alt&gt;}&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Lastly, the queue is shut down (by fittingly calling &lt;em&gt;Shutdown&lt;/em&gt;). Shutdown closes the queue (all further enqueue operations are absorbed) and causes all pending readers for which no more entries are available on the queue to unblock immediately&amp;nbsp; and return &lt;em&gt;null&lt;/em&gt;. The resolver loops will complete their respective jobs and will terminate whenever they dequeue &lt;em&gt;null&lt;/em&gt; from the queue. As they terminate, they call the registered termination callback (&lt;em&gt;loopTerminationCallback&lt;/em&gt; from above) and that will eventually cause &lt;em&gt;shutdownCompletedEvent&lt;/em&gt; to become signaled as discussed above.&lt;/p&gt;
&lt;p&gt;The log-reader simulator isn’t particularly interesting for this sample, even though one of the goodies is that the simulation executes on an I/O completion port instead of a managed thread-pool thread – that’s another blog post. The two methods of interest are Begin/EndGetLogData – all that’s of interest here is that EndGetLogData returns an &lt;em&gt;IPAddress&lt;/em&gt; that’s assumed to be parsed out of a log.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; IPAddressLogReaderSimulator&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IAsyncResult BeginGetLogData(AsyncCallback callback, &lt;span class=kwrd&gt;object&lt;/span&gt; data);&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IPAddress EndGetLogData(IAsyncResult result);&lt;/pre&gt;&lt;pre class=alt&gt;}&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The simulator is used internally&amp;nbsp; by the &lt;em&gt;LogDataAcquisitionLoop&lt;/em&gt; class – which we’ll drill into because it implements the throttling mechanism on the queue.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; LogDataAcquisitionLoop : IDisposable&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; IPAddressLogReaderSimulator ipAddressLogReaderSimulator;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;int&lt;/span&gt; readingSuspended;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;bool&lt;/span&gt; shuttingDown;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; LogDataAcquisitionLoop(InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue, &lt;span class=kwrd&gt;int&lt;/span&gt; maxItemsInQueue)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue = logDataQueue;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue = maxItemsInQueue;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown = &lt;span class=kwrd&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator = &lt;span class=kwrd&gt;new&lt;/span&gt; IPAddressLogReaderSimulator();&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;&lt;span class=kwrd&gt;this&lt;/span&gt;.LogDataAcquired&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The constructor sets up the shared state of the loop and kicks off the first read operation on the simulator. Once BeginGetLogData has acquired the first IPAddress (which will happy very quickly), the &lt;em&gt;LogDataAcquired&lt;/em&gt; callback method will be invoked.&amp;nbsp; &lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;LogDataAcquired&lt;/font&gt;(IAsyncResult result)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        IPAddress address = &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.EndGetLogData(result);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        Console.WriteLine(&lt;span class=str&gt;"-- added {0}"&lt;/span&gt;, address);&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.EnqueueAndDispatch(address, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #00ff00"&gt;LogDataItemDequeued&lt;/font&gt;);&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown &amp;amp;&amp;amp; &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.PendingCount &amp;lt; &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;LogDataAcquired&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=rem&gt;// the queue will be at the defined capacity, thus abandon &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class=rem&gt;// the read loop - it'll be picked up by LogDataItemDequeued&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=rem&gt;// as the queue pressure eases&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            Interlocked.Exchange(&lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffc000"&gt;readingSuspended&lt;/font&gt;, 1);&lt;/pre&gt;&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"-- suspended reads"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;    }&lt;/pre&gt;&lt;/div&gt;




&lt;p&gt;The callback method gets the IPAddress and puts it into the queue – using the &lt;em&gt;InputQueue&amp;lt;T&amp;gt;.EnqueueAndDispatch(T, Action)&lt;/em&gt; method. There are two aspects that are quite special about that method when compared to the regular &lt;em&gt;Queue&amp;lt;T&amp;gt;.Enqueue(T) &lt;/em&gt;method. First, it does take a callback as the second argument alongside the item to be enqueued; second, the method name isn’t just &lt;em&gt;Enqueue&lt;/em&gt;, it also says &lt;em&gt;Dispatch. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt; is called, the item and the callback get put into an internal item queue – that’s the ‘enqueue’ part. As we will see in context a bit later in this post, the ‘dequeue’ operation on the queue is the &lt;em&gt;BeginDequeue&lt;/em&gt;/&lt;em&gt;EndDequeue&lt;/em&gt; asynchronous method call pair. There can be any number of concurrent &lt;em&gt;BeginDequeue&lt;/em&gt; requests pending on the queue. ‘Pending’ means that the calls – rather their async callbacks and async state – are registered in another queue internal to &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; that preserves the call order. Thus, &lt;em&gt;BeginDequeue &lt;/em&gt;always only puts the async callback and async state into that queue and returns afterwards. There is no thread spun or hung. That’s all it does.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;As things go, the best opportunity to service a pending dequeue operation on a queue is when an item is being enqueued. Consequently, &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt; will first put the item into the internal queue and will then look whether there are registered waiters and/or readers – waiters are registered by ‘(Begin-)WaitForItem’, readers are registered by ‘(Begin-)Dequeue’. Since it’s known that there a new item in the queue now, the operation will iterate overall waiters and complete them – and does so by invoking their async callbacks, effectively lending the&amp;nbsp; enqueue operation’s thread to the waiters. If there’s at least one pending reader, it’ll then pop a message from the head of the internal item queue and call the reader’s async callback, lending the enqueue operation’s thread to processing of the dequeue operation. If that just made your head spin – yes, the item may have been dequeued and processed as &lt;em&gt;EnqueueAndDispatch&lt;/em&gt; returns. &lt;/p&gt;
&lt;p&gt;There is an overload for&lt;em&gt; EnqueueAndDispatch()&lt;/em&gt; that takes an extra boolean parameter that lets you cause the dispatch operation to happen on a different thread, and there is also a &lt;em&gt;EnqueueWithoutDispatch()&lt;/em&gt; method that just won’t dispatch through and a standalone &lt;em&gt;Dispatch()&lt;/em&gt; method.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The callback supplied to &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt;, here the &lt;em&gt;LogDataItemDequeued&lt;/em&gt; method, is am &lt;em&gt;Action &lt;/em&gt;delegate. The queue will call this callback as the item is being dequeued and, more precisely, when the item has been removed from the internal item queue, but just before it is returned to the caller. That turns out to be quite handy. If you take another look at the &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;&lt;em&gt;LogDataAcquired&lt;/em&gt;&lt;/font&gt; method you’ll notice that we’ve got two alternate code paths after &lt;em&gt;EnqueueAndDispatch()&lt;/em&gt;. The first branch is called when the queue has not reached capacity and it’s not shutting down. When that’s so, we’re scheduling getting the next log item – otherwise we don’t. Instead, we set the &lt;em&gt;&lt;font style="BACKGROUND-COLOR: #ffffff"&gt;readingSuspended&lt;/font&gt;&lt;/em&gt; flag and quit – effectively terminating and abandoning the loop. So how does that get restarted when the queue is no longer at capacity? The &lt;em&gt;LogDataItemDequeued&lt;/em&gt; callback!&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #00ff00"&gt;LogDataItemDequeued&lt;/font&gt;()&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=rem&gt;// called whenever an item is dequeued. First we check &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=rem&gt;// whether the queue is no longer full after this &lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=rem&gt;// operation and the we check whether we need to resume&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=rem&gt;// the read loop.&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shuttingDown &amp;amp;&amp;amp;&lt;/pre&gt;&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.PendingCount &amp;lt; &lt;span class=kwrd&gt;this&lt;/span&gt;.maxItemsInQueue &amp;amp;&amp;amp;&lt;/pre&gt;&lt;pre class=alt&gt;            Interlocked.CompareExchange(&lt;span class=kwrd&gt;ref&lt;/span&gt; &lt;span class=kwrd&gt;this&lt;/span&gt;.readingSuspended, 0, 1) == 1)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"-- resuming reads"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.ipAddressLogReaderSimulator.BeginGetLogData(&lt;span class=kwrd&gt;this&lt;/span&gt;.LogDataAcquired, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The callback gets called for each item that gets dequeued. Which means that we’ll get an opportunity to restart the loop when it’s been stalled because the queue reached capacity. So we’re checking here whether the queue isn’t shuttong down and whether it’s below capacity and if that’s so and the &lt;em&gt;readingSuspended&lt;/em&gt; flag is set, we’re&amp;nbsp; restarting the read loop. And that’s how the throttle works.&lt;/p&gt;
&lt;p&gt;So now we’ve got the data from the log in the queue and we’re throttling nicely so that we don’t pull too much data into memory. How about taking a look at the DNS resolver loops that process the data?&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;&lt;span class=kwrd&gt;class&lt;/span&gt; IPAddressResolverLoop : IDisposable&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;int&lt;/span&gt; loop;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; WaitCallback loopCompleted;&lt;/pre&gt;&lt;pre&gt;    &lt;span class=kwrd&gt;readonly&lt;/span&gt; &lt;span class=kwrd&gt;object&lt;/span&gt; state;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;bool&lt;/span&gt; shutdown;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;public&lt;/span&gt; IPAddressResolverLoop(InputQueue&amp;lt;IPAddress&amp;gt; logDataQueue, &lt;span class=kwrd&gt;int&lt;/span&gt; loop, WaitCallback loopCompleted, &lt;span class=kwrd&gt;object&lt;/span&gt; state)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue = logDataQueue;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.loop = loop;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.loopCompleted = loopCompleted;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.state = state;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.BeginDequeue(TimeSpan.MaxValue, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This loop is also implemented as a class and the fields hold shared that that’s initialized in the constructor. This loop also auto-starts and does so by calling &lt;em&gt;BeginDequeue &lt;/em&gt;on the input queue. As stated above, BeginDequeue&amp;nbsp; commonly just parks the callback and returns.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;(IAsyncResult ar)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        IPAddress address = &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.EndDequeue(ar);&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;if&lt;/span&gt; (!&lt;span class=kwrd&gt;this&lt;/span&gt;.shutdown &amp;amp;&amp;amp; address != &lt;span class=kwrd&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class=alt&gt;        {&lt;/pre&gt;&lt;pre&gt;            Console.WriteLine(&lt;span class=str&gt;"-- took {0}"&lt;/span&gt;, address);&lt;/pre&gt;&lt;pre class=alt&gt;            Dns.BeginGetHostEntry(address, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #00ff00"&gt;IPAddressResolved&lt;/font&gt;, &lt;span class=kwrd&gt;new&lt;/span&gt; &lt;span class=kwrd&gt;object&lt;/span&gt;[] { Stopwatch.StartNew(), address });&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=kwrd&gt;this&lt;/span&gt;.loopCompleted(&lt;span class=kwrd&gt;this&lt;/span&gt;.state);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;    }&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As an &lt;em&gt;IPAddress&lt;/em&gt; is becomes available on the queue, the callback is being invoked and that’s quite likely on a thread lent by &lt;em&gt;EnqueueAndDispatch&lt;/em&gt;() and therefore sitting&amp;nbsp; on the thread the log file generator is using to call back for completion of the &lt;em&gt;BeginGetLogData&lt;/em&gt; method if you trace things back. If we get an address and the value isn’t &lt;em&gt;null&lt;/em&gt;, we’ll then proceed to schedule the DNS lookup via &lt;em&gt;Dns.BeginGetHostEntry&lt;/em&gt;. Otherwise we’ll terminate the loop and call the &lt;em&gt;loopCompleted&lt;/em&gt; callback. In Main() that’s the anonymous method that counts down the loop counter and signals the event when it falls to zero.&lt;/p&gt;
&lt;div class=csharpcode&gt;&lt;pre class=alt&gt;    &lt;span class=kwrd&gt;void&lt;/span&gt; &lt;font style="BACKGROUND-COLOR: #00ff00"&gt;IPAddressResolved&lt;/font&gt;(IAsyncResult ar)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class=alt&gt;        var args = ((&lt;span class=kwrd&gt;object&lt;/span&gt;[])ar.AsyncState);&lt;/pre&gt;&lt;pre&gt;        var stopwatch = (Stopwatch)args[0];&lt;/pre&gt;&lt;pre class=alt&gt;        var address = (IPAddress)args[1];&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class=alt&gt;        stopwatch.Stop();&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;double&lt;/span&gt; msecs = stopwatch.ElapsedMilliseconds;&lt;/pre&gt;&lt;pre class=alt&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class=kwrd&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;        {&lt;/pre&gt;&lt;pre&gt;            IPHostEntry entry = Dns.EndGetHostEntry(ar);&lt;/pre&gt;&lt;pre class=alt&gt;            Console.WriteLine(&lt;span class=str&gt;"{0}: {1} {2}ms"&lt;/span&gt;, &lt;span class=kwrd&gt;this&lt;/span&gt;.loop, entry.HostName, msecs);&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;catch&lt;/span&gt; (SocketException)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class=alt&gt;            &lt;span class=rem&gt;// couldn't resolve. print the literal address&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            Console.WriteLine(&lt;span class=str&gt;"{0}: {1} {2}ms"&lt;/span&gt;, &lt;span class=kwrd&gt;this&lt;/span&gt;.loop, address, msecs);&lt;/pre&gt;&lt;pre class=alt&gt;        }&lt;/pre&gt;&lt;pre&gt;        &lt;span class=rem&gt;// done with this entry, get the next&lt;/span&gt;&lt;/pre&gt;&lt;pre class=alt&gt;        &lt;span class=kwrd&gt;this&lt;/span&gt;.logDataQueue.BeginDequeue(TimeSpan.MaxValue, &lt;span class=kwrd&gt;this&lt;/span&gt;.&lt;font style="BACKGROUND-COLOR: #ffff00"&gt;IPAddressDequeued&lt;/font&gt;, &lt;span class=kwrd&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The &lt;em&gt;IPAddressResolved&lt;/em&gt; method just deals with the mechanics of printing out the result of the lookup and then schedules another &lt;em&gt;BeginDequeue&lt;/em&gt; call to start the next iteration. &lt;/p&gt;
&lt;p&gt;Summary: The enabler for and the core piece of the implementation of this scenario is &lt;em&gt;InputQueue&amp;lt;T&amp;gt;&lt;/em&gt; – the dequeue-callback enables implementing throttling effectively and the dispatch logic provides an efficient way to leverage threads in applications that leverage asynchronous programming patterns, especially in I/O driven situations as illustrated here.&lt;/p&gt;
&lt;p&gt;And last but not least – here’s teh codez; project file is for VS2010, throw the files into a new console app for VS2008 and mark the project to allow unsafe code (for the I/O completion thread pool code).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vasters.com/clemensv/content/binary/UsingInputQueue.zip"&gt;UsingInputQueue.zip (13.85 KB)&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;or if you'd rather have a version of InputQueue that is using the regular thread pool, &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&amp;amp;displaylang=en"&gt;download the WCF samples&lt;/a&gt;&amp;nbsp;and look for InputQueue.cs.&lt;/p&gt;
&lt;p&gt;[The sample code posted here is subject to the Windows SDK sample code license]&lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=3d2486d4-2bfa-446c-886b-bf336f92c861" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10060831" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/WCF/">WCF</category></item><item><title>Programming WCF Services, Third Edition</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/09/10/programming-wcf-services-third-edition.aspx</link><pubDate>Fri, 10 Sep 2010 18:10:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10060593</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10060593</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/09/10/programming-wcf-services-third-edition.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://oreilly.com/catalog/9780596805494"&gt;&lt;img style="MARGIN: 5px; DISPLAY: inline" alt="Book cover of Programming WCF Services" align=right src="http://covers.oreilly.com/images/9780596805494/cat.gif" width=180 /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Juval Löwy’s very successful WCF book is now available in its third edition – and Juval asked me to update the foreword this time around. It’s been over three years since I wrote the foreword to the first edition and thus it was time for an update since WCF has moved on quite a bit and the use of it in the customer landscape and inside of MS has deepened where we’re building a lot of very interesting products on top of the WCF technology across all businesses – not least of which is the Azure AppFabric Service Bus that I work on and that’s entirely based on WCF services.&lt;/p&gt;
&lt;p&gt;You can take a peek into the latest edition &lt;a href="http://oreilly.com/catalog/9780596805494/preview#preview"&gt;at the O’Reilly website&lt;/a&gt; and read my foreword if you care. To be clear: It’s the least important part of the whole book :-)&lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=6a3321d3-1e96-47ae-8c5e-9d60346627de" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10060593" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/WCF/">WCF</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>Twitter</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/09/08/twitter.aspx</link><pubDate>Wed, 08 Sep 2010 16:20:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10059590</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10059590</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/09/08/twitter.aspx#comments</comments><description>&lt;p&gt;For the (blog-) record - if you'd ever be looking for me on Twitter (where I'm sadly writing tons more than here), I'm &lt;a href="http://twitter.com/clemensv"&gt;@clemensv&lt;/a&gt;&amp;nbsp;over there :-) &lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=5f014ea7-bac6-4b48-af18-e41533801e56" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10059590" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Twitter/">Twitter</category></item><item><title>Windows Azure AppFabric Overview session from TechEd Australia 2010 </title><link>http://blogs.msdn.com/b/clemensv/archive/2010/09/08/windows-azure-appfabric-overview-session-from-teched-australia-2010.aspx</link><pubDate>Wed, 08 Sep 2010 16:08:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10059587</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10059587</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/09/08/windows-azure-appfabric-overview-session-from-teched-australia-2010.aspx#comments</comments><description>&lt;p&gt;In case you need a refresher or update about the things me and our team work on at Microsoft, &lt;a href="http://www.msteched.com/2010/Australia/COS230"&gt;go here&lt;/a&gt; for a very recent and very good presentation by my PM colleague &lt;a href="http://twitter.com/mmyslin"&gt;Maggie Myslinska&lt;/a&gt; from TechEd Australia 2010 about Windows Azure AppFabric with Service Bus demos and a demo of the new Access Control V2 CTP&lt;/p&gt;



&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=a14d84f7-0d07-49da-a5d8-35088052c3e5" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10059587" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category></item><item><title>TechEd: ASI204 Windows Azure Platform AppFabric Overview</title><link>http://blogs.msdn.com/b/clemensv/archive/2010/06/01/teched-asi204-windows-azure-platform-appfabric-overview.aspx</link><pubDate>Tue, 01 Jun 2010 12:15:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10018516</guid><dc:creator>clemensv</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/clemensv/rsscomments.aspx?WeblogPostID=10018516</wfw:commentRss><comments>http://blogs.msdn.com/b/clemensv/archive/2010/06/01/teched-asi204-windows-azure-platform-appfabric-overview.aspx#comments</comments><description>&lt;p&gt;Room 398, Tuesday June 8 &lt;br /&gt;3:15pm-4:30pm &lt;br /&gt;&lt;br /&gt;Session Type: Breakout Session &lt;br /&gt;Track: Application Server &amp;amp; Infrastructure &lt;br /&gt;Speaker(s): Maggie Myslinska &lt;br /&gt;Level: 200 – Intermediate &lt;br /&gt;&lt;br /&gt;&lt;em&gt;Come learn how to use Windows Azure AppFabric (with Service Bus and Access Control) as building block services for Web-based and hosted applications, and how developers can leverage services to create applications in the cloud and connect them with on-premises systems.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you are planning on seeing &lt;a href="http://vasters.com/clemensv/PermaLink,guid,3ce38507-44b7-4a2a-bacb-aeb7aaacdf56.aspx"&gt;Juval’s and my talk ASI304 at TechEd&lt;/a&gt; and/or if you need to know more about how &lt;a href="http://www.microsoft.com/windowsazure/appfabric/"&gt;Windows Azure AppFabric&lt;/a&gt; enables federated cloud/on-premise applications and a range of other scenarios, you should definitely put &lt;a href="http://northamerica.msteched.com/ScheduleBuilder?keyword=asi204"&gt;Maggie’s talk onto your TechEd schedule&lt;/a&gt; as well.&amp;nbsp; &lt;/p&gt;&lt;img width="0" height="0" src="http://vasters.com/clemensv/cptrk.ashx?id=daa81750-f570-46e1-a38a-05d008e57585" /&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10018516" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/TechEd/">TechEd</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Azure/">Azure</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/AppFabric/">AppFabric</category><category domain="http://blogs.msdn.com/b/clemensv/archive/tags/Talks/">Talks</category></item></channel></rss>
