<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-15136575</atom:id><lastBuildDate>Thu, 23 May 2013 07:34:23 +0000</lastBuildDate><category>WCF Facility</category><category>Architecture</category><category>Log4net</category><category>Forms Authentication</category><category>DDD7</category><category>RavenDb</category><category>msbuild</category><category>MSTest</category><category>MetaWeblog API</category><category>Ajax</category><category>Unit Tests</category><category>software factories</category><category>Rap</category><category>Live Writer</category><category>Google maps</category><category>AltNetUK</category><category>MVCContrib</category><category>MEF</category><category>Web Design</category><category>DDD8</category><category>Task Parallel Library</category><category>Visual Tools</category><category>WTF</category><category>LINQ to SQL</category><category>EasyNetQ</category><category>ALT.NET UK</category><category>Extension methods</category><category>jQuery</category><category>CSS</category><category>IoC</category><category>REST</category><category>Windsor</category><category>Multi-tenancy</category><category>Photosynth</category><category>Web Services</category><category>IServiceLocator</category><category>ALT.NET</category><category>sussex geek dinner</category><category>F#</category><category>Google</category><category>Web Hosting</category><category>visual studio</category><category>Suteki Shop</category><category>RSD</category><category>WCF</category><category>Castle Windsor</category><category>MVC Framework</category><category>Linq</category><category>PDC</category><category>Validation</category><category>Load Testing</category><category>NHibernate</category><category>asp.net</category><category>IE</category><category>Monorail</category><category>IRepository</category><category>ADO.NET Data Services</category><category>REMIX</category><category>blogging</category><category>custom iterators</category><category>C# 4.0</category><title>Code rant</title><description>Life as a mort.</description><link>http://mikehadlow.blogspot.com/</link><managingEditor>noreply@blogger.com (Mike Hadlow)</managingEditor><generator>Blogger</generator><openSearch:totalResults>444</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/CodeRant" /><feedburner:info uri="coderant" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-5528553422093681488</guid><pubDate>Fri, 03 May 2013 15:22:00 +0000</pubDate><atom:updated>2013-05-03T16:30:59.822+01:00</atom:updated><title>The Benefits of a Reverse Proxy</title><description>&lt;p&gt;A typical ASP.NET public website hosted on IIS is usually configured in such a way that the server that IIS is installed on is visible to the public internet. HTTP requests from a browser or web service client are routed directly to IIS which also hosts the ASP.NET worker process.&amp;#160; All the functionality needed to produce the web site is embodied in a single server. This includes caching, SSL termination, authentication, serving static files and compression. This approach is simple and straightforward for small sites, but is hard to scale, both in terms of performance, and in terms of managing the complexity of a large complex application. This is especially true if you have a distributed service oriented architecture with multiple HTTP endpoints that appear and disappear frequently.&lt;/p&gt;  &lt;p&gt;A reverse proxy is server component that sits between the internet and your web servers. It accepts HTTP requests, provides various services, and forwards the requests to one or many servers.&lt;/p&gt;  &lt;p&gt;&lt;img title="font-side-proxy" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="font-side-proxy" src="http://lh4.ggpht.com/-woCHbnyXB3k/UYPWR481THI/AAAAAAAAIx8/xn9GR0qAqC4/font-side-proxy%25255B5%25255D.png?imgmax=800" width="600" height="278" /&gt; &lt;/p&gt;  &lt;p&gt;Having a point at which you can inspect, transform and route HTTP requests before they reach your web servers provides a whole host of benefits. Here are some:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Load Balancing&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is the reverse proxy function that people are most familiar with. Here the proxy routes incoming HTTP requests to a number of identical web servers. This can work on a simple round-robin basis, or if you have statefull web servers (it’s better not to) there are session-aware load balancers available. It’s such a common function that load balancing reverse proxies are usually just referred to as ‘load balancers’. There are specialized load balancing products available, but many general purpose reverse proxies also provide load balancing functionality.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;A reverse proxy can hide the topology and characteristics of your back-end servers by removing the need for direct internet access to them. You can place your reverse proxy in an internet facing DMZ, but hide your web servers inside a non-public subnet.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;You can use your reverse proxy to provide a single point of authentication for all HTTP requests.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SSL Termination&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Here the reverse proxy handles incoming HTTPS connections, decrypting the requests and passing unencrypted requests on to the web servers. This has several benefits:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Removes the need to install certificates on many back end web servers.&lt;/li&gt;    &lt;li&gt;Provides a single point of configuration and management for SSL/TLS&lt;/li&gt;    &lt;li&gt;Takes the processing load of encrypting/decrypting HTTPS traffic away from web servers.&lt;/li&gt;    &lt;li&gt;Makes testing and intercepting HTTP requests to individual web servers easier.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Serving Static Content&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Not strictly speaking ‘reverse proxying’ as such. Some reverse proxy servers can also act as web servers serving static content. The average web page can often consist of megabytes of static content such as images, CSS files and JavaScript files. By serving these separately you can take considerable load from back end web servers, leaving them free to render dynamic content.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The reverse proxy can also act as a cache. You can either have a dumb cache that simply expires after a set period, or better still a cache that respects Cache-Control and Expires headers. This can considerably reduce the load on the back-end servers.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Compression&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In order to reduce the bandwidth needed for individual requests, the reverse proxy can decompress incoming requests and compress outgoing ones. This reduces the load on the back-end servers that would otherwise have to do the compression, and makes debugging requests to, and responses from, the back-end servers easier.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Centralised Logging and Auditing&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Because all HTTP requests are routed through the reverse proxy, it makes an excellent point for logging and auditing.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;URL Rewriting&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Sometimes the URL scheme that a legacy application presents is not ideal for discovery or search engine optimisation. A reverse proxy can rewrite URLs before passing them on to your back-end servers. For example, a legacy ASP.NET application might have a URL for a product that looks like this:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;http://www.myexampleshop.com/products.aspx?productid=1234&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;You can use a reverse proxy to present a search engine optimised URL instead:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;http://www.myexampleshop.com/products/1234/lunar-module&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Aggregating Multiple Websites Into the Same URL Space&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In a distributed architecture it’s desirable to have different pieces of functionality served by isolated components. A reverse proxy can route different branches of a single URL address space to different internal web servers. &lt;/p&gt;  &lt;p&gt;For example, say I’ve got three internal web servers:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;http://products.internal.net/&lt;br /&gt;http://orders.internal.net/&lt;br /&gt;http://stock-control.internal.net/&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;I can route these from a single external domain using my reverse proxy:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;http://www.example.com/products/    -&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; http://products.internal.net/&lt;br /&gt;http://www.example.com/orders/    -&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; http://orders.internal.net/&lt;br /&gt;http://www.example.com/stock/    -&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; http://stock-control.internal.net/&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;To an external customer it appears that they are simply navigating a single website, but internally the organisation is maintaining three entirely separate sites. This approach can work extremely well for web service APIs where the reverse proxy provides a consistent single public facade to an internal distributed component oriented architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So …&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, a reverse proxy can off load much of the infrastructure concerns of a high-volume distributed web application.&lt;/p&gt;

&lt;p&gt;We’re currently looking at &lt;a href="http://wiki.nginx.org/Main"&gt;Nginx&lt;/a&gt; for this role. Expect some practical Nginx related posts about how to do some of this stuff in the very near future.&lt;/p&gt;

&lt;p&gt;Happy proxying!&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/Ik-9FWofdpI/the-benefits-of-reverse-proxy.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-woCHbnyXB3k/UYPWR481THI/AAAAAAAAIx8/xn9GR0qAqC4/s72-c/font-side-proxy%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/05/the-benefits-of-reverse-proxy.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-3307279633235947879</guid><pubDate>Mon, 22 Apr 2013 15:38:00 +0000</pubDate><atom:updated>2013-04-22T16:43:19.195+01:00</atom:updated><title>Stop Your Console App The Nice Way</title><description>&lt;p&gt;When you write a console application, do you simply put&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Hit &amp;lt;enter&amp;gt; to end&amp;quot;&lt;/span&gt;);&lt;br /&gt;Console.ReadLine();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;at the end of Main and block on Console.ReadLine()?&lt;/p&gt;

&lt;p&gt;It’s much nicer to to make your console application work with Windows command line conventions and exit when the user types Control-C.&lt;/p&gt;

&lt;p&gt;The Console class has a static event CancelKeyPress that fires when Ctrl-C is pressed. You can create an AutoResetEvent that blocks until you call Set in the CancelKeyPress handler.&lt;/p&gt;

&lt;p&gt;It’s also nice to stop the application from being arbitrarily killed at the point where Ctrl-C is pressed by setting the EventArgs.Cancel property to true. This gives you a chance to complete what you are doing and exit the application cleanly.&lt;/p&gt;

&lt;p&gt;Here’s an example. My little console application kicks off a worker thread and then blocks waiting for Ctrl-C as described above. When Ctrl-C is pressed I send a signal to the worker thread telling it to finish what it’s doing and exit.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; Mike.Spikes.ConsoleShutdown&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; cancel = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Application has started. Ctrl-C to end&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;// do some cool stuff here&lt;/span&gt;&lt;br /&gt;            var myThread = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Thread(Worker);&lt;br /&gt;            myThread.Start();&lt;br /&gt;&lt;br /&gt;            var autoResetEvent = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;br /&gt;            Console.CancelKeyPress += (sender, eventArgs) =&amp;gt;&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #008000"&gt;// cancel the cancellation to allow the program to shutdown cleanly&lt;/span&gt;&lt;br /&gt;                    eventArgs.Cancel = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;                    autoResetEvent.Set();&lt;br /&gt;                };&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000"&gt;// main blocks here waiting for ctrl-C&lt;/span&gt;&lt;br /&gt;            autoResetEvent.WaitOne();&lt;br /&gt;            cancel = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Now shutting down&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Worker()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (!cancel)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Worker is working&amp;quot;&lt;/span&gt;);&lt;br /&gt;                Thread.Sleep(1000);&lt;br /&gt;            }&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Worker thread ending&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Much nicer I think.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/vHytyO36rf4/stop-your-console-app-nice-way.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>9</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/04/stop-your-console-app-nice-way.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-73101241878931773</guid><pubDate>Thu, 18 Apr 2013 15:11:00 +0000</pubDate><atom:updated>2013-04-18T16:11:44.908+01:00</atom:updated><title>Serializing Lua Coroutines With Pluto</title><description>&lt;p&gt;In my last post I showed how it’s possible to use Lua as a &lt;a href="http://mikehadlow.blogspot.co.uk/2013/04/lua-as-distributed-workflow-scripting.html"&gt;distributed workflow scripting language&lt;/a&gt; because of its build in support for coroutines. But in order to create viable long-running workflows we have to have some way of saving the script’s state at the point that it pauses; we need a way to serialize the coroutine.&lt;/p&gt;  &lt;p&gt;Enter Pluto:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“&lt;em&gt;Pluto is a heavy duty persistence library for Lua. Pluto is a library which allows users to write arbitrarily large portions of the &amp;quot;Lua universe&amp;quot; into a flat file, and later read them back into the same or a different Lua universe.&lt;/em&gt;”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I downloaded the &lt;a href="http://luaos.net/pages/tamed-pluto.php"&gt;Win32 build of Tamed Pluto from here&lt;/a&gt; and placed it in a directory alongside my Pluto.dll. You have to tell Lua where to find C libraries by setting the Lua package.cpath:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (var lua = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Lua())&lt;br /&gt;{&lt;br /&gt;    lua[&lt;span style="color: #006080"&gt;&amp;quot;package.cpath&amp;quot;&lt;/span&gt;] = &lt;span style="color: #006080"&gt;@&amp;quot;D:\Source\Mike.DistributedLua\Lua\?.dll&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Lua can now find the Pluto library and we can import it into our script with:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;require(&lt;span style="color: #006080"&gt;'pluto'&lt;/span&gt;)&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here’s a script which defines a function foo which calls a function bar. Foo is used to create a coroutine. Inside bar the coroutine yields. The script uses Pluto to serialize the yielded coroutine and saves it to a file.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #008000"&gt;-- import pluto, print out the version number &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- and set non-human binary serialization scheme.&lt;/span&gt;&lt;br /&gt;require(&lt;span style="color: #006080"&gt;'pluto'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;print&lt;/span&gt;(&lt;span style="color: #006080"&gt;'pluto version '&lt;/span&gt;..pluto.version())&lt;br /&gt;pluto.human(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- perms are items to be substituted at serialization&lt;/span&gt;&lt;br /&gt;perms = { [coroutine.yield] = 1 }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- the functions that we want to execute as a coroutine&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; foo()&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;local&lt;/span&gt; someMessage = &lt;span style="color: #006080"&gt;'And hello from a long dead variable!'&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;local&lt;/span&gt; i = 4&lt;br /&gt;    bar(someMessage)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;print&lt;/span&gt;(i)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; bar(msg)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;print&lt;/span&gt;(&lt;span style="color: #006080"&gt;'entered bar'&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color: #008000"&gt;-- bar runs to here then yields&lt;/span&gt;&lt;br /&gt;    coroutine.yield()&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;print&lt;/span&gt;(msg)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- create and start the coroutine&lt;/span&gt;&lt;br /&gt;co = coroutine.&lt;span style="color: #0000ff"&gt;create&lt;/span&gt;(foo)&lt;br /&gt;coroutine.resume(co)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- the coroutine has now stopped at yield. so we can&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- persist its state with pluto&lt;/span&gt;&lt;br /&gt;buf = pluto.persist(perms, co)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- save the serialized state to a file&lt;/span&gt;&lt;br /&gt;outfile = io.&lt;span style="color: #0000ff"&gt;open&lt;/span&gt;(persistCRPath, &lt;span style="color: #006080"&gt;'wb'&lt;/span&gt;)&lt;br /&gt;outfile:&lt;span style="color: #0000ff"&gt;write&lt;/span&gt;(buf)&lt;br /&gt;outfile:&lt;span style="color: #0000ff"&gt;close&lt;/span&gt;()&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This next script loads the serialized coroutine from disk, deserializes it, and runs it from the point that it yielded:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #008000"&gt;-- import pluto, print out the version number &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- and set non-human binary serialization scheme.&lt;/span&gt;&lt;br /&gt;require(&lt;span style="color: #006080"&gt;'pluto'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;print&lt;/span&gt;(&lt;span style="color: #006080"&gt;'pluto version '&lt;/span&gt;..pluto.version())&lt;br /&gt;pluto.human(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- perms are items to be substituted at serialization&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- (reverse the key/value pair that you used to serialize)&lt;/span&gt;&lt;br /&gt;perms = { [1] = coroutine.yield }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- get the serialized coroutine from disk&lt;/span&gt;&lt;br /&gt;infile, err = io.&lt;span style="color: #0000ff"&gt;open&lt;/span&gt;(persistCRPath, &lt;span style="color: #006080"&gt;'rb'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; infile == nil &lt;span style="color: #0000ff"&gt;then&lt;/span&gt;&lt;br /&gt;    error(&lt;span style="color: #006080"&gt;'While opening: '&lt;/span&gt; .. (err &lt;span style="color: #0000ff"&gt;or&lt;/span&gt; &lt;span style="color: #006080"&gt;'no error'&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;buf, err = infile:&lt;span style="color: #0000ff"&gt;read&lt;/span&gt;(&lt;span style="color: #006080"&gt;'*a'&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; buf == nil &lt;span style="color: #0000ff"&gt;then&lt;/span&gt;&lt;br /&gt;    error(&lt;span style="color: #006080"&gt;'While reading: '&lt;/span&gt; .. (err &lt;span style="color: #0000ff"&gt;or&lt;/span&gt; &lt;span style="color: #006080"&gt;'no error'&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #0000ff"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;infile:&lt;span style="color: #0000ff"&gt;close&lt;/span&gt;()&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- deserialize it&lt;/span&gt;&lt;br /&gt;co = pluto.unpersist(perms, buf)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;-- and run it&lt;/span&gt;&lt;br /&gt;coroutine.resume(co)&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;When we run the scripts, the first prints out ‘entered bar’ and then yields:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;LUA&amp;gt; pluto version Tamed Pluto 1.0&lt;br /&gt;LUA&amp;gt; entered bar&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The second script loads the paused ‘foo’ and ‘bar’ and continues from the yield:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;LUA&amp;gt; pluto version Tamed Pluto 1.0&lt;br /&gt;LUA&amp;gt; And hello from a &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; dead variable!&lt;br /&gt;LUA&amp;gt; 4&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Having the ability to run a script to the point at which it starts a long running call, serialize its state and store it somewhere, then pick up that serialized state and resume it at another place and time is a very powerful capability. It means we can write simple procedural scripts for our workflows, but have them execute over a distributed service oriented architecture.&lt;/p&gt;

&lt;p&gt;The complete code for this experiment is on GitHub &lt;a href="https://github.com/mikehadlow/Mike.DistributedLua/blob/master/Mike.DistributedLua/PlutoSpike.cs"&gt;here&lt;/a&gt;.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/jwMF2Q_1M7c/serializing-lua-coroutines-with-pluto.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>0</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/04/serializing-lua-coroutines-with-pluto.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-5805849305215033871</guid><pubDate>Thu, 04 Apr 2013 15:39:00 +0000</pubDate><atom:updated>2013-04-04T16:39:33.587+01:00</atom:updated><title>Lua as a Distributed Workflow Scripting Language</title><description>&lt;p&gt;I’ve been spending a lot of time recently thinking about ways of orchestrating long running workflows in a service oriented architecture. I was talking this over at last Tuesday’s &lt;a href="http://brightonalt.net/"&gt;Brighton ALT NET&lt;/a&gt; when &lt;a href="https://twitter.com/jaykannan"&gt;Jay Kannan&lt;/a&gt;, who’s a game developer amongst other things, mentioned that &lt;a href="http://www.lua.org/"&gt;Lua&lt;/a&gt; is a popular choice for scripting game platforms. Maybe I should check it out. So I did. And it turns out to be very interesting.&lt;/p&gt;  &lt;p&gt;If you haven’t heard of Lua, it’s a “powerful, fast, lightweight, embeddable scripting language” originally conceived by a team at the Catholic University of Rio de Janeiro in Brazil. It’s the leading scripting language for game platforms and also pops up in other interesting locations including Photoshop and &lt;a href="http://blog.wikimedia.org/2013/03/14/what-lua-scripting-means-wikimedia-open-source/"&gt;Wikipedia&lt;/a&gt;. It’s got a straightforward C API that makes it relatively simple to p-invoke from .NET, and indeed there’s a &lt;a href="http://luaforge.net/projects/luainterface/"&gt;LuaInterface&lt;/a&gt; library that provides a managed API.&lt;/p&gt;  &lt;p&gt;I got the source code from the &lt;a href="https://code.google.com/p/luainterface/"&gt;Google code svn repository&lt;/a&gt; and built it in VS 2012, but there are NuGet packages available as well.&lt;/p&gt;  &lt;p&gt;It turned out to be very simple to use Lua to script a distributed workflow. Lua has &lt;a href="http://www.lua.org/manual/5.2/manual.html#2.6"&gt;first class coroutines&lt;/a&gt; which means that you can pause and continue a Lua script at will. The LuaInterface library allows you inject C# functions and call them as Lua functions, so it’s simply a case of calling an asynchronous C# ‘begin’ function, suspending the script by yielding the coroutine, waiting for the asynchronous function to return, setting the return value, and starting up the script again. &lt;/p&gt;  &lt;p&gt;Let me show you how.&lt;/p&gt;  &lt;p&gt;First here’s a little Lua script:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;a = 5&lt;br /&gt;b = 6&lt;br /&gt;&lt;br /&gt;print(&lt;span style="color: #006080"&gt;'doing remote add ...'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;r1 = remoteAdd(a, b)&lt;br /&gt;&lt;br /&gt;print(&lt;span style="color: #006080"&gt;'doing remote multiply ...'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;r2 = remoteMultiply(r1, 4)&lt;br /&gt;&lt;br /&gt;print(&lt;span style="color: #006080"&gt;'doing remote divide ...'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;r3 = remoteDivide(r2, 2)&lt;br /&gt;&lt;br /&gt;print(r3)&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The three functions ‘remoteAdd’, ‘remoteMultiply’ and ‘remoteDivide’ are all asynchronous. Behind the scenes a message is sent via RabbitMQ to a remote OperationServer where the calculation is carried out and a message is returned.&lt;/p&gt;

&lt;p&gt;The script runs in my LuaRuntime class. This creates and sets up the Lua environment that the script runs in:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LuaRuntime : IDisposable&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Lua lua = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Lua();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Functions functions = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Functions();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; LuaRuntime()&lt;br /&gt;    {&lt;br /&gt;        lua.RegisterFunction(&lt;span style="color: #006080"&gt;&amp;quot;print&amp;quot;&lt;/span&gt;, functions, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Functions).GetMethod(&lt;span style="color: #006080"&gt;&amp;quot;Print&amp;quot;&lt;/span&gt;));&lt;br /&gt;        lua.RegisterFunction(&lt;span style="color: #006080"&gt;&amp;quot;startOperation&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;, GetType().GetMethod(&lt;span style="color: #006080"&gt;&amp;quot;StartOperation&amp;quot;&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;        lua.DoString(&lt;br /&gt;&lt;span style="color: #006080"&gt;@&amp;quot;&lt;br /&gt;function remoteAdd(a, b) return remoteOperation(a, b, '+'); end&lt;br /&gt;function remoteMultiply(a, b) return remoteOperation(a, b, '*'); end&lt;br /&gt;function remoteDivide(a, b) return remoteOperation(a, b, '/'); end&lt;br /&gt;&lt;br /&gt;function remoteOperation(a, b, op)&lt;br /&gt;    startOperation(a, b, op)&lt;br /&gt;    local cor = coroutine.running()&lt;br /&gt;    coroutine.yield(cor)&lt;br /&gt;&lt;br /&gt;    return LUA_RUNTIME_OPERATION_RESULT&lt;br /&gt;end&lt;br /&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartOperation(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; a, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; b, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; operation)&lt;br /&gt;    {&lt;br /&gt;        functions.RunOperation(a, b, operation, result =&amp;gt;&lt;br /&gt;            {&lt;br /&gt;                lua[&lt;span style="color: #006080"&gt;&amp;quot;LUA_RUNTIME_OPERATION_RESULT&amp;quot;&lt;/span&gt;] = result;&lt;br /&gt;                lua.DoString(&lt;span style="color: #006080"&gt;&amp;quot;coroutine.resume(co)&amp;quot;&lt;/span&gt;);&lt;br /&gt;            });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Execute(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; script)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; coroutineWrapper =&lt;br /&gt;&lt;span style="color: #006080"&gt;@&amp;quot;co = coroutine.create(function() &lt;br /&gt;{0}&lt;br /&gt;end)&amp;quot;&lt;/span&gt;;&lt;br /&gt;        lua.DoString(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(coroutineWrapper, script));&lt;br /&gt;        lua.DoString(&lt;span style="color: #006080"&gt;&amp;quot;coroutine.resume(co)&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;    {&lt;br /&gt;        lua.Dispose();&lt;br /&gt;        functions.Dispose();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;When this class is instantiated it creates a new LuaInterface environment (the Lua class) and a new instance of a Functions class that I’ll explain below. &lt;/p&gt;

&lt;p&gt;The constructor is where most of the interesting setup happens. First we register two C# functions that we want to call from inside Lua: ‘print’ which simply prints from the console, and ‘startOperation’ which starts an asynchronous math operation.&lt;/p&gt;

&lt;p&gt;Next we define our three functions: ‘remoteAdd’, ‘remoteMultiply’ and ‘remoteDivide’ which all in turn invoke a common function ‘remoteOperation’. RemoteOperation calls the registered C# function ‘startOperation’ then yields the currently running coroutine. Effectively the script will stop here until it’s started again. After it starts, the result of the asynchronous operation is accessed from the&amp;#160; LUA_RUNTIME_OPERATION_RESULT variable and returned to the caller.&lt;/p&gt;

&lt;p&gt;The C# function StartOperation calls RunOperation on our Functions class which has an asynchronous callback. In the callback we set the result value in the Lua environment and execute ‘coroutine.resume’ which restarts the Lua script at the point where it yielded.&lt;/p&gt;

&lt;p&gt;The Execute function actually runs the script. First it embeds it in a ‘coroutine.create’ call so that the entire script is created as a coroutine, then it simply starts the coroutine by calling ‘coroutine.resume’.&lt;/p&gt;

&lt;p&gt;The Functions class is just a wrapper around a function that maintains an &lt;a href="http://easynetq.com"&gt;EasyNetQ&lt;/a&gt; connection to RabbitMQ and makes an EasyNetQ request to a remote server somewhere else on the network.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Functions : IDisposable&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; IBus bus;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Functions()&lt;br /&gt;    {&lt;br /&gt;        bus = RabbitHutch.CreateBus(&lt;span style="color: #006080"&gt;&amp;quot;host=localhost&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;    {&lt;br /&gt;        bus.Dispose();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RunOperation(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; a, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; b, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; operation, Action&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt; resultCallback)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (var channel = bus.OpenPublishChannel())&lt;br /&gt;        {&lt;br /&gt;            var request = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; OperationRequest()&lt;br /&gt;                {&lt;br /&gt;                    A = a,&lt;br /&gt;                    B = b,&lt;br /&gt;                    Operation = operation&lt;br /&gt;                };&lt;br /&gt;            channel.Request&amp;lt;OperationRequest, OperationResponse&amp;gt;(request, response =&amp;gt;&lt;br /&gt;                {&lt;br /&gt;                    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Got response {0}&amp;quot;&lt;/span&gt;, response.Result);&lt;br /&gt;                    resultCallback(response.Result);&lt;br /&gt;                });&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Print(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; msg)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;LUA&amp;gt; {0}&amp;quot;&lt;/span&gt;, msg);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;Here’s a sample run of the script:&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;DEBUG: Trying to connect&lt;br /&gt;DEBUG: OnConnected &lt;span style="color: #0000ff"&gt;event&lt;/span&gt; fired&lt;br /&gt;INFO: Connected to RabbitMQ. Broker: &lt;span style="color: #006080"&gt;'localhost'&lt;/span&gt;, Port: 5672, VHost: &lt;span style="color: #006080"&gt;'/'&lt;/span&gt;&lt;br /&gt;LUA&amp;gt; doing remote add ...&lt;br /&gt;DEBUG: Declared Consumer. queue=&lt;span style="color: #006080"&gt;'easynetq.response.143441ff-3635-4d5d-8e42-6b379b3f8356'&lt;/span&gt;, prefetchcount=50&lt;br /&gt;DEBUG: Published to exchange: &lt;span style="color: #006080"&gt;'easy_net_q_rpc'&lt;/span&gt;, routing key: &lt;span style="color: #006080"&gt;'Mike_DistributedLua_Messages_OperationRequest:Mike_DistributedLua_Messages'&lt;/span&gt;, correlationId: &lt;span style="color: #006080"&gt;'50560dd9-2be1-49a1-96f6-9c62641080ae'&lt;/span&gt;&lt;br /&gt;DEBUG: Recieved &lt;br /&gt;    RoutingKey: &lt;span style="color: #006080"&gt;'easynetq.response.143441ff-3635-4d5d-8e42-6b379b3f8356'&lt;/span&gt;&lt;br /&gt;    CorrelationId: &lt;span style="color: #006080"&gt;'50560dd9-2be1-49a1-96f6-9c62641080ae'&lt;/span&gt;&lt;br /&gt;    ConsumerTag: &lt;span style="color: #006080"&gt;'101343d9-9497-4893-88e6-b89cc1de29a4'&lt;/span&gt;&lt;br /&gt;Got response 11&lt;br /&gt;LUA&amp;gt; doing remote multiply ...&lt;br /&gt;DEBUG: Declared Consumer. queue=&lt;span style="color: #006080"&gt;'easynetq.response.f571f6d7-b963-4a88-bf62-f05785009e39'&lt;/span&gt;, prefetchcount=50&lt;br /&gt;DEBUG: Published to exchange: &lt;span style="color: #006080"&gt;'easy_net_q_rpc'&lt;/span&gt;, routing key: &lt;span style="color: #006080"&gt;'Mike_DistributedLua_Messages_OperationRequest:Mike_DistributedLua_Messages'&lt;/span&gt;, correlationId: &lt;span style="color: #006080"&gt;'0ea7e1c3-6f12-4cb9-a861-2f5de8f2600d'&lt;/span&gt;&lt;br /&gt;DEBUG: Model Shutdown &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; queue: &lt;span style="color: #006080"&gt;'easynetq.response.143441ff-3635-4d5d-8e42-6b379b3f8356'&lt;/span&gt;&lt;br /&gt;DEBUG: Recieved &lt;br /&gt;    RoutingKey: &lt;span style="color: #006080"&gt;'easynetq.response.f571f6d7-b963-4a88-bf62-f05785009e39'&lt;/span&gt;&lt;br /&gt;    CorrelationId: &lt;span style="color: #006080"&gt;'0ea7e1c3-6f12-4cb9-a861-2f5de8f2600d'&lt;/span&gt;&lt;br /&gt;    ConsumerTag: &lt;span style="color: #006080"&gt;'2c35f24e-7745-4475-885a-d214a1446a70'&lt;/span&gt;&lt;br /&gt;Got response 44&lt;br /&gt;LUA&amp;gt; doing remote divide ...&lt;br /&gt;DEBUG: Declared Consumer. queue=&lt;span style="color: #006080"&gt;'easynetq.response.060f7882-685c-4b00-a930-aa4f20f7c057'&lt;/span&gt;, prefetchcount=50&lt;br /&gt;DEBUG: Published to exchange: &lt;span style="color: #006080"&gt;'easy_net_q_rpc'&lt;/span&gt;, routing key: &lt;span style="color: #006080"&gt;'Mike_DistributedLua_Messages_OperationRequest:Mike_DistributedLua_Messages'&lt;/span&gt;, correlationId: &lt;span style="color: #006080"&gt;'ea9a90cc-cd7d-4f05-b171-c6849026ac4a'&lt;/span&gt;&lt;br /&gt;DEBUG: Model Shutdown &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; queue: &lt;span style="color: #006080"&gt;'easynetq.response.f571f6d7-b963-4a88-bf62-f05785009e39'&lt;/span&gt;&lt;br /&gt;DEBUG: Recieved &lt;br /&gt;    RoutingKey: &lt;span style="color: #006080"&gt;'easynetq.response.060f7882-685c-4b00-a930-aa4f20f7c057'&lt;/span&gt;&lt;br /&gt;    CorrelationId: &lt;span style="color: #006080"&gt;'ea9a90cc-cd7d-4f05-b171-c6849026ac4a'&lt;/span&gt;&lt;br /&gt;    ConsumerTag: &lt;span style="color: #006080"&gt;'90e6b024-c5c4-440a-abdf-cb9a000c131c'&lt;/span&gt;&lt;br /&gt;Got response 22&lt;br /&gt;LUA&amp;gt; 22&lt;br /&gt;DEBUG: Model Shutdown &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; queue: &lt;span style="color: #006080"&gt;'easynetq.response.060f7882-685c-4b00-a930-aa4f20f7c057'&lt;/span&gt;&lt;br /&gt;Completed&lt;br /&gt;DEBUG: Connection disposed&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;div&gt;You can see the Lua print statements interleaved with EasyNetQ DEBUG statements showing the messages being published and consumed.&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;So there you go, a distributed workflow scripting engine in under 100 lines of code. All I’ve got to do now is serialize the Lua environment at each yield and then restart it again from its serialized state. This is possible according to a bit of googling yesterday afternoon. Watch this space.&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;You can find the code for all this on GitHub here:&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;&lt;a href="https://github.com/mikehadlow/Mike.DistributedLua"&gt;https://github.com/mikehadlow/Mike.DistributedLua&lt;/a&gt;&lt;/div&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/0D3_2Hjtb4U/lua-as-distributed-workflow-scripting.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/04/lua-as-distributed-workflow-scripting.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-674161379490517626</guid><pubDate>Tue, 05 Mar 2013 08:52:00 +0000</pubDate><atom:updated>2013-03-05T08:52:38.097Z</atom:updated><title>Coders, Musicians and Cooks</title><description>&lt;p&gt;In a light hearted Twitter exchange yesterday I asked why so many coders also played guitar. Mark Seemann suggested that there was also a high correlation with cooking. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-vTPbxRI_rSo/UTWyTIz0AKI/AAAAAAAAHk4/OIp1Mqp9L_s/s1600-h/code_play_cook_tweet%25255B4%25255D.png"&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="code_play_cook_tweet" border="0" alt="code_play_cook_tweet" src="http://lh6.ggpht.com/-4Q6iG7idYx0/UTWyT96F_OI/AAAAAAAAHk8/xWYW3WSh4Xs/code_play_cook_tweet_thumb%25255B2%25255D.png?imgmax=800" width="534" height="237" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;How about a survey? Mark and I have over 4000 twitter followers between us so I was sure we could get a few of them to click a few radio buttons, with no promise of reward, but with the warm feeling that they were helping to progress the anthropological understanding of the coding tribe. So I &lt;a href="https://docs.google.com/a/suteki.co.uk/forms/d/1I_UwVA8XK6HE-8AvFnyn8EJSeryCs-CNS1qC-f-u5u8/viewform"&gt;created a survey&lt;/a&gt; and waited for the results to stream in. Of course, as Rob Pickering pointed out, this kind of self selecting survey is very unscientific, but fun nonetheless.&lt;/p&gt;  &lt;p&gt;What have we learnt?&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;It is ridiculously easy to create an online survey using Google Drive. Just click ‘new form’, type in a few questions, and Bob’s yer uncle. It automatically builds a nice summary graphic on the fly as the survey progresses (see below).&lt;/li&gt;    &lt;li&gt;Most of Mark and I’s followers are C# coders. 81%. That’s not really surprising.&lt;/li&gt;    &lt;li&gt;More coders cook than play musical instruments: 85% verses 53%. That’s not really surprising either. I expect if you took a survey of the general population you’d find quite a high percentage who cook verses those who play.&lt;/li&gt;    &lt;li&gt;Guitar is by far the most popular instrument among coders. 30% play guitar. This confirms my hunch, but doesn’t answer my question – why it’s such a high percentage.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here is the Google Drive graphic of the results.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-9TVsHDsnQC8/UTWyUvhhVDI/AAAAAAAAHlE/aogMkMHsSgs/s1600-h/code_play_cook_survey%25255B4%25255D.png"&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="code_play_cook_survey" border="0" alt="code_play_cook_survey" src="http://lh5.ggpht.com/-TRrvgW2MSUc/UTWyVOxHjqI/AAAAAAAAHlI/dJqEUMw2TJo/code_play_cook_survey_thumb%25255B2%25255D.png?imgmax=800" width="676" height="927" /&gt;&lt;/a&gt;&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/1_tUiKiAwP8/coders-musicians-and-cooks.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-4Q6iG7idYx0/UTWyT96F_OI/AAAAAAAAHk8/xWYW3WSh4Xs/s72-c/code_play_cook_tweet_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/03/coders-musicians-and-cooks.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-426855837964499199</guid><pubDate>Wed, 27 Feb 2013 17:00:00 +0000</pubDate><atom:updated>2013-02-27T17:00:00.824Z</atom:updated><title>Fractured Product Syndrome</title><description>&lt;p&gt;How do you sell your software product? Do you fork the source code of your previous customer, modify it a little and deploy it as its own instance with its own database? Maybe each customer even has their own server? Their own set of servers? &lt;/p&gt;  &lt;p&gt;You are suffering from the &lt;em&gt;Fractured Product Syndrome&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Let me tell you a story. &lt;/p&gt;  &lt;p&gt;Colin and Alex have a little web development consultancy, called Coaltech (get it?) they are pretty handy with ASP.NET and SQL Server and already had a respectable list of satisfied clients when a local car hire company, Easy Wheels, asked them if they could build them a car booking system. It would keep a list of Easy Wheels’ cars and allow customers to view them and book them online.&lt;/p&gt;  &lt;p&gt;Colin and Alex signed a contract with Easy Wheels and got busy. Their “just do it” attitude to getting features done meant that the code wasn’t particularly beautiful, but it did the job and after a couple of months work the system went live. Easy Wheels were very happy with their new system, so happy in fact that they started to tell other independent car rental companies about it. A few months later Colin and Alex got a call from Hire My Ride. They loved what Coaltech had done for Easy Wheels and wanted a similar system. Of course it would have to be redesigned to fit in with Hire My Ride’s branding, but the basic functionality was pretty much identical. Colin and Alex did the obvious thing, they took a copy of the Easy Wheels code and tweaked it for Hire My Ride. Of course they charged the same bespoke software price for Hire My Ride’s system.&lt;/p&gt;  &lt;p&gt;Soon a third and fourth car hire company had asked Coaltech for their ‘system’. Each time Colin and Alex took a copy of the last customer’s code – it made sense to take the most recent code because they inevitably added a few refinements with each customer – and then they altered it to match the new customer’s requirements. Before long they had arranged a deal with another web agency to take over all their non-car-hire work and decided to concentrate full time on the ‘system’. It needed a name too, they couldn’t carry on calling it ‘Easy Wheels’ and they certainly couldn’t market it like that. Soon it became ‘Coaltech Cars’ with a new marketing website. They also found that they couldn’t keep up with demand with just the two of them doing customer implementations. Each new customer took around six weeks of development work with the inevitable to-and-fro of slightly different requirements and design changes. To help meet demand they started to hire developers. First Jez, then Dave, then Neville. They all modified the software in slightly different ways, but it didn’t seem to matter at the time.&lt;/p&gt;  &lt;p&gt;Fast forward five years. Coaltech now has 50 employees and around 50 customers. It’s fair to say that they are the leading vendor of independent car rental management systems. The majority of their staff are developers, although they also have a small sales, HR and customer relationship management team. You would have thought that Colin and Alex would be happy to have turned their little web development company into such a success, but instead life just seemed to be one long headache. Although the company had grown, it always seemed hard to turn a profit. As it was customers often balked at the price of the system. The same bug would turn up again and again for different customers. There never seemed to be enough time to fix them all. Even though they might have delivered a new feature for one client, it always seemed to take just as long to implement it for another; sometimes longer depending on what code they’d been forked from. The small team that looked after the servers were in constant fire fighting mode and got very upset when anyone suggested ‘upgrading’ any of the clients -&amp;#160; it always meant bugs, downtime and screaming customers. And then the government changed the Value Added Tax rate. Colin had to cancel his holiday and they lost two of their best developers after several weeks of late nights and no weekends while they updated and redeployed 50 separate web applications.&lt;/p&gt;  &lt;p&gt;The end for Coaltech cars came slowly and painfully. Alex had the first hint of it when he was made aware of a little company called RentBoy. They had a little software-as-a-service product for small car hire companies. To use it you entered your credit card number, a logo, a few other details, and you were good to go. They weren’t any immediate competition for Coaltech Cars, having only a small subset of the features, but they soon captured the low end of the market, the one or two man band car companies that had never been able to afford Coaltech’s sign up or licensing fees. &lt;/p&gt;  &lt;p&gt;But then the features started coming thick and fast and soon Coaltech found they were loosing out to RentBoy when bidding for clients. Colin found an article on the &lt;a href="http://highscalability.com/"&gt;High Scalability&lt;/a&gt; blog about RentBoy’s architecture. They had a single scalable application that served all their customers, one place to fix bugs, one point of scalability and maintenance. They practiced continuous deployment allowing them to quickly build and release new features for all their customers. The company had four employees and already more customers than Coaltech. They charged about a tenth of Coaltech’s fees.&lt;/p&gt;  &lt;p&gt;Coaltech’s new client revenues soon dried up. They’d always made a certain amount of money from sign-up fees. Too late they realised that they had to start shedding staff, always a painful thing for a small closely knit company. The debts mounted until the bank would no longer support them, and before long they had to declare bankruptcy. Luckily Colin and Alex managed to get jobs as project managers in enterprise development teams.&lt;/p&gt;  &lt;p&gt;The moral of the story? Try to avoid Fractured Product Syndrome if you possibly can. Although simply forking the source code for each new customer appears by far the easiest thing to do at the start, it simply doesn’t scale. Start thinking about how to build multi-tenanted software-as-a-service long before you get to where Coaltech got to. Learn to say ‘no’ to customers if you have to. It’s far better to have a high number of low value customers than smaller numbers of higher value ones on a differentiated platform. It’s much easier for a low-value volume software provider to move into the high-value space than for a high-value provider to move down. &lt;/p&gt;  &lt;p&gt;Learn to recognise Fractured Product Syndrome and address it before it gets serious!&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/dMaC7-XpyJ4/fractured-product-syndrome.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>3</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/02/fractured-product-syndrome.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-1220279201940817253</guid><pubDate>Thu, 21 Feb 2013 12:39:00 +0000</pubDate><atom:updated>2013-02-21T12:39:59.548Z</atom:updated><title>EasyNetQ on .NET Rocks!</title><description>&lt;p&gt;&lt;a href="http://www.dotnetrocks.com/Default.aspx"&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="dotnetrocks" border="0" alt="dotnetrocks" src="http://lh6.ggpht.com/-ISTHxvDBQ14/USYVnvKVGUI/AAAAAAAAHb4/8cpFxClQo2k/dotnetrocks%25255B5%25255D.png?imgmax=800" width="493" height="134" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Last week I had the pleasure of being interviewed by Carl Franklin and Richard Campbell for a .NET Rocks episode on RabbitMQ and EasyNetQ. It was terrific fun and a real honour to be invited on the show. I’ve been listening to .NET Rocks since it started in 2002 so you can imagine how excited I was. Carl and Richard are seasoned pros when it comes to podcasting, and the awesome ninja editing skills they posses turned my rather hesitant and rambling answers into something that almost sounded coherent. &lt;/p&gt;  &lt;p&gt;You can listen to the show on the link below:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetrocks.com/default.aspx?ShowNum=848"&gt;http://www.dotnetrocks.com/default.aspx?ShowNum=848&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now Richard, about that Tesla …&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/gpnjgNAyH9k/easynetq-on-net-rocks.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-ISTHxvDBQ14/USYVnvKVGUI/AAAAAAAAHb4/8cpFxClQo2k/s72-c/dotnetrocks%25255B5%25255D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/02/easynetq-on-net-rocks.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-5565169786573044043</guid><pubDate>Wed, 06 Feb 2013 10:53:00 +0000</pubDate><atom:updated>2013-02-06T10:53:01.184Z</atom:updated><title>EasyNetQ in Africa</title><description>&lt;p&gt;Anthony Moloney got in touch with me recently. He’s using &lt;a href="http://easynetq.com/"&gt;EasyNetQ&lt;/a&gt;, my simple .NET API for RabbitMQ, with his team in Kenya. Here’s an email he sent me:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Hi Mike,&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Further to the brief twitter exchange today about using EasyNetQ on our Kenyan project. We started using EasyNetQ back in early November and I kept meaning to drop you a line to thank you for all your good work.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Virtual City are based in Nairobi and supply mobile solutions to the supply chain and agribusiness industry in Africa. African solutions for African problems. I got involved with them about 2 years ago to help them improve the quality of their products and I have been working on and off with them since then. Its been a bit of a journey we are getting there.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;We have a number of client applications including android and wpf working in an online/offline mode over mobile networks. We need to process large amounts of incoming commands from these applications. These commands are also routed via the server to other client apps. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;The application had originally used MVC and SQL server to synchronously process and store the commands but we were running into severe performance problems. We looked at various MQ solutions and decided to use RabbitMQ, WebApi &amp;amp; Mongo to improve processing throughput. While researching a .Net API for RabbitMQ I noticed that you had created the EasyNetQ API. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;EasyNetQ greatly simplifies interacting with RabbitMQ and providing your needs are not too complicated you really don't need to know too much about the guts of RabbitMQ. We replaced the existing server setup in about a week. The use of RabbitMQ has greatly increased the scalability of the product and allows us to either scale up or scale out. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;We are also using the EasyNetQ management API for monitoring queue activity on our customer services dashboard.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Kind Regards&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Anthony Moloney&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;One of the great rewards of running an open source project is hearing about the fascinating ways that it’s used around the world. I really like that it’s an ‘African solution for African problems’ and built by a Kenyan development team. It’s also interesting that they’ve used OSS projects like RabbitMQ and Mongo alongside .NET. It reminds me of the &lt;a href="http://highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html"&gt;Stack Overflow architecture&lt;/a&gt;, a .NET core surrounded by OSS infrastructure.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/EKZZ3koif_4/easynetq-in-africa.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>3</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/02/easynetq-in-africa.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-9107998146492466530</guid><pubDate>Fri, 01 Feb 2013 13:02:00 +0000</pubDate><atom:updated>2013-02-01T13:02:56.272Z</atom:updated><title>How to Write Scalable Services</title><description>&lt;p&gt;&lt;img alt="SDO_arch" src="http://www.slate.com/content/dam/slate/blogs/bad_astronomy/2012/12/best_of_2012_photos/SDO_arch.jpg.CROP.article920-large.jpg" width="613" height="347" /&gt;&lt;/p&gt;  &lt;p&gt;I’ve spent the last five years implementing and thinking about service oriented architectures. One of the core benefits of a service oriented approach is the promise of greatly enhanced scalability and redundancy. But to realise these benefits we have to write our services to be ‘scalable’. What does this mean?&lt;/p&gt;  &lt;p&gt;There are two fundamental ways we can scale software: 'Vertically' or 'horizontally'.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Vertical Scaling&lt;/strong&gt; addresses the scalability of a single instance of the service. A simple way to scale most software is simply to run it on a more powerful machine; one with a faster processor or more memory. We can also look for performance improvements in the way we write the code itself. An excellent example of company using this approach is &lt;a href="http://martinfowler.com/articles/lmax.html"&gt;LMAX&lt;/a&gt;. However, there are many drawbacks to the vertical scaling approach. Firstly the costs are rarely linear; ever more powerful hardware tends to be exponentially more expensive and the costs (and constraints) of building sophisticated performance optimised software are also considerable. Indeed premature performance optimisation often leads to overly complex software that's hard to reason about and therefore more prone to defects and high maintenance costs. Most importantly, vertical scaling does not address redundantcy; vertically scaling an application just turns a small single point of failure into a large single point of failure.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Horizontal Scaling.&lt;/strong&gt; Here we run multiple instances of the application rather than focussing on the performance of a single instance. This has the advantage of being linearly scalable; rather than buying a bigger, more expensive box, we just buy more copies of the same cheap box. With the right architectural design, this approach can scale massively. Indeed it's the approach taken by almost all of largest internet scale companies: Facebook, Google, Twitter etc.. Horizontal Scaling also introduces redundancy; the loss of a single node need not impact the system as a whole. For these reasons, horizontal scaling is the preferred approach to building scalable, redundant systems.&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, the fundamental approach to building scalable systems is to compose them of horizontally scaled services. In order to do this we need to follow a few basic principles:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Stateless.&lt;/strong&gt; Any services that stores state across an interaction with another service is hard to scale. For example, a web service that stores in-memory session state between requests requires a sophisticated session-aware load balancer. A stateless service, by contrast, only requires simple round-robin load balancing. For a web application (or service) you should avoid using session state or any static or application level variables.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Coarse Grained API.&lt;/strong&gt; To be stateless, a service should expose an API that exposes operations as a single interaction. A chatty API, where one sets up some data, asks for some transition, and then reads off some results, implies statefulness by its design. The service would need to identify a session and then maintain information about that session between successive calls. Instead a single call, or message, to the service should encapsulate all the information that the service requires to complete the operation.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Idempotent.&lt;/strong&gt; Much scalable infrastructure is a trade-off between competing constraints. Delivery guarantees are one of these. For various reasons it's is far simpler to guarantee 'at least once' delivery than 'exactly once'. If you can make your software tolerant of multiple deliveries of the same message it will be easier to scale.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Embrace Failure.&lt;/strong&gt; Arrays of services are redundant if the system as a whole can survive the loss of a single node. You should design your services and infrastructure to expect and survive failure. Consider implementing a &lt;a href="http://www.codinghorror.com/blog/2011/04/working-with-the-chaos-monkey.html"&gt;Chaos Monkey&lt;/a&gt; that randomly kills processes. If you start by expecting your services to fail, you'll be prepared when they inevitably do.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Avoid instance specific configuration.&lt;/strong&gt; A scalable service should be designed in such a way that it doesn't need to know about other instances of itself, or have to identify itself as a specific instance. I shouldn't need to have to configure one instance any differently than another. This would include communication mechanisms that require messages to be addressed to a specific instance of the service, or some non-convention based way that the service was required to identify itself. Instead we should rely on infrastructure (load-balancers, pub-sub messaging etc.) to manage the communication between arrays of services.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Simple automated deployment.&lt;/strong&gt; Have a service that can scale is no advantage if we can't deploy it when we are close to capacity. A scalable system must have automated processes to deploy new instances of services as the need arises.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;Monitoring.&lt;/strong&gt; We need to know when services are close to capacity so that we can add additional service instances. Monitoring is usually an infrastructure concern; we should be monitoring CPU, network, and memory usage and have alerts in place to warn us when these pass certain trigger points. Sometimes it's worth introducing application specific alerts when some internal trigger is reached, such as the number of items in an in-memory queue, for example.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;&lt;strong&gt;KISS - Keep It Small and Simple.&lt;/strong&gt; This is good advice for any software project, but is especially pertinent to building scalable resilient systems. Large monolithic codebases are hard to reason about, hard to monitor, and hard to scale. Building your system out of many small pieces makes it easy to address those pieces independently. Design your system so that each service has only one purpose and is decoupled from the operations of other services. Have your services communicate using non-proprietary open standards to avoid vendor lock-in and allow for a heterogeneous platform. JSON over HTTP, for example, is an excellent choice for intra-service communication. Every platform has HTTP and JSON libraries and there is abundant off-the-shelf infrastructure (proxies, load-balancers, caches) that can be used to help your system scale.&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This post just gives a few pointers to building scalable systems, for far more detailed examples and case studies I can't recommend the &lt;a href="http://highscalability.com/"&gt;High Scalability Blog&lt;/a&gt; enough. The Dodgy Coder blog has a very nice summary of some of the High Scalability case studies &lt;a href="http://www.dodgycoder.net/2012/04/scalability-lessons-from-google-youtube.html"&gt;here&lt;/a&gt;.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/w2haGYxhroM/how-to-write-scalable-services.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/02/how-to-write-scalable-services.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-8653772548183634396</guid><pubDate>Thu, 31 Jan 2013 12:38:00 +0000</pubDate><atom:updated>2013-01-31T12:38:52.575Z</atom:updated><title>Visual Studio: Multiple Startup Projects</title><description>&lt;p&gt;I’ve been using Visual Studio for over 10 years, but still keep on learning new tricks. That’s because I learn things very slowly dear reader! Today’s ‘wow, I didn’t know you could do that moment’, was finding out that it’s possible to launch multiple startup projects when one hits F5 – or Control-F5 in this case.&lt;/p&gt;  &lt;p&gt;My scenario is that I’m writing a little spike for a distributed application. Each of my services is implemented as a console app. During development, I want to run integration tests where the services all talk to each other, so before running the tests I want to run all the services. Now I’m used to right-clicking on a project and choosing ‘Set as startup project’, but you can’t select multiple projects this way and it’s very tedious to launch multiple projects by going to each one in turn, setting it as the startup project, and then hitting ctrl-F5. What I didn’t know is that you can right click on the Solution node, select ‘Set Startup Projects’ and you get this dialogue:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-GscZjVsqo2M/UQpl1qMA67I/AAAAAAAAG9M/D9FkbqYHm0k/s1600-h/Select_startup_project%25255B4%25255D.png"&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="Select_startup_project" border="0" alt="Select_startup_project" src="http://lh6.ggpht.com/-r6SuOviKoFc/UQpl2WvmBcI/AAAAAAAAG9U/dYOR3PYTc4M/Select_startup_project_thumb%25255B2%25255D.png?imgmax=800" width="782" height="491" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;You can then select multiple startup projects and choose any number of them to ‘Start without debugging’.&lt;/p&gt;  &lt;p&gt;Now I can hit ctrl-F5 and all my little services start up. Wonderful.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/0QZ30Nx84Po/visual-studio-multiple-startup-projects.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-r6SuOviKoFc/UQpl2WvmBcI/AAAAAAAAG9U/dYOR3PYTc4M/s72-c/Select_startup_project_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/01/visual-studio-multiple-startup-projects.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-9214071701331545491</guid><pubDate>Wed, 16 Jan 2013 15:31:00 +0000</pubDate><atom:updated>2013-01-16T15:31:31.434Z</atom:updated><title>Converting Between Unix Time And DateTime</title><description>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Unix_time"&gt;Unix time&lt;/a&gt; is the time value used in Unix based operating systems and is often exposed by Unix based APIs. To convert it to, or from, a .NET System.DateTime simply calculate the number of seconds since the Unix Epoch, midnight on the 1st January 1970. I’ve created a little class you can use to do just that. Note that the Unix Epoch is UTC, so you should always convert your local time to UTC before doing the calculation.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; UnixTime&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; DateTime epoch = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; FromDateTime(DateTime dateTime)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (dateTime.Kind == DateTimeKind.Utc)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;long&lt;/span&gt;)dateTime.Subtract(epoch).TotalSeconds;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color: #006080"&gt;&amp;quot;Input DateTime must be UTC&amp;quot;&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; DateTime ToDateTime(&lt;span style="color: #0000ff"&gt;long&lt;/span&gt; unixTime)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; epoch.AddSeconds(unixTime);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; Now&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; FromDateTime(DateTime.UtcNow);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;You can convert from Unix time to a UTC DateTime like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; calculatedCurrentTime = UnixTime.ToDateTime(currentUnixTime);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;Convert to Unix time from a UTC DateTime like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; calculatedUnixTime = UnixTime.FromDateTime(myDateTimeValue);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;And get the current time as a UTC time value like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;Console.Out.WriteLine(UnixTime.Now);&lt;/pre&gt;
&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div&gt;As an interesting aside, the 32 bit signed integer used in older Unix systems will overflow at 14 minutes past 3 o’clock and 7 seconds on the morning of 19th January 2038 and interpret the date as 1901. I shall come out of retirement and spend happy well paid hours as a ‘unix time consultant’. 64 bit systems will overflow in the year 292,277,026,596.&lt;/div&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/6NOQjtpe1Eg/converting-between-unix-time-and.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>5</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2013/01/converting-between-unix-time-and.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-1969169933372580753</guid><pubDate>Mon, 24 Dec 2012 12:56:00 +0000</pubDate><atom:updated>2012-12-24T15:51:11.480Z</atom:updated><title>A Geek Christmas Quiz–The Answers!</title><description>&lt;p&gt;Thanks for everyone who had a go at my &lt;a href="http://mikehadlow.blogspot.co.uk/2012/12/a-geek-christmas-quiz.html"&gt;Geek Christmas Quiz&lt;/a&gt;. The response was fantastic with both &lt;a href="https://twitter.com/iainholder"&gt;Iain Holder&lt;/a&gt; &lt;em&gt;and&lt;/em&gt; &lt;a href="https://twitter.com/robertpi"&gt;Rob Pickering&lt;/a&gt; sending me emails of their answers. I’m pretty sure neither of them Googled any of the questions, since their scores weren’t spectacular :)&lt;/p&gt;  &lt;p&gt;So, now the post you’ve all been waiting for with such anticipation… the answers!&lt;/p&gt;  &lt;h3&gt;Computers&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;G.N.U stands for &lt;a href="http://en.wikipedia.org/wiki/GNU_project"&gt;GNU is Not Unix&lt;/a&gt;. A recursive acronym, how geeky is that? &lt;/li&gt;    &lt;li&gt;The A in ARM &lt;em&gt;originally &lt;/em&gt;stood for ‘Acorn’ as in &lt;a href="http://en.wikipedia.org/wiki/ARM_architecture"&gt;Acorn Risc Machine&lt;/a&gt;. Yes, I know it stands for ‘Advanced’ now, but the question said ‘originally’. &lt;/li&gt;    &lt;li&gt;TCP stands for &lt;a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol"&gt;Transmission Control Protocol&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Paul_Allen"&gt;Paul Allen&lt;/a&gt; founded Microsoft with Bill&amp;#160; Gates. I’ve just finished reading his memoirs ‘Ideas Man’. Hard work! &lt;/li&gt;    &lt;li&gt;F2 (hex) is 15(F) * 16 + 2 = 242.&amp;#160; 1111 0010 (binary) &lt;/li&gt;    &lt;li&gt;Windows ME was based on the &lt;a href="http://xkcd.com/323/"&gt;Balmer Peak&lt;/a&gt; theory of software development. &lt;/li&gt;    &lt;li&gt;The first programmer was &lt;a href="http://en.wikipedia.org/wiki/Ada_Lovelace"&gt;Ada Lovelace.&lt;/a&gt; Yes yes, I know that’s contentious, but I made up this quiz, so there! &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Unix_time"&gt;UNIX time started in 1970&lt;/a&gt; (1st January to be exact). I know this because I just had to write a System.DateTime to UNIX time converter. &lt;/li&gt;    &lt;li&gt;SGI, the mostly defunct computer maker. You get a mark for &lt;a href="http://en.wikipedia.org/wiki/Silicon_Graphics_International"&gt;Silicon Graphics International&lt;/a&gt; (or Inc). &lt;/li&gt;    &lt;li&gt;Here’s monadic ‘&lt;a href="http://mikehadlow.blogspot.co.uk/2011/01/monads-in-c-3-creating-our-first-monad.html"&gt;Bind&lt;/a&gt;’ in C#: M&amp;lt;B&amp;gt; Bind&amp;lt;A,B&amp;gt;(M&amp;lt;A&amp;gt; a, Func&amp;lt;A, M&amp;lt;B&amp;gt;&amp;gt; func) &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Name That Geek!&lt;/h3&gt;  &lt;p&gt;&lt;img alt="[Name_that_geek%255B4%255D.png]" src="http://lh4.ggpht.com/-9dCdTenpfew/UNRJrz8wCHI/AAAAAAAAF20/F-jPxSUS0CE/s1600/Name_that_geek%25255B4%25255D.png" /&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Bill Gates – Co-founder of Microsoft with Paul Allen. &lt;/li&gt;    &lt;li&gt;Tim Berners-Lee – Creator of the World Wide Web. &lt;/li&gt;    &lt;li&gt;Larry Ellison – Founder of Oracle. Lives in a Samurai House (how geeky is that?) &lt;/li&gt;    &lt;li&gt;Linus Torvalds – Creator of Linux. &lt;/li&gt;    &lt;li&gt;Alan Turing – Mathematician and computer scientist. Described the Turing Machine. Helped save the free world from the Nazis. &lt;/li&gt;    &lt;li&gt;Steve Jobs – Founded Apple, NeXT and Pixar. &lt;/li&gt;    &lt;li&gt;Natalie Portman – Actress and self confessed geek. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Science&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;The four ‘letters’ of &lt;a href="http://en.wikipedia.org/wiki/DNA"&gt;DNA&lt;/a&gt; are C, G, T and A. If you know the actual names of the nucleotides (guanine, adenine, thymine, and cytosine), give yourself a bonus point – you really are a DNA geek! &lt;/li&gt;    &lt;li&gt;The ‘c’ in &lt;a href="http://en.wikipedia.org/wiki/Mass%E2%80%93energy_equivalence"&gt;E = mc&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; is a constant, the speed of light. &lt;/li&gt;    &lt;li&gt;The next number in the &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Fibonacci&lt;/a&gt; sequence 1 1 2 3 5 8 is 13 (5 + 8). &lt;/li&gt;    &lt;li&gt;C&lt;sub&gt;8&lt;/sub&gt;H&lt;sub&gt;10&lt;/sub&gt;N&lt;sub&gt;4&lt;/sub&gt;0&lt;sub&gt;2&lt;/sub&gt; is the chemical formula for &lt;a href="http://en.wikipedia.org/wiki/Caffeine"&gt;caffeine&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;According to Wikipedia, &lt;a href="http://en.wikipedia.org/wiki/Australopithecus"&gt;Australopithecus&lt;/a&gt;, the early hominid, became extinct around 2 million years ago. &lt;/li&gt;    &lt;li&gt;You would not find an electron in an &lt;a href="http://en.wikipedia.org/wiki/Atomic_nucleus"&gt;atomic nucleus&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Nitrogen is the most common gas in the &lt;a href="http://en.wikipedia.org/wiki/Atmosphere_of_Earth"&gt;Earth’s atmosphere&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;The formula for &lt;a href="http://en.wikipedia.org/wiki/Ohm's_law"&gt;Ohm’s Law&lt;/a&gt; is I = V/R (current = voltage / resistance). &lt;/li&gt;    &lt;li&gt;A piece of paper that, when folded in half, maintains the ratio between the length of its sides, has sides with a length ratio of 1.618, ‘&lt;a href="http://en.wikipedia.org/wiki/Golden_ratio"&gt;the golden ratio&lt;/a&gt;’. Did you know that &lt;a href="http://en.wikipedia.org/wiki/Golden_ratio#Relationship_to_Fibonacci_sequence"&gt;the ratio between successive Fibonacci sequence numbers also tends to the golden ratio&lt;/a&gt;? Maths is awesome! &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Evolution_of_cetaceans"&gt;The closest living land mammal to the cetaceans (including whales) is the Hippopotamus&lt;/a&gt;. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Space&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;The second (and third) stage of the Apollo Saturn V moon rocket was powered by five &lt;a href="http://en.wikipedia.org/wiki/J-2_(rocket_engine)"&gt;J2 rocket engine&lt;/a&gt;s. &lt;/li&gt;    &lt;li&gt;Saturn’s largest moon is &lt;a href="http://en.wikipedia.org/wiki/Titan_(moon)"&gt;Titan&lt;/a&gt;. Also the only moon in the solar system (other than our own) that a spaceship has landed on. &lt;/li&gt;    &lt;li&gt;You would experience &lt;a href="http://en.wikipedia.org/wiki/Gravitation_of_the_Moon"&gt;1/6th of the Earth’s gravity on the moon&lt;/a&gt;. Or there about. &lt;/li&gt;    &lt;li&gt;This question proved most contentious. The answer is &lt;em&gt;false&lt;/em&gt;, there is nowhere in space that has no gravity. Astronauts are weightless because they are in free-fall. Gravity itself is a property of space. &lt;/li&gt;    &lt;li&gt;A &lt;a href="http://en.wikipedia.org/wiki/Geosynchronous_orbit"&gt;Geosynchronous&lt;/a&gt; spaceship has an orbital period of 24 hours. So it appears to be stationary to a ground observer. &lt;/li&gt;    &lt;li&gt;The furthest planet from the sun is &lt;a href="http://en.wikipedia.org/wiki/Neptune"&gt;Neptune&lt;/a&gt;. Far fewer people know this, than know that Pluto &lt;em&gt;used to be&lt;/em&gt; the furthest planet from the sun. Actually Pluto was only the furthest for part of it’s, irregular, orbit. &lt;/li&gt;    &lt;li&gt;There are currently 6 people aboard the &lt;a href="http://www.nasa.gov/mission_pages/station/expeditions/index.html"&gt;International Space Station&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;According to Google (yes, I know) there are 13,000 &lt;a href="http://www.gearthblog.com/satellites.html"&gt;earth satellites&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Prospero_(satellite)"&gt;Prospero&lt;/a&gt; was the only satellite built and launched by the UK. It was launched by stealth after the programme had been cancelled, that’s the way we do things in the UK. &lt;/li&gt;    &lt;li&gt;The second man on the moon was &lt;a href="http://en.wikipedia.org/wiki/Buzz_Aldrin"&gt;Buzz Aldrin&lt;/a&gt;. He’s never forgiven NASA. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Name That Spaceship!&lt;/h3&gt;  &lt;p&gt;&lt;img alt="[Name_that_spaceship%255B4%255D.png]" src="http://lh4.ggpht.com/-hGzbsIuQB90/UNRJuMs_n_I/AAAAAAAAF3A/HI6dV7Jr0ic/s1600/Name_that_spaceship%25255B4%25255D.png" /&gt;&lt;/p&gt;  &lt;p&gt;In this round, give yourself a point if you can name the film or TV series the fictional spacecraft appeared in.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Red_Dwarf"&gt;Red Dwarf&lt;/a&gt;. Sorry, you probably have to be British to get this one. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Space:_1999"&gt;Space 1999&lt;/a&gt;. Sorry, you really have to be British &lt;em&gt;and&lt;/em&gt; over 40 to get this one … or a major TV space geek. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Voyager_program"&gt;Voyager&lt;/a&gt;. Difficult, interplanetary probes all look similar. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Apollo_Lunar_Module"&gt;Apollo Lunar Excursion Module&lt;/a&gt; (LEM). You can have a point for ‘Lunar Module’, but no, you don’t get a point for ‘Apollo’. Call yourself a geek? &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Skylab"&gt;Skylab&lt;/a&gt;. The first US space station, made out of old Apollo parts. Not many people get this one. A read a whole book about it, that’s how much of a space geek I am. &lt;/li&gt;    &lt;li&gt;Darth Vader’s TIE fighter. You can have a point for ‘TIE Fighter’. You can’t have a point for ‘Star Wars’. Yes yes, I know I’m contradicting myself, but, come on, &lt;em&gt;every&lt;/em&gt; geek should know this. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Curiosity_rover"&gt;Curiosity&lt;/a&gt;. No, no points for ‘Mars Rover’. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/2001:_A_Space_Odyssey_(film)"&gt;2001 A Space Odyssey&lt;/a&gt;. Even I don’t know what the ship is called. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Soyuz_(spacecraft)"&gt;Soyuz&lt;/a&gt;. It’s been used by the Russians to travel into space since 1966. 46 years! It’s almost as old as me. Odd, when space travel is so synonymous with high-technology, that much of the hardware is actually ancient. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Geek Culture&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;‘Spooky’ Mulder was the agent in the &lt;a href="http://en.wikipedia.org/wiki/The_X-Files"&gt;X-Files&lt;/a&gt;, played by actor &lt;a href="http://en.wikipedia.org/wiki/David_Duchovny"&gt;David Duchovny&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;Kiki is the &lt;em&gt;trainee witch&lt;/em&gt; in ‘&lt;a href="http://en.wikipedia.org/wiki/Kiki's_Delivery_Service"&gt;Kiki’s Delivery Service&lt;/a&gt;’, one of my favourite anime movies by the outstanding &lt;a href="http://en.wikipedia.org/wiki/Studio_Ghibli"&gt;Studio Ghibli&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;The actual quote: “&lt;a href="http://www.youtube.com/watch?v=IM1-DQ2Wo_w"&gt;Humans are a disease&lt;/a&gt;, a cancer of this planet.” by Agent Smith. You can have a point for Virus or Cancer too. Thanks Chris for the link and clarification. &lt;/li&gt;    &lt;li&gt;Spiderman of course! &lt;/li&gt;    &lt;li&gt;“It’s a Banana” &lt;a href="http://www.youtube.com/watch?v=oB-NnVpvQ78"&gt;Kryten, of Red Dwarf, learns to lie&lt;/a&gt;. &lt;/li&gt;    &lt;li&gt;My wife, who is Japanese, translates ‘&lt;a href="http://en.wikipedia.org/wiki/Otaku"&gt;Otaku&lt;/a&gt;’ as ‘geek’. Literally it means ‘you’ and is used to describe someone with obsessive interests. An appropriate question for a geek quiz I think. &lt;/li&gt;    &lt;li&gt;The name &lt;a href="http://en.wikipedia.org/wiki/R2-D2"&gt;R2D2&lt;/a&gt;&amp;#160; apparently came about when Lucas heard someone ask for Reel 2 Dialog Track 2 in the abbreviated form ‘R-2-D-2’. Later it was said to stand for Second Generation Robotic Droid Series 2, you can have a point for either. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Clarke's_three_laws"&gt;Clarke’s 3rd law&lt;/a&gt; states: “Any sufficiently advanced technology is indistinguishable from magic.” &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=4b4bGAoVR7g"&gt;African or European&lt;/a&gt;? From Monty Python’s Holy Grail. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=dSIKBliboIo"&gt;Open the pod bay doors please HAL&lt;/a&gt;. 2001 A Space Odyssey. &lt;a href="http://www.youtube.com/watch?v=3_CZswausC4"&gt;Or on acid here&lt;/a&gt;. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So there you are. I hope you enjoyed it, and maybe even learnt a little. I certainly did. I might even do it again next year.&lt;/p&gt;  &lt;p&gt;A very Merry Christmas to you all!&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/PhowE4MXuAI/a-geek-christmas-quizthe-answers.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-9dCdTenpfew/UNRJrz8wCHI/AAAAAAAAF20/F-jPxSUS0CE/s72-c/Name_that_geek%25255B4%25255D.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/12/a-geek-christmas-quizthe-answers.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-4649953361837336626</guid><pubDate>Fri, 21 Dec 2012 11:36:00 +0000</pubDate><atom:updated>2012-12-24T12:59:24.752Z</atom:updated><title>A Geek Christmas Quiz</title><description>&lt;p&gt;God rest ye merry gentlemen! Welcome to my 2012 Geek Christmas Quiz. Every Friday morning at 15below we have a ‘DevEd’ session. Usually this is a presentation about some interesting tech, or a new way we want to do something at the company, but today I thought I would try to gauge the true geekiness of our development team with a quiz. The winners, and therefore crowned top geeks, were Toby and Linda who got a total of 32 points. See if you can do better dear reader.&lt;/p&gt;  &lt;p&gt;You get one point for each correct answer. The quiz is split into six sections:&amp;#160; Computers, ‘Name That Geek’, Science, Space, ‘Name That Spaceship’, and Geek Culture.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;The answers are &lt;a href="http://mikehadlow.blogspot.co.uk/2012/12/a-geek-christmas-quizthe-answers.html"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Computers&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;What does G.N.U. stand for? &lt;/li&gt;    &lt;li&gt;What did the A in ARM originally stand for? &lt;/li&gt;    &lt;li&gt;What does TCP stand for? &lt;/li&gt;    &lt;li&gt;Who founded Microsoft with Bill Gates? &lt;/li&gt;    &lt;li&gt;What is F2 (hexadecimal) in decimal? &lt;/li&gt;    &lt;li&gt;Which operating system's development was based on the 'Balmer Peak'? &lt;/li&gt;    &lt;li&gt;Who was the first programmer? &lt;/li&gt;    &lt;li&gt;What year does UNIX time start? &lt;/li&gt;    &lt;li&gt;What did SGI stand for? &lt;/li&gt;    &lt;li&gt;Write down the type signature of the Monadic Bind method. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Name that Geek&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-9dCdTenpfew/UNRJrz8wCHI/AAAAAAAAF20/F-jPxSUS0CE/s1600-h/Name_that_geek%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Name_that_geek" border="0" alt="Name_that_geek" src="http://lh5.ggpht.com/-vPUctn60PDk/UNRJtJxs9GI/AAAAAAAAF24/7OrNbQ9DE7A/Name_that_geek_thumb%25255B2%25255D.png?imgmax=800" width="800" height="600" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Science&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;What are the four letters of DNA? &lt;/li&gt;    &lt;li&gt;What does the 'c' in E = mc2 stand for? &lt;/li&gt;    &lt;li&gt;What is the next number in this sequence: 1 1 2 3 5 8 _ ? &lt;/li&gt;    &lt;li&gt;What is C8 H10 N4 02 ? &lt;/li&gt;    &lt;li&gt;When did Australopithecus become extinct? (in millions of years ago) &lt;/li&gt;    &lt;li&gt;Which of the following would you &lt;em&gt;not&lt;/em&gt; expect to find in an atomic nucleus (electron, neutron, proton) &lt;/li&gt;    &lt;li&gt;What is the most common gas in the Earth's atmosphere? &lt;/li&gt;    &lt;li&gt;Write the formula for Ohm's law. &lt;/li&gt;    &lt;li&gt;If, after you fold a piece of paper in half, the ratio between its longest side and its shortest side is the same, what is that ratio? &lt;/li&gt;    &lt;li&gt;What living land mammal is the closest evolutionary relative to Whales? (cetaceans) &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Space&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;What rocket engine powered the 2nd stage of the Saturn V? &lt;/li&gt;    &lt;li&gt;What is Saturn's largest moon? &lt;/li&gt;    &lt;li&gt;What fraction of the Earth's gravity would you experience on the moon? &lt;/li&gt;    &lt;li&gt;Astronauts are weightless in space because there is no gravity. true or false? &lt;/li&gt;    &lt;li&gt;What is the orbital period of a geosynchronous satellite? &lt;/li&gt;    &lt;li&gt;What is the furthest planet from the sun? (now that Pluto has been demoted) &lt;/li&gt;    &lt;li&gt;How many people are currently living aboard the ISS? &lt;/li&gt;    &lt;li&gt;To the nearest thousand, how many satellites are currently orbiting the earth? &lt;/li&gt;    &lt;li&gt;What was the name of the only satellite launched by the UK? &lt;/li&gt;    &lt;li&gt;Who was the second man on the moon? &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Name that spaceship&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-hGzbsIuQB90/UNRJuMs_n_I/AAAAAAAAF3A/HI6dV7Jr0ic/s1600-h/Name_that_spaceship%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Name_that_spaceship" border="0" alt="Name_that_spaceship" src="http://lh6.ggpht.com/-sllcHIZrXC4/UNRJuxcyovI/AAAAAAAAF3I/fLMIC3BhDnI/Name_that_spaceship_thumb%25255B2%25255D.png?imgmax=800" width="800" height="600" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Geek Culture&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;Who was Spooky Mulder? &lt;/li&gt;    &lt;li&gt;Was Kiki a trainee witch or an evil princes? &lt;/li&gt;    &lt;li&gt;&amp;quot;Humans are a _____&amp;quot; (Agent Smith) &lt;/li&gt;    &lt;li&gt;Who is Peter Parker? &lt;/li&gt;    &lt;li&gt;&amp;quot;It's a b... It's a b... It's a small, off-duty Czechoslovakian traffic warden!&amp;quot; What is it really? &lt;/li&gt;    &lt;li&gt;What does 'Otaku' (Japanese) mean? &lt;/li&gt;    &lt;li&gt;What does R2D2 stand for? &lt;/li&gt;    &lt;li&gt;What is Clarke's 3rd law? &lt;/li&gt;    &lt;li&gt;What is the air speed velocity of an unladen swallow? &lt;/li&gt;    &lt;li&gt;Open ___ ___ ___ ____ please H.A.L &lt;/li&gt; &lt;/ol&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/bQgPcXJnIoY/a-geek-christmas-quiz.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-vPUctn60PDk/UNRJtJxs9GI/AAAAAAAAF24/7OrNbQ9DE7A/s72-c/Name_that_geek_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/12/a-geek-christmas-quiz.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-2267028320419266625</guid><pubDate>Tue, 18 Dec 2012 13:18:00 +0000</pubDate><atom:updated>2012-12-18T14:56:35.693Z</atom:updated><title>My Super Simple Node Twitter Re-Tweeter</title><description>&lt;p&gt;I’ve been having a lot of fun writing a little ‘re-tweeter’ this morning. We basically want to monitor our user stream and then re-tweet any status with a particular hash tag. I thought this would be an excellent little project for &lt;a href="http://nodejs.org/"&gt;node&lt;/a&gt;, and indeed it proved to be extremely easy to do. I used the &lt;a href="https://github.com/jdub/node-twitter"&gt;node-twitter&lt;/a&gt; library which worked fine for what I wanted to do.&lt;/p&gt;  &lt;p&gt;If you want to use this code, you’ll need to do the following:&lt;/p&gt;  &lt;p&gt;First you’ll need to go to &lt;a title="https://dev.twitter.com/apps" href="https://dev.twitter.com/apps"&gt;https://dev.twitter.com/apps&lt;/a&gt; and register a new app. You can then copy and paste your consumer key, consumer secret, access token and access token secret into the ‘xxx’ fields.&lt;/p&gt;  &lt;p&gt;Next install node-twitter with npm:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;npm install twitter&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Then just run the code with node (I’m a poet and I didn’t know it):&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;node twitter-retweeter.js&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Here’s the code in the twitter-retweeter.js file:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; util = require(&lt;span style="color: #006080"&gt;'util'&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; twitter = require(&lt;span style="color: #006080"&gt;'twitter'&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; twit = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; twitter({&lt;br /&gt;    consumer_key: &lt;span style="color: #006080"&gt;'xxx'&lt;/span&gt;,&lt;br /&gt;    consumer_secret: &lt;span style="color: #006080"&gt;'xxx'&lt;/span&gt;,&lt;br /&gt;    access_token_key: &lt;span style="color: #006080"&gt;'xxx'&lt;/span&gt;,&lt;br /&gt;    access_token_secret: &lt;span style="color: #006080"&gt;'xxx'&lt;/span&gt;&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; hashtag = &lt;span style="color: #006080"&gt;'#iloveprog'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; write(data) {&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ( &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; data === &lt;span style="color: #006080"&gt;'string'&lt;/span&gt;) {&lt;br /&gt;        console.log(data);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data.text &amp;amp;&amp;amp; data.user &amp;amp;&amp;amp; data.user.screen_name) {&lt;br /&gt;        console.log(data.user.screen_name + &lt;span style="color: #006080"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; + data.text);&lt;br /&gt;        testForHashtag(data);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data.delete) {&lt;br /&gt;        console.log(&lt;span style="color: #006080"&gt;'DELETE'&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data.message) {&lt;br /&gt;        console.log(&lt;span style="color: #006080"&gt;'ERROR'&lt;/span&gt; + data.message);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {&lt;br /&gt;        console.log(util.inspect(data));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; testForHashtag(data) {&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(data.retweeted) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(data.text.indexOf(hashtag) != -1) {&lt;br /&gt;        twit.retweetStatus(data.id_str, &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(){&lt;br /&gt;            console.log(&lt;span style="color: #006080"&gt;'retweet callback'&lt;/span&gt;);&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; reconnect() {&lt;br /&gt;    setTimeout(startStreaming, 1000);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; startStreaming() {&lt;br /&gt;    twit.stream(&lt;span style="color: #006080"&gt;'user'&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(stream) {&lt;br /&gt;        console.log(&lt;span style="color: #006080"&gt;'starting stream'&lt;/span&gt;);&lt;br /&gt;        stream.on(&lt;span style="color: #006080"&gt;'data'&lt;/span&gt;, write);&lt;br /&gt;        stream.on(&lt;span style="color: #006080"&gt;'end'&lt;/span&gt;, reconnect)&lt;br /&gt;    });&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;startStreaming();&lt;br /&gt;&lt;br /&gt;console.log(&lt;span style="color: #006080"&gt;'lisening for tweets'&lt;/span&gt;);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;It’s all really straight forward. The startStreaming function kicks of the callback on the twitter user stream. Each time an event occurs it calls the write function which checks for the given hashtag and then retweets the status if there’s a match.&lt;/p&gt;

&lt;p&gt;Lovely!&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/x-avxoFIoiQ/my-super-simple-node-twitter-re-tweeter.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>1</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/12/my-super-simple-node-twitter-re-tweeter.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-1842887952689492869</guid><pubDate>Wed, 05 Dec 2012 15:38:00 +0000</pubDate><atom:updated>2012-12-05T15:38:52.014Z</atom:updated><title>WebRequest Throws On 404 Status Code</title><description>&lt;p&gt;WebRequest, or rather HttpWebRequest has the annoying behaviour or throwing a WebException when the server returns 404 ‘not found’ status, or in fact any unexpected status number. It would be much better if it didn’t do this and simply allowed the application to decide what it should do on different status codes. At the very least there should be some way of turning this behaviour on or off. In fact it would be nice if the whole WebRequest class wasn’t a monolithic black box, but a toolbox of components that allowed you to tailor an HTTP client to your requirements. I was a little surprised when I did some Googling earlier and couldn’t find a nice open source alternative to WebRequest; it’s the sort of thing that the community is usually quite good at coding around. Oh well, I’ll add that to my ever growing list of potential future GitHub projects (that will never happen).&lt;/p&gt;  &lt;p&gt;My quick and dirty fix for this problem was an extension method that catches WebException, checks if the type of the exception is a protocol exception – this seems to be the status for status code exceptions, and then returns the response from the exception’s Response property. It’s horrible, but it seems to work:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; HttpWebResponse GetHttpResponse(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; HttpWebRequest request)&lt;br /&gt;{&lt;br /&gt;    HttpWebResponse response = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        response = (HttpWebResponse)request.GetResponse();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (WebException exception)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (exception.Status == WebExceptionStatus.ProtocolError)&lt;br /&gt;        {&lt;br /&gt;            response = (HttpWebResponse) exception.Response;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; response;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;It conveniently returns an HttpWebResponse instead of a WebResponse.&lt;/p&gt;

&lt;p&gt;You could use it like this …&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var response = request.GetHttpResponse();&lt;br /&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (response.StatusCode != HttpStatusCode.NotFound)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000"&gt;// handle appropriately&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Of course, if you want to handle the response asynchronously, you’ll have to write an extension method for EndGetResponse as well.&lt;/p&gt;

&lt;p&gt;… or, if you’re using .NET 4.5, you could use HttpClient. It wraps WebRequest internally, but it does return status codes rather than throwing it seems.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/LJE7Ju6oHyw/webrequest-throws-on-404-status-code.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>4</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/12/webrequest-throws-on-404-status-code.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-7783806682964584847</guid><pubDate>Tue, 04 Dec 2012 15:42:00 +0000</pubDate><atom:updated>2012-12-04T15:46:20.605Z</atom:updated><title>The Onion Of Compromise</title><description>&lt;p&gt;&lt;a href="http://lh6.ggpht.com/-5VcHEPU6IOY/UL4Z_WtK_kI/AAAAAAAAFTs/fvTeBYx4kz4/s1600-h/yellow_onion%25255B4%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="yellow_onion" border="0" alt="yellow_onion" src="http://lh3.ggpht.com/-N5l9XVmW_d8/UL4aAOVkpqI/AAAAAAAAFTw/QkN_ohEqRfw/yellow_onion_thumb%25255B2%25255D.jpg?imgmax=800" width="500" height="546" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I love little phrases that sum up large scale behaviours in software systems and the organisations that produce them. One of my favourite is “The Onion Of Compromise.” I first heard this gem from my excellent friend Iain Holder. Iain doesn’t claim to be the author, that honour goes to a mysterious third person named ‘Mike’.&lt;/p&gt;  &lt;p&gt;Being a programmer is all about making decisions. Lots and lots of little decisions. In fact every line of code is a decision; a little cog in the wheel of a grander machine. The simple thing that separates a good programmer from a poor programmer is that they tend to make relatively more good decisions and less bad ones.&lt;/p&gt;  &lt;p&gt;Incidentally, that’s why it’s a mistake to think that you can hire an experienced ‘chief architect’ who ‘designs’ your system, while rooms full of junior/cheap developers churn out the code - and expect anything other than a disaster to occur. The decisions are just too granular to be&amp;#160; made by one person on a large project.&lt;/p&gt;  &lt;p&gt;Good decisions are ones which aid the evolution and stability of an application. They are summed up by epithets that describe general good practice, such as ‘Don’t Repeat Yourself’, ‘Open Closed Principle’ and a hundred others. An experienced programmer will employ a range of these rules-of-thumb to ensure that they don’t get tangled up in needless complexity as their application grows. You can tell a project where good decisions have been made; it’s easy to add new features and there are few bugs.&lt;/p&gt;  &lt;p&gt;A bad decision often doesn’t seem like a bad decision at first, merely a way of implementing a feature or fixing a bug with the least possible impact on the code. Often the bad decision will introduce a constraint on further evolution of the software or a special case given a particular combination of factors. If a bad decision isn’t rolled back it can quickly lead to further bad decisions as the programmer works around it. Soon layers of poor design wrap that initial poor decision. This is ‘The Onion of Compromise’. That initial first mistake (or compromise) leads to a cascade of poor choices. Another name for the layers of the onion is ‘Technical Debt’.&lt;/p&gt;  &lt;p&gt;It’s easy to spot software that has suffered from The Onion of Compromise; it’s brittle, you change one thing and it breaks seemingly unrelated parts of the system; it seems to take ages to implement new features; and there’s a high bug count.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/aG1Ln4-HH88/the-onion-of-compromise.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-N5l9XVmW_d8/UL4aAOVkpqI/AAAAAAAAFTw/QkN_ohEqRfw/s72-c/yellow_onion_thumb%25255B2%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/12/the-onion-of-compromise.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-5760479612412375433</guid><pubDate>Mon, 26 Nov 2012 15:20:00 +0000</pubDate><atom:updated>2012-12-03T15:54:56.961Z</atom:updated><title>RabbitMQ On Windows With .NET, A Case Study</title><description>&lt;p&gt;Any reader of this blog will know that my big project over the last year has been to create a simple .NET API for &lt;a href="http://www.rabbitmq.com"&gt;RabbitMQ&lt;/a&gt; called &lt;a href="http://easynetq.com"&gt;EasyNetQ&lt;/a&gt;.&amp;#160; I’ve been working as a software architect at &lt;a href="http://www.15below.com/"&gt;15Below&lt;/a&gt; for the last year and a half. The prime motivation for writing EasyNetQ was so that our developers would have an easy API for working with RabbitMQ on .NET. I was very fortunate that, founder and technical director, John Clynes, supported my wish to build it as an open source library. I originally wrote this post for the VMWare blog as a case study of running RabbitMQ in a Microsoft environment.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.15Below.com/"&gt;15Below&lt;/a&gt; is based in &lt;a href="http://en.wikipedia.org/wiki/Brighton"&gt;Brighton&lt;/a&gt; on the south coast of England, famous for it’s &lt;a href="http://en.wikipedia.org/wiki/Royal_Pavilion"&gt;Regency pavilion&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Brighton_Pier"&gt;Victorian pier&lt;/a&gt;. We provide messaging and integration services for the travel industry. Our clients include Ryanair, Qantas, JetBlue, Thomas Cook and around 30 other airline and rail customers. We send hundreds of millions of transactional notifications each year to our customer’s passengers.&lt;/p&gt;  &lt;p&gt;RabbitMQ has helped us to significantly simplify and stabilise our software. It’s one of those black boxes that you install, configure, and then really don’t have to worry about. In over a year of production we’ve found it to be extremely stable and reliable. &lt;/p&gt;  &lt;p&gt;Prior to introducing RabbitMQ our applications would use SQL Server as a queuing mechanism. Each task would be represented by a row in a workflow table. Each process in the workflow would poll the table looking for rows that matched its status, process the rows in in a batch, and then update the rows’ status field for the next process to pick up. Each step in the process would be hosted by an application service that implemented its own threading model, often using a different approach to all the other services. This created highly coupled software, with workflow steps and infrastructure concerns, such as threading and load balancing, mixed together with business logic. We also discovered that a relational database is not a natural fit for a queuing system. The contention on the workflow tables is high, with constant inserts, selects and updates causing locking issues. Deleting completed items is also problematic on highly indexed tables and we had considerable problems with continuously growing tables.&lt;/p&gt;  &lt;p align="left"&gt;I wrote about the ‘&lt;a href="http://mikehadlow.blogspot.co.uk/2012/04/database-as-queue-anti-pattern.html"&gt;Database As Queue Anti-Pattern&lt;/a&gt;’ in a previous post in more detail.&lt;/p&gt;  &lt;p&gt;RabbitMQ provides a number of features that helped us overcome these problems. Firstly it is designed from the beginning as a high-performance messaging platform. It easily outperformed our SQL Server based solution with none of its locking or deletion problems. Rabbit’s event-oriented messaging model also takes away much of the need for complex multi-threaded batch processing code that was previously a cause of instability in our systems.&lt;/p&gt;  &lt;p&gt;We first introduced RabbitMQ about 18 months ago as the core infrastructure behind our Flight Status product. We wanted a high performance messaging product with a proven track record that supported common messaging patterns, such as publish/subscribe and request/response. A further requirement was that it should provide automatic work distribution and load balancing.&lt;/p&gt;  &lt;p&gt;The need to support messaging patterns ruled out simple store-and-forward queues such as MSMQ and ActiveMQ. We were very impressed by ZeroMQ, but decided that we really needed the centralised manageability of a broker based product. This left RabbitMQ. Although support for AMQP, an open messaging standard, wasn’t in our list of requirements, its implementation by RabbitMQ made us more confident that we were choosing a sustainable strategy.&lt;/p&gt;  &lt;p&gt;We are very much a Microsoft shop, so we had some initial concerns about RabbitMQ’s performance and stability on Windows. We were reassured by reading some accounts of RabbitMQ’s and indeed Erlang’s use on Windows by organisations with some very impressive load requirements. Subsequent experience has borne these reports out, and we have found RabbitMQ on Server 2008 to be rock solid.&lt;/p&gt;  &lt;p&gt;As a Microsoft shop, our development platform is .NET. Although VMWare provide an AMQP C# client, it is a low-level API, not suitable for use by more junior developers. For this reason we created our own high-level .NET API for RabbitMQ that provides simple single method access to common messaging patterns and does not require a deep knowledge of AMQP.&amp;#160; This API is called EasyNetQ. We’ve open sourced it and, with over 3000 downloads, it is now the leading high-level API for RabbitMQ with .NET. You can find more information about it at &lt;a href="http://easynetq.com"&gt;EasyNetQ.com&lt;/a&gt;. We would recommend looking at it if you are a .NET shop using RabbitMQ.&lt;/p&gt;  &lt;p&gt;15Below’s Flight-Status product provides real-time flight information to passengers and their family and friends. We interface with the airline’s real-time flight information stream generated from their operation systems and provide a platform that allows them to apply complex business logic to this stream. We render customer tailored output, and communicate with the airline’s customers via a range of channels, including email, SMS, voice and iPhone/Android push. RabbitMQ allows us to build each piece; the client for the fight information stream, the message renderer, the sink channels and the business logic; as separate components that communicate using structured messages. &lt;a href="http://mikehadlow.blogspot.co.uk/2011/09/some-thoughts-on-service-oriented_27.html"&gt;Our architecture looks something like this&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-FOQfJpkaE50/ULOIz2EkZFI/AAAAAAAAE6w/ZAGKTGcyAWI/s1600-h/rabbit_based_architecture%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="rabbit_based_architecture" border="0" alt="rabbit_based_architecture" src="http://lh3.ggpht.com/-pq4TLn7W9DI/ULOI1G9PTMI/AAAAAAAAE60/7DuN10gmyQ0/rabbit_based_architecture_thumb%25255B2%25255D.png?imgmax=800" width="589" height="343" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The green boxes are our core product systems, the blue boxes represent custom code that we write for each customer. A ‘customer saga’ is code that models a long-running business process and includes all the workflow logic for a particular customer’s flight information requirements. A ‘core product service’ is an independent service that implements a feature of our product. An example would be the service that takes flight information and combines it with a customer defined template to create an email to be sent to a passenger. Constructing services as independently deployable and runnable applications gives us great flexibility and scalability. If we need to scale up a particular component, we simply install more copies. RabbitMQ’s automatic work sharing feature means that we can do this without any reconfiguration of existing components. This architecture also makes it easy to test each application service in isolation since it’s simply a question of firing messages at the service and watching its response.&lt;/p&gt;  &lt;p&gt;In conclusion, RabbitMQ has provided a rock solid piece of infrastructure with the features to allow us to significantly reduce the architectural complexity of our systems. We can now build software for our clients faster and more reliably. It scales to higher loads than our previous relational-database based systems and is more flexible in the face of changing customer requirements.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/I6ETidSOW9U/rabbitmq-on-windows-with-net-case-study.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-pq4TLn7W9DI/ULOI1G9PTMI/AAAAAAAAE60/7DuN10gmyQ0/s72-c/rabbit_based_architecture_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/11/rabbitmq-on-windows-with-net-case-study.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-4806207035367098167</guid><pubDate>Fri, 23 Nov 2012 15:56:00 +0000</pubDate><atom:updated>2012-11-23T16:32:52.048Z</atom:updated><title>Using BlockingCollection To Communicate Between Threads</title><description>&lt;p&gt;Consider these (somewhat) common programming challenges:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I’m using a third party library that is not thread safe, but I want my application to share work between multiple threads. How do I marshal calls between my multi-threaded code to the single threaded library? &lt;/li&gt;    &lt;li&gt;I have a single source of events on a single thread, but I want to share the work between a pool of multiple threads? &lt;/li&gt;    &lt;li&gt;I have multiple threads emitting events, but I want to consume them on a single thread? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;One way of doing this would be to have some shared state, a field or a property on a static class, and wrap locks around it so that multiple threads can access it safely. This is a pretty common way of trying to skin this particular cat, but it’s shot through with traps for the unwary. Also, it can hurt performance because access to the shared resource is serialized, even though the things accessing it are running in parallel.&lt;/p&gt;  &lt;p&gt;A better way is to use a &lt;a href="http://msdn.microsoft.com/en-us/library/dd997371.aspx"&gt;BlockingCollection&lt;/a&gt; and have your threads communicate via message classes.&lt;/p&gt;  &lt;p&gt;BlockingCollection is a class in the new System.Collections.Concurrent namespace that arrived with .NET 4.0. It contains a ConcurrentQueue, although you can swap this for a ConcurrentStack or a ConcurrentBag if you want. You push objects in at one end and sit in a loop consuming them from the other. The (multiple) producer(s) and (multiple) consumer(s) can be running on different threads without any locks. That’s OK because the Concurrent namespace collection classes are guaranteed to be thread safe. The ‘blocking’ part of the name is there because the consuming end blocks until an object is available. &lt;a href="http://www.codethinked.com/blockingcollection-and-iproducerconsumercollection"&gt;Justin Etheredge has an excellent post that looks at BlockingCollection in more detail here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For an example, let’s implement a parallel pipeline. A ventilator produces tasks to be processed in parallel, a set of workers process the tasks on separate threads, and a sink collects the results back together again. It shows both one-to-many and many-to-one thread communication. I’ve stolen the idea and the diagram from the excellent &lt;a href="http://zguide.zeromq.org/page:all"&gt;ZeroMQ Guide&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-IYE80tKuYuk/UK-coCuYmjI/AAAAAAAAEzk/PbB3_wp0ohM/s1600-h/zguide_parallel_workers%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="zguide_parallel_workers" border="0" alt="zguide_parallel_workers" src="http://lh4.ggpht.com/-OKZlzpImkgY/UK-cpA7oHhI/AAAAAAAAEzs/uC0tfTs_Diw/zguide_parallel_workers_thumb%25255B2%25255D.png?imgmax=800" width="456" height="539" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;First we’ll need a class that represents a piece of work, we’ll keep it super simple for this example:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WorkItem&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Text { get; set; }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;We’ll need two BlockingCollections, one to take the tasks from the ventilator to the workers, and another to take the finished work from the workers to the sink:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var ventilatorQueue = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BlockingCollection&amp;lt;WorkItem&amp;gt;();&lt;br /&gt;var sinkQueue = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BlockingCollection&amp;lt;WorkItem&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now let’s write our ventilator:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartVentilator(BlockingCollection&amp;lt;WorkItem&amp;gt; ventilatorQueue)&lt;br /&gt;{&lt;br /&gt;    Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&lt;br /&gt;        {&lt;br /&gt;            ventilatorQueue.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WorkItem { Text = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;&amp;quot;Item {0}&amp;quot;&lt;/span&gt;, i) });&lt;br /&gt;        }&lt;br /&gt;    }, TaskCreationOptions.LongRunning);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;It just iterates 100 times creating work items and pushing them on the ventilatorQueue.&lt;/p&gt;

&lt;p&gt;Here is a worker:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartWorker(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; workerNumber,&lt;br /&gt;    BlockingCollection&amp;lt;WorkItem&amp;gt; ventilatorQueue,&lt;br /&gt;    BlockingCollection&amp;lt;WorkItem&amp;gt; sinkQueue)&lt;br /&gt;{&lt;br /&gt;    Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var workItem &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; ventilatorQueue.GetConsumingEnumerable())&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000"&gt;// pretend to take some time to process&lt;/span&gt;&lt;br /&gt;            Thread.Sleep(30);&lt;br /&gt;            workItem.Text = workItem.Text + &lt;span style="color: #006080"&gt;&amp;quot; processed by worker &amp;quot;&lt;/span&gt; + workerNumber;&lt;br /&gt;            sinkQueue.Add(workItem);&lt;br /&gt;        }&lt;br /&gt;    }, TaskCreationOptions.LongRunning);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;BlockingCollection provides a GetConsumingEnumerable method that yields each item in turn. It blocks if there are no items on the queue. Note that I’m not worrying about shutdown patterns in this code. In production code you’d need to worry about how to close down your worker threads.&lt;/p&gt;

&lt;p&gt;Next let’s write our sink:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartSink(BlockingCollection&amp;lt;WorkItem&amp;gt; sinkQueue)&lt;br /&gt;{&lt;br /&gt;    Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var workItem &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; sinkQueue.GetConsumingEnumerable())&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;Processed Messsage: {0}&amp;quot;&lt;/span&gt;, workItem.Text);&lt;br /&gt;        }&lt;br /&gt;    }, TaskCreationOptions.LongRunning);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Once again, this sits in an infinite foreach loop consuming items from the sinkQueue.&lt;/p&gt;

&lt;p&gt;Finally we need to wire up the pieces and kick it off:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;StartSink(sinkQueue);&lt;br /&gt;&lt;br /&gt;StartWorker(0, ventilatorQueue, sinkQueue);&lt;br /&gt;StartWorker(1, ventilatorQueue, sinkQueue);&lt;br /&gt;StartWorker(2, ventilatorQueue, sinkQueue);&lt;br /&gt;&lt;br /&gt;StartVentilator(ventilatorQueue);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;I’ve started the sink first, then the workers and finally the producer. It doesn’t overly matter what order they start in since the queues will store any tasks the ventilator creates before the workers and the sink start.&lt;/p&gt;

&lt;p&gt;Running the code I get output something like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;Processed Messsage: Item 1 processed by worker 1&lt;br /&gt;Processed Messsage: Item 2 processed by worker 0&lt;br /&gt;Processed Messsage: Item 0 processed by worker 2&lt;br /&gt;Processed Messsage: Item 5 processed by worker 2&lt;br /&gt;Processed Messsage: Item 3 processed by worker 1&lt;br /&gt;&lt;br /&gt;....&lt;br /&gt;&lt;br /&gt;Processed Messsage: Item 95 processed by worker 0&lt;br /&gt;Processed Messsage: Item 98 processed by worker 0&lt;br /&gt;Processed Messsage: Item 97 processed by worker 2&lt;br /&gt;Processed Messsage: Item 96 processed by worker 1&lt;br /&gt;Processed Messsage: Item 99 processed by worker 0&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This pattern is a great way of decoupling the communication between a source and a sink, or a producer and a consumer. It also allows you to have multiple sources and multiple sinks, but primarily it’s a safe way for multiple threads to interact.&lt;/p&gt;

&lt;p&gt;The complete example is &lt;a href="https://github.com/mikehadlow/Mike.Spikes/blob/master/Mike.Spikes/ProducerConsumer/ProducerConsumerSpike.cs"&gt;here&lt;/a&gt; on GitHub.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/I-kx-KzbLCg/using-blockingcollection-to-communicate.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-OKZlzpImkgY/UK-cpA7oHhI/AAAAAAAAEzs/uC0tfTs_Diw/s72-c/zguide_parallel_workers_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/11/using-blockingcollection-to-communicate.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-4294113506658199419</guid><pubDate>Thu, 15 Nov 2012 16:31:00 +0000</pubDate><atom:updated>2012-11-15T16:31:21.202Z</atom:updated><title>A C# .NET Client Proxy For The RabbitMQ Management API</title><description>&lt;p&gt;&lt;a href="http://www.rabbitmq.com"&gt;RabbitMQ&lt;/a&gt; comes with a very nice &lt;a href="http://www.rabbitmq.com/management.html"&gt;Management UI and a HTTP JSON API&lt;/a&gt;, that allows you to configure and monitor your RabbitMQ broker. From the website:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“&lt;em&gt;The rabbitmq-management plugin provides an HTTP-based API for management and monitoring of your RabbitMQ server, along with a browser-based UI and a command line tool, &lt;/em&gt;&lt;a href="http://www.rabbitmq.com/management-cli.html"&gt;&lt;em&gt;rabbitmqadmin&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. Features include:&lt;/em&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;em&gt;Declare, list and delete exchanges, queues, bindings, users, virtual hosts and permissions. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Monitor queue length, message rates globally and per channel, data rates per connection, etc. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Send and receive messages. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Monitor Erlang processes, file descriptors, memory use. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Export / import object definitions to JSON. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Force close connections, purge queues.&lt;/em&gt;”&lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;Wouldn’t it be cool if you could do all these management tasks from your .NET code? Well now you can. I’ve just added a new project to &lt;a href="http://easynetq.com"&gt;EasyNetQ&lt;/a&gt; called &lt;a href="https://github.com/mikehadlow/EasyNetQ/wiki/Management-API-Introduction"&gt;EasyNetQ.Management.Client&lt;/a&gt;. This is a .NET client-side proxy for the HTTP-based API.&lt;/p&gt;  &lt;p&gt;It’s on &lt;a href="http://nuget.org/packages/EasyNetQ.Management.Client"&gt;NuGet&lt;/a&gt;, so to install it, you simply run:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;PM&amp;gt; Install-Package EasyNetQ.Management.Client&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;To give an overview of the sort of things you can do with EasyNetQ.Client.Management, have a look at this code. It first creates a new Virtual Host and a User, and gives the User permissions on the Virtual Host. Then it re-connects as the new user, creates an exchange and a queue, binds them, and publishes a message to the exchange. Finally it gets the first message from the queue and outputs it to the console.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var initial = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ManagementClient(&lt;span style="color: #006080"&gt;&amp;quot;http://localhost&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;guest&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;guest&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// first create a new virtual host&lt;/span&gt;&lt;br /&gt;var vhost = initial.CreateVirtualHost(&lt;span style="color: #006080"&gt;&amp;quot;my_virtual_host&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// next create a user for that virutal host&lt;/span&gt;&lt;br /&gt;var user = initial.CreateUser(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; UserInfo(&lt;span style="color: #006080"&gt;&amp;quot;mike&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;topSecret&amp;quot;&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// give the new user all permissions on the virtual host&lt;/span&gt;&lt;br /&gt;initial.CreatePermission(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PermissionInfo(user, vhost));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// now log in again as the new user&lt;/span&gt;&lt;br /&gt;var management = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ManagementClient(&lt;span style="color: #006080"&gt;&amp;quot;http://localhost&amp;quot;&lt;/span&gt;, user.name, &lt;span style="color: #006080"&gt;&amp;quot;topSecret&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// test that everything's OK&lt;/span&gt;&lt;br /&gt;management.IsAlive(vhost);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// create an exchange&lt;/span&gt;&lt;br /&gt;var exchange = management.CreateExchange(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ExchangeInfo(&lt;span style="color: #006080"&gt;&amp;quot;my_exchagne&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;direct&amp;quot;&lt;/span&gt;), vhost);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// create a queue&lt;/span&gt;&lt;br /&gt;var queue = management.CreateQueue(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; QueueInfo(&lt;span style="color: #006080"&gt;&amp;quot;my_queue&amp;quot;&lt;/span&gt;), vhost);&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// bind the exchange to the queue&lt;/span&gt;&lt;br /&gt;management.CreateBinding(exchange, queue, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BindingInfo(&lt;span style="color: #006080"&gt;&amp;quot;my_routing_key&amp;quot;&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// publish a test message&lt;/span&gt;&lt;br /&gt;management.Publish(exchange, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PublishInfo(&lt;span style="color: #006080"&gt;&amp;quot;my_routing_key&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #008000"&gt;// get any messages on the queue&lt;/span&gt;&lt;br /&gt;var messages = management.GetMessagesFromQueue(queue, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; GetMessagesCriteria(1, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var message &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; messages)&lt;br /&gt;{&lt;br /&gt;    Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;message.payload = {0}&amp;quot;&lt;/span&gt;, message.payload);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This library is also ideal for monitoring queue levels, channels and connections on your RabbitMQ broker. For example, this code prints out details of all the current connections to the RabbitMQ broker:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var connections = managementClient.GetConnections();&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var connection &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; connections)&lt;br /&gt;{&lt;br /&gt;    Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;connection.name = {0}&amp;quot;&lt;/span&gt;, connection.name);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;user:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.user);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;application:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.application);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;client_api:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.client_api);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;application_location:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.application_location);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;connected:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.connected);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;easynetq_version:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.easynetq_version);&lt;br /&gt;    Console.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;machine_name:\t{0}&amp;quot;&lt;/span&gt;, connection.client_properties.machine_name);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;On my machine, with one consumer running it outputs this:&lt;/div&gt;

&lt;div&gt;&amp;#160;&lt;/div&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;connection.name = [::1]:64754 -&amp;gt; [::1]:5672&lt;br /&gt;user:   guest&lt;br /&gt;application:    EasyNetQ.Tests.Performance.Consumer.exe&lt;br /&gt;client_api: EasyNetQ&lt;br /&gt;application_location:   D:\Source\EasyNetQ\Source\EasyNetQ.Tests.Performance.Consumer\bin\Debug&lt;br /&gt;connected:  14/11/2012 15:06:19&lt;br /&gt;easynetq_version:   0.9.0.0&lt;br /&gt;machine_name:   THOMAS&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;You can see the name of the application that’s making the connection, the machine it’s running on and even its location on disk. That’s rather nice. From this information it wouldn’t be too hard to auto-generate a complete system diagram of your distributed messaging application. Now there’s an idea :)&lt;/p&gt;

&lt;p&gt;For more information, check out &lt;a href="https://github.com/mikehadlow/EasyNetQ/wiki/Management-API-Introduction"&gt;the documentation&lt;/a&gt;. &lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/v2PJeL60WSQ/a-c-net-client-proxy-for-rabbitmq.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>1</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/11/a-c-net-client-proxy-for-rabbitmq.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-831570590454155988</guid><pubDate>Mon, 12 Nov 2012 17:05:00 +0000</pubDate><atom:updated>2012-11-12T17:05:19.888Z</atom:updated><title>Nicer Client Properties For EasyNetQ</title><description>&lt;p&gt;EasyNetQ is my lightweight easy-to-use .NET API for RabbitMQ.&lt;/p&gt;  &lt;p&gt;Today I added a small but very nice feature, better client properties. Now when you look at connections created by EasyNetQ you can see the machine that connected, the application and the application’s location on disk. It also gives you the date and time that EasyNetQ first connected. Very useful for debugging.&lt;/p&gt;  &lt;p&gt;Here’s an example. Check out the ‘Client Properties’ section.&lt;/p&gt;  &lt;p&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="nice_connection_properties" border="0" alt="nice_connection_properties" src="http://lh4.ggpht.com/-Fs9WHiPLt_8/UKEsTfz1fTI/AAAAAAAAEkE/DBV_ODEoNu4/nice_connection_properties%25255B10%25255D.png?imgmax=800" width="691" height="751" /&gt;&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/4CeD4ILWnIk/nicer-client-properties-for-easynetq.html</link><author>noreply@blogger.com (Mike Hadlow)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-Fs9WHiPLt_8/UKEsTfz1fTI/AAAAAAAAEkE/DBV_ODEoNu4/s72-c/nice_connection_properties%25255B10%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/11/nicer-client-properties-for-easynetq.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-7524169801308575215</guid><pubDate>Tue, 06 Nov 2012 14:47:00 +0000</pubDate><atom:updated>2012-11-06T14:47:52.158Z</atom:updated><title>EasyNetQ Publisher Confirms</title><description>&lt;p&gt;&lt;a href="http://easynetq.com"&gt;EasyNetQ&lt;/a&gt; is my easy-to-use .NET API for RabbitMQ.&lt;/p&gt;  &lt;p&gt;The default AMQP publish is not transactional and doesn't guarantee that your message will actually reach the broker. AMQP does specify a transactional publish, but with RabbitMQ it is extremely slow, around 200 slower than a non-transactional publish, and we haven't supported it via the EasyNetQ API. For high-performance guaranteed delivery it's recommended that you use 'Publisher Confirms'. Simply speaking, this an extension to AMQP that provides a call-back when your message has been successfully received by the broker.&lt;/p&gt;  &lt;p&gt;What does 'successfully received' mean? It depends ...&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A transient message is confirmed the moment it is enqueued. &lt;/li&gt;    &lt;li&gt;A persistent message is confirmed as soon as it is persisted to disk, or when it is consumed on every queue. &lt;/li&gt;    &lt;li&gt;An unroutable transient message is confirmed directly it is published. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For more information on publisher confirms, &lt;a href="http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/"&gt;please read the announcement on the RabbitMQ blog&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;To use publisher confirms, you must first create the publish channel with publisher confirms on:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var channel = bus.OpenPublishChannel(x =&amp;gt; x.WithPublisherConfirms())&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Next you must specify success and failure callbacks when you publish your message:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;channel.Publish(message, x =&amp;gt; &lt;br /&gt;    x.OnSuccess(() =&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// do success processing here&lt;/span&gt;&lt;br /&gt;    })&lt;br /&gt;    .OnFailure(() =&amp;gt; &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000"&gt;// do failure processing here&lt;/span&gt;&lt;br /&gt;    }));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Be careful not to dispose the publish channel before your call-backs have had a chance to execute.&lt;/p&gt;

&lt;p&gt;Here's an example of a simple test. We're publishing 10,000 messages and then waiting for them all to be acknowledged before disposing the channel. There's a timeout, so if the batch takes longer than 10 seconds we abort with an exception.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; batchSize = 10000;&lt;br /&gt;var callbackCount = 0;&lt;br /&gt;var stopwatch = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;stopwatch.Start();&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; (var channel = bus.OpenPublishChannel(x =&amp;gt; x.WithPublisherConfirms()))&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; batchSize; i++)&lt;br /&gt;    {&lt;br /&gt;        var message = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyMessage {Text = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;&amp;quot;Hello Message {0}&amp;quot;&lt;/span&gt;, i)};&lt;br /&gt;        channel.Publish(message, x =&amp;gt; &lt;br /&gt;            x.OnSuccess(() =&amp;gt; {&lt;br /&gt;                callbackCount++;&lt;br /&gt;            })&lt;br /&gt;            .OnFailure(() =&amp;gt;&lt;br /&gt;            {&lt;br /&gt;                callbackCount++;&lt;br /&gt;            }));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #008000"&gt;// wait until all the publications have been acknowleged.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (callbackCount &amp;lt; batchSize)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (stopwatch.Elapsed.Seconds &amp;gt; 10)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ApplicationException(&lt;span style="color: #006080"&gt;&amp;quot;Aborted batch with timeout&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        Thread.Sleep(10);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/WGHD4mY1Upg/easynetq-publisher-confirms.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>0</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/11/easynetq-publisher-confirms.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-6363320774030276112</guid><pubDate>Wed, 10 Oct 2012 15:24:00 +0000</pubDate><atom:updated>2012-10-10T16:39:31.725+01:00</atom:updated><title>A Functional IoC Container</title><description>&lt;p&gt;Today I was idly thinking about &lt;a href="http://mikehadlow.blogspot.co.uk/2010/03/thought-experiment-curry-facility.html"&gt;an idea I had a couple of years ago for a functional IoC container&lt;/a&gt;. I’d had a go at implementing such a beast, but soon got bogged down in a tangled mess of spaghetti reflection code and gave it up as too much bother. But today it suddenly occurred&amp;#160; to me that there was no need for any reflection voodoo; the C# type system is powerful enough to do all the work for us.&lt;/p&gt;  &lt;p&gt;In object oriented programming languages we build programs from classes. Classes declare the contract(s) they support with interfaces and declare their dependencies with constructor arguments. We use an IoC container to wire instances of our classes together to make a running program.&lt;/p&gt;  &lt;p&gt;Pure functional languages, like Haskell, don’t have any concept of class, instead they use currying and partial application to compose hierarchies of functions.&lt;/p&gt;  &lt;p&gt;Here’s an example of a purely functional program written in C#.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Module&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data GetAndTransform(Func&amp;lt;Input,Data&amp;gt; dataAccsessor, Func&amp;lt;Data,Data&amp;gt; transformer, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; id)&lt;br /&gt;    {&lt;br /&gt;        var input = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Input() {Id = id};&lt;br /&gt;        var data = dataAccsessor(input);&lt;br /&gt;        var transformed = transformer(data);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; transformed;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data DataAccsessor(Input input)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Data&lt;br /&gt;        {&lt;br /&gt;            Id = input.Id,&lt;br /&gt;            Name = &lt;span style="color: #006080"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;&lt;br /&gt;        };&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Data Transformer(Data original)&lt;br /&gt;    {&lt;br /&gt;        original.Name = original.Name + &lt;span style="color: #006080"&gt;&amp;quot; transformed&amp;quot;&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; original;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;GetAndTransform simply takes an int id argument, does some work, and then returns some data. It needs a dataAccsessor and a transformer in order to do its job.&lt;/p&gt;

&lt;p&gt;C# doesn’t support currying or partial application, so in order to run it we have to compose the program and execute it all in one step. For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var id = 10;&lt;br /&gt;var data = Module.GetAndTransform(Module.DataAccsessor, Module.Transformer, id);&lt;br /&gt;&lt;br /&gt;Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;data.Id = {0}&amp;quot;&lt;/span&gt;, data.Id);&lt;br /&gt;Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;data.Name = {0}&amp;quot;&lt;/span&gt;, data.Name);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;But what if we had a ‘currying container’, one that could compose the program in one step and then return a function for us to execute in another? Here is such a container at work with our program:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var registration = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Container()&lt;br /&gt;    .Register&amp;lt;Func&amp;lt;Input, Data&amp;gt;, Func&amp;lt;Data, Data&amp;gt;, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, Data&amp;gt;(Module.GetAndTransform)&lt;br /&gt;    .Register&amp;lt;Input,Data&amp;gt;(Module.DataAccsessor)&lt;br /&gt;    .Register&amp;lt;Data,Data&amp;gt;(Module.Transformer);&lt;br /&gt;&lt;br /&gt;var main = registration.Get&amp;lt;Func&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, Data&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;var data = main(10);&lt;br /&gt;&lt;br /&gt;Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;data.Id = {0}&amp;quot;&lt;/span&gt;, data.Id);&lt;br /&gt;Console.Out.WriteLine(&lt;span style="color: #006080"&gt;&amp;quot;data.Name = {0}&amp;quot;&lt;/span&gt;, data.Name);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;In the first line, we create a new instance of our container. On the next three lines we register our functions. Unfortunately C#’s type inference isn’t powerful enough to let us do away with the tedious type annotations; we have to explicitly declare the argument and return types of each of our functions. &lt;/p&gt;

&lt;p&gt;Once our functions are registered we can ask the container for a program (main) that takes an int and returns a Data instance. The container works out that it needs to curry GetAndTransform and then partially apply DataAccsessor and Transformer to it to produce the desired function.&lt;/p&gt;

&lt;p&gt;We can then run our ‘main’ function which gives us our expected output:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;data.Id = 10&lt;br /&gt;data.Name = Test transformed&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The container turns out to be very simple, just a dictionary that’s keyed by type and contains a collection of constructor functions that know how to build the target (key) type.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IRegistration&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Add(Type target, Func&amp;lt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; constructor);&lt;br /&gt;    T Get&amp;lt;T&amp;gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Container : IRegistration&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Dictionary&amp;lt;Type, Func&amp;lt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;&amp;gt; registrations = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;Type, Func&amp;lt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Add(Type target,  Func&amp;lt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&amp;gt; constructor)&lt;br /&gt;    {&lt;br /&gt;        registrations.Add(target, constructor);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; T Get&amp;lt;T&amp;gt;()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; (T)registrations[&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; (T)]();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The magic sauce is in the Registration function overloads. If you take the standard functional idea that a function should only have one argument and one return type, you can take any input function, curry it, and then partially apply arguments until you are left with a Func&amp;lt;X,Y&amp;gt;. So you know what the ‘target’ type of each function should be, a function from the last argument to the return type. A Func&amp;lt;A,B,C,R&amp;gt; gets resolved to a Func&amp;lt;C,R&amp;gt;. There’s no need to explicitly register a target, it’s implicit from the type of the provided function:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RegistrationExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IRegistration Register&amp;lt;A,R&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IRegistration registration, Func&amp;lt;A, R&amp;gt; source)&lt;br /&gt;    {&lt;br /&gt;        var targetType = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; (Func&amp;lt;A, R&amp;gt;);&lt;br /&gt;        var curried = Functional.Curry(source);&lt;br /&gt;&lt;br /&gt;        registration.Add(targetType, () =&amp;gt; curried);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; registration;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IRegistration Register&amp;lt;A,B,R&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IRegistration registration, Func&amp;lt;A, B, R&amp;gt; source)&lt;br /&gt;    {&lt;br /&gt;        var targetType = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; (Func&amp;lt;B, R&amp;gt;);&lt;br /&gt;        var curried = Functional.Curry(source);&lt;br /&gt;&lt;br /&gt;        registration.Add(targetType, () =&amp;gt; curried(&lt;br /&gt;            registration.Get&amp;lt;A&amp;gt;()&lt;br /&gt;            ));&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; registration;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IRegistration Register&amp;lt;A, B, C, R&amp;gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; IRegistration registration, Func&amp;lt;A, B, C, R&amp;gt; source)&lt;br /&gt;    {&lt;br /&gt;        var targetType = &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Func&amp;lt;C, R&amp;gt;);&lt;br /&gt;        var curried = Functional.Curry(source);&lt;br /&gt;&lt;br /&gt;        registration.Add(targetType, () =&amp;gt; curried(&lt;br /&gt;            registration.Get&amp;lt;A&amp;gt;()&lt;br /&gt;            )&lt;br /&gt;            (&lt;br /&gt;            registration.Get&amp;lt;B&amp;gt;()&lt;br /&gt;            ));&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; registration;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Each overload deals with an input function with a different number of arguments. My simple experiment only works with functions with up to three arguments (two dependencies and an input type), but it would be easy to extend for higher numbers. The Curry function is stolen from Oliver Sturm and looks like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Functional&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Func&amp;lt;A, R&amp;gt; Curry&amp;lt;A, R&amp;gt;(Func&amp;lt;A, R&amp;gt; input)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; input;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Func&amp;lt;A, Func&amp;lt;B, R&amp;gt;&amp;gt; Curry&amp;lt;A, B, R&amp;gt;(Func&amp;lt;A, B, R&amp;gt; input)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; a =&amp;gt; b =&amp;gt; input(a, b);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Func&amp;lt;A, Func&amp;lt;B, Func&amp;lt;C,R&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;A, B, C, R&amp;gt;(Func&amp;lt;A, B, C, R&amp;gt; input)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; a =&amp;gt; b =&amp;gt; c =&amp;gt; input(a, b, c);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Rather nice, even if I say so myself.&lt;/p&gt;

&lt;p&gt;Of course this little experiment has many limitations. For a start it only understands functions in terms of Func&amp;lt; … &amp;gt;, so you can’t have more than one function of each ‘type’. You couldn’t have two Func&amp;lt;int,int&amp;gt; for example, which might be somewhat limiting.&lt;/p&gt;

&lt;p&gt;The code is on GitHub &lt;a href="https://github.com/mikehadlow/Mike.Spikes/tree/master/Mike.Spikes/CurryContainer"&gt;here&lt;/a&gt; if you want to have a play.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/1Oa5boozpB0/a-functional-ioc-container.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/10/a-functional-ioc-container.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-1273684278024365061</guid><pubDate>Wed, 03 Oct 2012 11:07:00 +0000</pubDate><atom:updated>2012-10-03T12:22:07.028+01:00</atom:updated><title>EasyNetQ Cluster Support</title><description>&lt;p&gt;&lt;a href="http://easynetq.com"&gt;EasyNetQ&lt;/a&gt;, my super simple .NET API for &lt;a href="http://rabbitmq.com"&gt;RabbitMQ&lt;/a&gt;, now (from version 0.7.2.34) supports RabbitMQ clusters without any need to deploy a load balancer.&lt;/p&gt;  &lt;p&gt;Simply list the nodes of the cluster in the connection string ...&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;var bus = RabbitHutch.CreateBus(&amp;quot;host=ubuntu:5672,ubuntu:5673&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example I have set up a cluster on a single machine, 'ubuntu', with node 1 on port 5672 and node 2 on port 5673. When the CreateBus statement executes, EasyNetQ will attempt to connect to the first host listed (ubuntu:5672). If it fails to connect it will attempt to connect to the second host listed (ubuntu:5673). If neither node is available it will sit in a re-try loop attempting to connect to both servers every five seconds. It logs all this activity to the registered IEasyNetQLogger. You might see something like this if the first node was unavailable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DEBUG: Trying to connect
ERROR: Failed to connect to Broker: 'ubuntu', Port: 5672 VHost: '/'. ExceptionMessage: 'None of the specified endpoints were reachable'
DEBUG: OnConnected event fired
INFO: Connected to RabbitMQ. Broker: 'ubuntu', Port: 5674, VHost: '/'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the node that EasyNetQ is connected to fails, EasyNetQ will attempt to connect to the next listed node. Once connected, it will re-declare all the exchanges and queues and re-start all the consumers. Here's an example log record showing one node failing then EasyNetQ connecting to the other node and recreating the subscribers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;INFO: Disconnected from RabbitMQ Broker
DEBUG: Trying to connect
DEBUG: OnConnected event fired
DEBUG: Re-creating subscribers
INFO: Connected to RabbitMQ. Broker: 'ubuntu', Port: 5674, VHost: '/'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You get automatic fail-over out of the box. That’s pretty cool.&lt;/p&gt;

&lt;p&gt;If you have multiple services using EasyNetQ to connect to a RabbitMQ cluster, they will all initially connect to the first listed node in their respective connection strings. For this reason the EasyNetQ cluster support is not really suitable for load balancing high throughput systems. I would recommend that you use a dedicated hardware or software load balancer instead, if that’s what you want.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/nSyrLCMBeAw/easynetq-cluster-support.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>0</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/10/easynetq-cluster-support.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-7659989202506728939</guid><pubDate>Fri, 28 Sep 2012 15:30:00 +0000</pubDate><atom:updated>2012-09-28T16:35:50.305+01:00</atom:updated><title>Parsing a Connection String With Sprache</title><description>&lt;p&gt;&lt;a href="https://github.com/sprache/Sprache"&gt;Sprache&lt;/a&gt; is a very cool lightweight parser library for C#. Today I was experimenting with parsing &lt;a href="http://easynetq.com/"&gt;EasyNetQ&lt;/a&gt; connection strings, so I thought I’d have a go at getting Sprache to do it. An EasyNetQ connection string is a list of key-value pairs like this:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;key1=value1;key2=value2;key3=value3&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;The motivation for looking at something more sophisticated than simply chopping strings based on delimiters, is that I’m thinking of having more complex values that would themselves need parsing. But that’s for the future, today I’m just going to parse a simple connection string where the values can be strings or numbers (ushort to be exact).&lt;/p&gt;

&lt;p&gt;So, I want to parse a connection string that looks like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;virtualHost=Copa;username=Copa;host=192.168.1.1;password=abc_xyz;port=12345;requestedHeartbeat=3&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;… into a strongly typed structure like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ConnectionConfiguration : IConnectionConfiguration&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Host { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ushort&lt;/span&gt; Port { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; VirtualHost { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; UserName { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Password { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ushort&lt;/span&gt; RequestedHeartbeat { get; set; }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;



&lt;p&gt;I want it to be as easy as possible to add new connection string items.&lt;/p&gt;

&lt;p&gt;First let’s define a name for a function that updates a ConnectionConfiguration. A uncommonly used version of the ‘using’ statement allows us to give a short name to a complex type:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; UpdateConfiguration = Func&amp;lt;ConnectionConfiguration, ConnectionConfiguration&amp;gt;;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now lets define a little function that creates a Sprache parser for a key value pair. We supply the key and a parser for the value and get back a parser that can update the ConnectionConfiguration.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Parser&amp;lt;UpdateConfiguration&amp;gt; BuildKeyValueParser&amp;lt;T&amp;gt;(&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; keyName,&lt;br /&gt;    Parser&amp;lt;T&amp;gt; valueParser,&lt;br /&gt;    Expression&amp;lt;Func&amp;lt;ConnectionConfiguration, T&amp;gt;&amp;gt; getter)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;br /&gt;        from key &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Parse.String(keyName).Token()&lt;br /&gt;        from separator &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Parse.Char(&lt;span style="color: #006080"&gt;'='&lt;/span&gt;)&lt;br /&gt;        from &lt;span style="color: #0000ff"&gt;value&lt;/span&gt; &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; valueParser&lt;br /&gt;        select (Func&amp;lt;ConnectionConfiguration, ConnectionConfiguration&amp;gt;)(c =&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            CreateSetter(getter)(c, &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; c;&lt;br /&gt;        });&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The CreateSetter is a little function that turns a property expression (like x =&amp;gt; x.Name) into an Action&amp;lt;TTarget, TProperty&amp;gt;.&lt;/p&gt;

&lt;p&gt;Next let’s define parsers for string and number values:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Parser&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt; Text = Parse.CharExcept(&lt;span style="color: #006080"&gt;';'&lt;/span&gt;).Many().Text();&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Parser&amp;lt;&lt;span style="color: #0000ff"&gt;ushort&lt;/span&gt;&amp;gt; Number = Parse.Number.Select(&lt;span style="color: #0000ff"&gt;ushort&lt;/span&gt;.Parse);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Now we can chain a series of BuildKeyValueParser invocations and Or them together so that we can parse any of our expected key-values:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Parser&amp;lt;UpdateConfiguration&amp;gt; Part = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Parser&amp;lt;UpdateConfiguration&amp;gt;&amp;gt;&lt;br /&gt;{&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;host&amp;quot;&lt;/span&gt;, Text, c =&amp;gt; c.Host),&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;port&amp;quot;&lt;/span&gt;, Number, c =&amp;gt; c.Port),&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;virtualHost&amp;quot;&lt;/span&gt;, Text, c =&amp;gt; c.VirtualHost),&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;requestedHeartbeat&amp;quot;&lt;/span&gt;, Number, c =&amp;gt; c.RequestedHeartbeat),&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;username&amp;quot;&lt;/span&gt;, Text, c =&amp;gt; c.UserName),&lt;br /&gt;    BuildKeyValueParser(&lt;span style="color: #006080"&gt;&amp;quot;password&amp;quot;&lt;/span&gt;, Text, c =&amp;gt; c.Password),&lt;br /&gt;}.Aggregate((a, b) =&amp;gt; a.Or(b));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Each invocation of BuildKeyValueParser defines an expected key-value pair of our connection string. We just give the key name, the parser that understands the value, and the property on ConnectionConfiguration that we want to update. In effect we’ve defined a little DSL for connection strings. If I want to add a new connection string value, I simply add a new property to ConnectionConfiguration and a single line to the above code.&lt;/p&gt;

&lt;p&gt;Now lets define a parser for the entire string, by saying that we’ll parse any number of key-value parts:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Parser&amp;lt;IEnumerable&amp;lt;UpdateConfiguration&amp;gt;&amp;gt; ConnectionStringBuilder =&lt;br /&gt;    from first &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Part&lt;br /&gt;    from rest &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Parse.Char(&lt;span style="color: #006080"&gt;';'&lt;/span&gt;).Then(_ =&amp;gt; Part).Many()&lt;br /&gt;    select Cons(first, rest);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;All we have to do now is parse the connection string and apply the chain of update functions to a ConnectionConfiguration instance:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IConnectionConfiguration Parse(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; connectionString)&lt;br /&gt;{&lt;br /&gt;    var updater = ConnectionStringGrammar.ConnectionStringBuilder.Parse(connectionString);&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; updater.Aggregate(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ConnectionConfiguration(), (current, updateFunction) =&amp;gt; updateFunction(current));&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;





&lt;p&gt;We get lots of nice things out of the box with Sprache, one of the best is the excellent error messages:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;Parsing failure: unexpected &lt;span style="color: #006080"&gt;'x'&lt;/span&gt;; expected host or port or virtualHost or requestedHeartbeat or username or password (Line 1, Column 1).&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Sprache is really nice for this kind of task. I’d recommend checking it out.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/wsWqBqRK1e8/parsing-connection-string-with-sprache.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>5</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/09/parsing-connection-string-with-sprache.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-15136575.post-383578744118389713</guid><pubDate>Tue, 25 Sep 2012 12:50:00 +0000</pubDate><atom:updated>2012-09-25T13:50:00.876+01:00</atom:updated><title>Replacing EasyNetQ Components</title><description>&lt;p&gt;&lt;a href="http://easynetq.com/"&gt;EasyNetQ&lt;/a&gt;, my simple .NET API for &lt;a href="http://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt;, is a library composed of small components. Until today, the code simply wired the components in a messy hard-coded routine. Now it has its own &lt;a href="https://github.com/mikehadlow/EasyNetQ/blob/master/Source/EasyNetQ/DefaultServiceProvider.cs"&gt;tiny internal IoC container&lt;/a&gt;.&amp;#160; When you write:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var bus = RabbitHutch.CreateBus(&lt;span style="color: #006080"&gt;&amp;quot;host=localhost&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;... the static method CreateBus registers the components with the container and then resolves the IBus instance. The really cool thing about this is that it allows you, the user, to replace &lt;em&gt;any&lt;/em&gt; of the internal components, including IBus, with your own implementations. An overload of the CreateBus method provides the hook which gives you access to the component registration. The signature looks like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; IBus CreateBus(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; connectionString, Action&amp;lt;IServiceRegister&amp;gt; registerServices)&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The IServiceRegister interface provides a single method:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IServiceRegister&lt;br /&gt;{&lt;br /&gt;    IServiceRegister Register&amp;lt;TService&amp;gt;(Func&amp;lt;IServiceProvider, TService&amp;gt; serviceCreator) &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; TService : &lt;span style="color: #0000ff"&gt;class&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;So to register your own logger, based on IEasyNetQLogger, you'd write this code:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var logger = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyLogger(); &lt;span style="color: #008000"&gt;// MyLogger implements IEasyNetQLogger&lt;/span&gt;&lt;br /&gt;var bus = RabbitHutch.CreateBus(connectionString, &lt;br /&gt;    serviceRegister =&amp;gt; serviceRegister.Register(serviceProvider =&amp;gt; logger));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The Register method's argument, Func&amp;lt;IServiceProvider, TService&amp;gt;, is a function that's run when CreateBus pulls together the components to make an IBus instance. IServiceProvider looks like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IServiceProvider&lt;br /&gt;{&lt;br /&gt;    TService Resolve&amp;lt;TService&amp;gt;() &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; TService : &lt;span style="color: #0000ff"&gt;class&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This allows you to access other services that EasyNetQ provides. If for example you wanted to replace the default serializer with your own implementation of ISerializer, and you wanted to construct it with a reference to the internal logger, you could do this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;var bus = RabbitHutch.CreateBus(connectionString, serviceRegister =&amp;gt; serviceRegister.Register(&lt;br /&gt;    serviceProvider =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MySerializer(serviceProvider.Resolve&amp;lt;IEasyNetQLogger&amp;gt;())));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;There’s nothing to stop you registering your own interfaces with the container that you can then use with your implementations of EasyNetQ’s service interfaces.&lt;/p&gt;

&lt;p&gt;To see the complete list of components that make up the IBus instance, and how they are assembled, take a look at the &lt;a href="https://github.com/mikehadlow/EasyNetQ/blob/master/Source/EasyNetQ/ComponentRegistration.cs"&gt;ComponentRegistration&lt;/a&gt; class.&lt;/p&gt;  </description><link>http://feedproxy.google.com/~r/CodeRant/~3/juqaMRlmYsM/replacing-easynetq-components.html</link><author>noreply@blogger.com (Mike Hadlow)</author><thr:total>2</thr:total><feedburner:origLink>http://mikehadlow.blogspot.com/2012/09/replacing-easynetq-components.html</feedburner:origLink></item></channel></rss>
