<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en" xml:base="http://wildpointer.org/wp-atom.php">
	<title type="text">wildpointer*</title>
	<subtitle type="text">referencing whatever comes to mind, by chet nichols</subtitle>

	<updated>2011-06-19T07:27:40Z</updated>

	<link rel="alternate" type="text/html" href="http://wildpointer.org" />
	<id>http://wildpointer.org/feed/atom/</id>
	

	<generator uri="http://wordpress.org/" version="3.0.4">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/chet" /><feedburner:info uri="chet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[a little abstraction goes a long way (fun with SOAP APIs)]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/k7XPO5VIBKs/" />
		<id>http://wildpointer.org/?p=165</id>
		<updated>2011-06-19T07:27:40Z</updated>
		<published>2011-06-19T07:18:55Z</published>
		<category scheme="http://wildpointer.org" term="code" /><category scheme="http://wildpointer.org" term="tech" /><category scheme="http://wildpointer.org" term="theory" />		<summary type="html"><![CDATA[I&#8217;ve been working with SOAP services a lot lately. Is that moaning I hear? It is! But you know, as long as I&#8217;m provided an API that works, and isn&#8217;t *too* slow, I&#8217;ll deal! However, it&#8217;s nice everyone finally realized XML.. well.. isn&#8217;t the best for stuff like this, and are moving away from it. [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2011/06/18/a-little-abstraction-goes-a-long-way-fun-with-soap-apis/">&lt;p&gt;I&amp;#8217;ve been working with SOAP services a lot lately. Is that moaning I hear? It is! But you know, as long as I&amp;#8217;m provided an API that works, and isn&amp;#8217;t *too* slow, I&amp;#8217;ll deal! However, it&amp;#8217;s nice everyone finally realized XML.. well.. isn&amp;#8217;t the best for stuff like this, and are moving away from it. Took them long enough. &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;This should be a relatively quick post, but I think the point it makes is nice. My colleague Paul once told me my code looks like a 5 year old wrote it. I try to keep things simple, and make things simple. The goal is to take something that could have been complex (or sounds complex), and break it down into little logical chunks you can make sense of the first time through. I&amp;#8217;m also a 5 year old, so that might have something to do with it.&lt;/p&gt;
&lt;p&gt;In this case, I was working on interacting with a SOAP API for a load balancing product. Their API is actually really nice, but with the amount of settings you can change for certain objects, their free, open code samples definitely wouldn&amp;#8217;t fly for an enterprise-class tool. Here it is:&lt;/p&gt;
&lt;h3&gt;Original Code&lt;/h3&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;addservice&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;
    SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'name'&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'test-svc'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'IP'&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'1.2.3.4'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'servicetype'&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'http'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'port'&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'80'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'maxreq'&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;'8'&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;result&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If this is all you need to do, then it definitely works. But, what happens if you need to set more than 5 values? Maybe you have 10 you need to set? Maybe the number of arguments is going to be dynamic every time you run it (ie: you don&amp;#8217;t know if maxreq is going to be set EVERY time). Well, that could be a pain in the bootay. &lt;/p&gt;
&lt;p&gt;There are a couple things we&amp;#8217;re going to end up doing here, but first thing first: this whole multi-argument thing isn&amp;#8217;t going to fly if I want to make things dynamic (ie: loop through a data set to build your input key/val pairs). I also reeeaaally don&amp;#8217;t want to have to say &lt;em&gt;SOAP::Data-&gt;name&lt;/em&gt; for every key/val pair I set. I&amp;#8217;d rather just be able to define my arguments as a hash (or dictionary, or whatever your $langauge calls it), and let something take care of the dirty work for me. Simple!&lt;/p&gt;
&lt;p&gt;Since our SOAP call takes an array of SOAP::Data objects, all we really need to do is make something that takes a hash, converts it into an array of SOAP::Data objects, then pass to our SOAP call. We&amp;#8217;re going to use an arrayref to make things easier. I think pointers are fun, so I tend to just use ref&amp;#8217;s for everything. I hope that&amp;#8217;s okay.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&amp;nbsp;
&lt;span style="color: #000000; font-weight: bold;"&gt;sub&lt;/span&gt; hash_to_soap_data &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;    &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@_&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap_data&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066;"&gt;sort&lt;/span&gt; &lt;span style="color: #000066;"&gt;keys&lt;/span&gt; &lt;span style="color: #339933;"&gt;%&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
        &lt;span style="color: #000066;"&gt;push&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;@&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$soap_data&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #000066;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap_data&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ta da! That wasn&amp;#8217;t so bad, was it? Now, we can do something like this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&amp;nbsp;
&lt;span style="color: #666666; font-style: italic;"&gt;# we could also just define the hash&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# as the argument to hash_to_soap_data&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# if you wanted to smash it together even&lt;/span&gt;
&lt;span style="color: #666666; font-style: italic;"&gt;# more.&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;
    name &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;test-svc&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    servicetype &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;http&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    port &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;80&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    ipaddress &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;1.2.3.4&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap_data&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; hash_to_soap_data&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;addservice&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;@&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$soap_data&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Looking better! But you know, it&amp;#8217;s still a little bit too annoying. I don&amp;#8217;t want to have to define a hash, pass it to a function X, then take the result of function X and pass it to  function Y. The ideal code would just to be to make an API call by passing a hash to a function, and let the underlying code handle making things happen. &lt;strong&gt;In short, we&amp;#8217;re going to abstract things.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is where we decide how we want to actually interface with our function. In our case, I think something like this is nice:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; call_api&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$func_name&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that example, we can just make our API call in one easy line by passing a hashref. Yes, we&amp;#8217;ll have a function &lt;em&gt;call_api()&lt;/em&gt; to deal with, but that&amp;#8217;s part of the abstraction. &lt;/p&gt;
&lt;p&gt;Ultimately, this will eventually allow us to easily change the inner-workings of &lt;em&gt;call_api()&lt;/em&gt; later on without ever having to change the rest of our code. For example, maybe the API changes from SOAP to a RESTful style, maybe using JSON. By abstracting, you can re-write &lt;em&gt;call_api()&lt;/em&gt; to just make RESTful calls and return JSON results.&lt;/p&gt;
&lt;p&gt;In any case, let&amp;#8217;s write it:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&amp;nbsp;
&lt;span style="color: #000000; font-weight: bold;"&gt;sub&lt;/span&gt; call_api &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #666666; font-style: italic;"&gt;# note: $soap is our SOAP or SOAP::Lite object&lt;/span&gt;
    &lt;span style="color: #666666; font-style: italic;"&gt;# that we have already defined elsewhere.&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$func&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@_&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@soap_data&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000066;"&gt;sort&lt;/span&gt; &lt;span style="color: #000066;"&gt;keys&lt;/span&gt; &lt;span style="color: #339933;"&gt;%&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
        &lt;span style="color: #000066;"&gt;push&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@soap_data&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; SOAP&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;Data&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;name&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$key&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$soap&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$func&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;@soap_data&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that complete, now we just implement:&lt;/p&gt;
&lt;h3&gt;Abstracted Code&lt;/h3&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; call_api&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;addservice&amp;quot;&lt;/span&gt; &lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    name &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;test-svc&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    ip &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;1.2.3.4&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    servicetype &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;http&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    port &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;80&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;
    maxreq &lt;span style="color: #339933;"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;8&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;    
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Your first thought probably is: it looks &lt;b&gt;almost&lt;/b&gt; exactly like our original code! &lt;em&gt;What&amp;#8217;s the point? You suck?&lt;/em&gt; The point is you have now abstracted things just enough to make things a lot easier to manage in the long run. Based on inputs, you can dynamically assign the function (ie: maybe it&amp;#8217;s &lt;em&gt;addservice&lt;/em&gt; to start, but based on a conditional, it may change to &lt;em&gt;setservice&lt;/em&gt;, and all you need to change is &lt;em&gt;$func_name&lt;/em&gt;. Your single API line still works as expected, so no need for multiple API lines. Same with your data hash. You can build your input key/val pairs manually, dynamically based on IO, other conditionals, etc, and never have to change that one friendly line:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$result&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; call_api&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$func_name&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$hashref&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It also helps with troubleshooting, because you know that all API calls ultimately funnel in to &lt;em&gt;call_api()&lt;/em&gt;. And, like I mentioned before, if the server-side ever changes from SOAP to whatever the latest and greatest is, you should have hopefully abstracted things enough to just be able to change your single function without affecting everything else.&lt;/p&gt;
&lt;p&gt;In practice, I&amp;#8217;ve found this to work pretty well. There will be one-offs now and then, and you&amp;#8217;ll have to account for them. However, over time, you&amp;#8217;ll start to be able to identify places for abstraction beforehand, which in the long run will just help you to make pretty sweet abstractions for doing anything. This doesn&amp;#8217;t just apply to Perl, and it doesn&amp;#8217;t just apply to SOAP. I try to apply it to as many places I can. It tends to work best in an object-oriented codebase (yes, even Perl objects), but even abstraction via functions can be good too!&lt;/p&gt;
&lt;p&gt;Someone joked once about &amp;#8220;hello world&amp;#8221; for a new programmer is 1 line, while it&amp;#8217;s 250 lines with 5 layers of abstraction and an additional 20 comments for an experienced programmer. While it&amp;#8217;s not far off, there&amp;#8217;s definitely a sane balance somewhere in the middle, and that&amp;#8217;s part of the journey &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt;  Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/k7XPO5VIBKs" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2011/06/18/a-little-abstraction-goes-a-long-way-fun-with-soap-apis/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2011/06/18/a-little-abstraction-goes-a-long-way-fun-with-soap-apis/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://wildpointer.org/2011/06/18/a-little-abstraction-goes-a-long-way-fun-with-soap-apis/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[perl typecast beware! weak typing and the range operator.]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/cdoQy8gNvj4/" />
		<id>http://chetnichols.org/?p=156</id>
		<updated>2010-11-24T19:29:26Z</updated>
		<published>2010-11-24T07:46:01Z</published>
		<category scheme="http://wildpointer.org" term="perl" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[Background: I&#8217;ve been working on a suite of tools for the past few months to help with some config automation, and one of the config files allows you to put in a range (ie: 1-100, or even 0200-0399). The tool will take the range, look for running jobs with an ID in that range, then [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2010/11/23/perl-typecast-beware-weak-typing-and-the-range-operator/">&lt;p&gt;Background: I&amp;#8217;ve been working on a suite of tools for the past few months to help with some config automation, and one of the config files allows you to put in a range (ie: 1-100, or even 0200-0399). The tool will take the range, look for running jobs with an ID in that range, then do something with it. In some cases, we do have jobs whose ID starts with a zero (or multiple zeroes), so the leading zero can be important. &lt;strong&gt;This is where I ran into some interesting discoveries!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Okay, so, to aid in making it easy to iterate over the range, I was using the &lt;em&gt;range operator&lt;/em&gt; in Perl, which is the little &amp;#8220;..&amp;#8221; thing you can do, (or dotdot, or dot-dot, or whatever you might call it). For example:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt; 
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;%s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$_&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;.. or, being a little more realistic:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;1&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;   &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #cc66cc;"&gt;100&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;%s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run those, and you&amp;#8217;ll get all the numbers from 1 to 100. Fantastic. Want to get even more crazy? How about letters. Yeah, it does those too. Sweet.&lt;/p&gt;
&lt;p&gt;In this example, we&amp;#8217;ll get everything from a to z:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;   &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;z&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;%s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hrmm, what about if we want the range from a to zzzzz? Yup, it does that too:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;   &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;zzzzz&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;%s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$i&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Of course, I&amp;#8217;m not giving you the output, because that would be insane.. but it works. Nice!&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s actually a bunch more you can do with it, too. There&amp;#8217;s even a &amp;#8220;&amp;#8230;&amp;#8221; (dot-dot-dot) that you can do something with (but I forget what). However, it is all documented here:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://perldoc.perl.org/perlop.html#Range-Operators"&gt;http://perldoc.perl.org/perlop.html#Range-Operators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But that&amp;#8217;s not what this post is about. It&amp;#8217;s about something interesting I ran into. Still interested? Good. Keep reading.&lt;/p&gt;
&lt;p&gt;So anyway, in the case of my config parser, I would parse out ranges as tokens (ie: 0200-0300), split, and do a search across the range. For example:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# $range = &amp;quot;0200-0300&amp;quot;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$range&lt;/span&gt; &lt;span style="color: #339933;"&gt;=~&lt;/span&gt; &lt;span style="color: #009966; font-style: italic;"&gt;/^(\d+)\-(\d+)$/&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;found_job_id&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      do_something_with&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This basically allows us to lazily put large ranges into the config, but requires us to be more specific when creating jobs with new IDs (to ensure it falls within our range). In any case, this works exactly as we&amp;#8217;d expect, leading zeroes and all.&lt;/p&gt;
&lt;p&gt;Now, as part of error checking, I decided I should make sure that the &lt;em&gt;$start&lt;/em&gt; value was less than the &lt;em&gt;$end&lt;/em&gt; value, since the range operator will not work if &lt;em&gt;$start&lt;/em&gt; is greater than &lt;em&gt;$end&lt;/em&gt;. It will just return an empty set. This is documented and not an error, so I wanted to throw an error.&lt;/p&gt;
&lt;p&gt;To do so, I just modified my code to implement a simple comparison check:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# $range = &amp;quot;0200-0300&amp;quot;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$range&lt;/span&gt; &lt;span style="color: #339933;"&gt;=~&lt;/span&gt; &lt;span style="color: #009966; font-style: italic;"&gt;/^(\d+)\-(\d+)$/&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   throw_error_and_exit&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;Start is greater than end! Fix your range, buddy.&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;found_job_id&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      do_something_with&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The change seemed harmless enough, but when I ran the config parser again to make sure things worked, I got nothing. Literally. Nothing. It appeared as if everything broke. Weird. No errors, the range is valid (I was using 0100-0200), but, um, what?&lt;/p&gt;
&lt;p&gt;After scratching my head for about 20 seconds, I went, &amp;#8220;aha!&amp;#8221; Yes, just like that.&lt;/p&gt;
&lt;p&gt;Sure enough, &lt;strong&gt;when I parse out my range from the config, the values I get back are strings&lt;/strong&gt; (which makes sense), so in the case of &lt;em&gt;0200-0300&lt;/em&gt;, the range operator is actually performing the operation based on the string value of each, using what they consider the &amp;#8220;magical auto-increment algorithm&amp;#8221; (per the Perl documentation). I don&amp;#8217;t know what type of analysis it does, but it&amp;#8217;s probably just based on ASCII values.&lt;/p&gt;
&lt;p&gt;In any case, &lt;strong&gt;AFTER&lt;/strong&gt; I added my new comparison operation (to check if &lt;em&gt;$start&lt;/em&gt; was greater than &lt;em&gt;$end&lt;/em&gt;), &lt;strong&gt;Perl had to typecast my variables&lt;/strong&gt; (which were strings) &lt;strong&gt;to integers to compare them, therefore dropping the leading zeroes&lt;/strong&gt;! Here&amp;#8217;s something a little more graphic:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #666666; font-style: italic;"&gt;# $range = &amp;quot;0200-0300&amp;quot;&lt;/span&gt;
&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$range&lt;/span&gt; &lt;span style="color: #339933;"&gt;=~&lt;/span&gt; &lt;span style="color: #009966; font-style: italic;"&gt;/^(\d+)\-(\d+)$/&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# &amp;lt;--- STRINGS&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# &amp;lt;--- OMG NOW THEY'RE INTEGERS&lt;/span&gt;
   throw_error_and_exit&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;Start is greater than end! Fix that.&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$start&lt;/span&gt; &lt;span style="color: #339933;"&gt;..&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$end&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt; &lt;span style="color: #666666; font-style: italic;"&gt;# &amp;lt;--- HEY WHERE'D THE LEADING ZERO GO?&lt;/span&gt;
   &lt;span style="color: #b1b100;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;found_job_id&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      do_something_with&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$id&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is one of those things with Perl where a mix of dynamic and weak typing features lead to strings magically (and uncontrollably) being casted to integers where needed. In most cases, having a language with both dynamic and weak typing on variables can be nice, but it can also lead to laziness and unexpected results if you&amp;#8217;re not careful. &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;Well, that&amp;#8217;s all for today. Just thought I&amp;#8217;d share that one.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/cdoQy8gNvj4" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2010/11/23/perl-typecast-beware-weak-typing-and-the-range-operator/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2010/11/23/perl-typecast-beware-weak-typing-and-the-range-operator/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	<feedburner:origLink>http://wildpointer.org/2010/11/23/perl-typecast-beware-weak-typing-and-the-range-operator/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[offload Mac OS X swap with dynamic_pager and an SDXC card]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/R6h73YkXN78/" />
		<id>http://chetnichols.org/?p=126</id>
		<updated>2010-11-24T05:24:40Z</updated>
		<published>2010-07-24T05:55:22Z</published>
		<category scheme="http://wildpointer.org" term="apple" /><category scheme="http://wildpointer.org" term="tech" /><category scheme="http://wildpointer.org" term="hardware" /><category scheme="http://wildpointer.org" term="macosx" /><category scheme="http://wildpointer.org" term="sysadmin" />		<summary type="html"><![CDATA[I have an idea. So, I&#8217;ve run into some issues with OS X where it will start swapping, even though there is more than enough physical RAM available. I&#8217;m assuming this has to do with the OS deciding certain processes have been idle for long enough; it will pre-emptively swap them out with the assumption [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2010/07/23/offload-mac-os-x-swap-with-dynamic_pager-and-an-sdxc-card/">&lt;p&gt;I have an idea. &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;So, I&amp;#8217;ve run into some issues with OS X where it will start swapping, even though there is more than enough physical RAM available. I&amp;#8217;m assuming this has to do with the OS deciding certain processes have been idle for long enough; it will pre-emptively swap them out with the assumption of a need for new, soon-to-be &amp;#8220;things&amp;#8221; requiring memory. This would give the user the perception that their machine loads up things faster when said &amp;#8220;things&amp;#8221; need to be loaded. That could be total BS on my part, but until I have a full technical explanation of it, that&amp;#8217;s the story I&amp;#8217;m going to stick to.&lt;/p&gt;
&lt;p&gt;Now, I&amp;#8217;m used to Linux, where you can set &lt;em&gt;/proc/sys/vm/swappiness=0&lt;/em&gt; and effectively stop swapping altogether. As long as there&amp;#8217;s enough physical memory available, it will keep using it. If you run out, then OOM kill (assuming you haven&amp;#8217;t disabled it via &lt;em&gt;/proc/sys/vm/oom-kill&lt;/em&gt;) will come and start playing whack-a-mole with your processes. Sweet. This is good.&lt;/p&gt;
&lt;p&gt;Since OS X doesn&amp;#8217;t have this, what *does* it have? Well, it has a process called &lt;strong&gt;dynamic_pager&lt;/strong&gt;, which oversees the management of swap (and swap files). There are two files we&amp;#8217;re interested in here:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
/sbin/dynamic_pager&lt;br /&gt;
/System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
The binary is obvious, but the LaunchDaemon plist is what we&amp;#8217;re really interested in here. This is what tells &lt;em&gt;dynamic_pager&lt;/em&gt; to kick off at launch. Now, the plist is in binary format, so to really get a look (from Terminal, unless you use the plist Editor), you can convert it to XML:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
plutil -convert xml1 com.apple.dynamic_pager.plist&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
From there, the contents of the file will be something like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&amp;gt;&lt;br /&gt;
&amp;lt;plist version="1.0"&amp;gt;&lt;br /&gt;
&amp;lt;dict&amp;gt;&lt;br /&gt;
    &amp;lt;key&amp;gt;EnableTransactions&amp;lt;/key&amp;gt;&lt;br /&gt;
    &amp;lt;true/&amp;gt;&lt;br /&gt;
    &amp;lt;key&amp;gt;HopefullyExitsLast&amp;lt;/key&amp;gt;&lt;br /&gt;
    &amp;lt;true/&amp;gt;&lt;br /&gt;
    &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;&lt;br /&gt;
    &amp;lt;string&amp;gt;com.apple.dynamic_pager&amp;lt;/string&amp;gt;&lt;br /&gt;
    &amp;lt;key&amp;gt;OnDemand&amp;lt;/key&amp;gt;&lt;br /&gt;
    &amp;lt;false/&amp;gt;&lt;br /&gt;
    &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;&lt;br /&gt;
    &amp;lt;array&amp;gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;/sbin/dynamic_pager&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;-F&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;/private/var/vm/swapfile&amp;lt;/string&amp;gt;&lt;br /&gt;
    &amp;lt;/array&amp;gt;&lt;br /&gt;
&amp;lt;/dict&amp;gt;&lt;br /&gt;
&amp;lt;/plist&amp;gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Fantastic! By the way, to convert back to binary when you&amp;#8217;re done, you can do this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
plutil -convert binary com.apple.dynamic_pager.plist&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
Now that we&amp;#8217;re looking at our plist, you&amp;#8217;ll notice the config setting for &lt;em&gt;-F /private/var/vm/swapfile&lt;/em&gt;. This is the base name used by dynamic_pager for when it needs to create a new swapfile. If you do a ps, you&amp;#8217;ll notice it running:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
[chet@cilantro ~]$ ps ax | grep dynamic_pager&lt;br /&gt;
   39   ??  Ss     0:00.02 /sbin/dynamic_pager -F /private/var/vm/swapfile&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
And if you check out &lt;em&gt;/private/var/vm&lt;/em&gt;:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
[chet@cilantro ~]$ ls -lh /private/var/vm/&lt;br /&gt;
-rw-------  1 root  wheel    64M Jul 19 22:02 swapfile0&lt;br /&gt;
-rw-------  1 root  wheel    64M Jul 23 21:38 swapfile1&lt;br /&gt;
-rw-------  1 root  wheel   128M Jul 23 21:38 swapfile2&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
As you can see, &lt;em&gt;dynamic_pager&lt;/em&gt; is alive and well, managing a set of swap files on my local disk. Side note about the listing above: as the need for swap increases (or decreases) with activity, &lt;em&gt;dynamic_pager&lt;/em&gt; will take the liberty of dynamically changing the swapfile size for you. You can also specify the &lt;strong&gt;-S&lt;/strong&gt; flag in your plist to specify a static file size.&lt;/p&gt;
&lt;p&gt;In any case, here&amp;#8217;s where the fun starts: I don&amp;#8217;t know about you, but the disk in my MacBook Pro isn&amp;#8217;t anything super-amazing. Maybe it&amp;#8217;s on a 3Gb/sec SATA channel, but it&amp;#8217;s a 5400rpm drive, and random writes usually yield somewhere around 12MB/sec. Sequential writes will hit about 60MB/sec at times, but lets be honest, random is what we should be caring about; they&amp;#8217;re nothing spectacular.&lt;/p&gt;
&lt;p&gt;So, when I&amp;#8217;m in the middle of working on something, have a few Flash widgets running, doing who knows what, and I start to experience the lovely effects of swapping, it&amp;#8217;s not always the best experience. On top of slowing things down, it&amp;#8217;s also adding a lot of extra physical load to the disk. Poopy. I wish there was a way to decouple swap from my physical root disk, and possibly put it somewhere that might help out swap performance a bit. Oh wait, I have a thought!&lt;/p&gt;
&lt;p&gt;Thanks to the designers at Apple, who graciously added an SD card slot to the latest line of MacBook Pro&amp;#8217;s, we now have an option for swap: &lt;strong&gt;offload it to an SD card!&lt;/strong&gt; Now, a plain old SD card might not be the best (even a class 10 would only give you 10MB/sec max, and under real world conditions it&amp;#8217;s obviously going to be worse.. about 2MB/sec), but with the latest SDXC technology, Kingston, Toshiba (and others) have developed cards hitting between 50-60MB/sec on writes, which is very similar to the sequential writes on our local disk. Again, under real-world, random usage, it&amp;#8217;s going to be less, but should be relatively similar to the random writes of our local disk. To try it out, just slide in your SDXC card, and update your plist to something like the following:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;/sbin/dynamic_pager&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;-F&amp;lt;/string&amp;gt;&lt;br /&gt;
        &amp;lt;string&amp;gt;/Volumes/sdxc_swap/swapfile&amp;lt;/string&amp;gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
After that, restart your &lt;em&gt;dynamic_pager&lt;/em&gt; process, and you should be good to go, enjoying an offloaded swap, and totally burn out your SDXC card &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;That being said, I&amp;#8217;d like to mention a couple of things. First, I don&amp;#8217;t have a high performance SDXC card of my own for testing, so performance mileage may vary depending on the card. I know Toshiba is targeting their SDXC cards for use in Netbooks, which is great; it gives us an glimmer of hope that their cards are built for some relatively heavy duty lifting- more than your standard camera SD card; maybe you won&amp;#8217;t burn it out as quickly after all!&lt;/p&gt;
&lt;p&gt;Another thing to point out is that the high performance cards we&amp;#8217;re discussing are all relatively larger.. 32GB or greater in size. Chances are you&amp;#8217;ll [hopefully] never hit this in swap. However, dynamic_pager will also take care of dumping out a &lt;em&gt;sleepimage&lt;/em&gt; file to the swap space, which will be up to however many GB of RAM you may have; take that into consideration when picking a card. You&amp;#8217;ll probably still have leftover space, but just a word of advice.&lt;/p&gt;
&lt;p&gt;That being said, putting your &lt;em&gt;sleepimage&lt;/em&gt; on an SDXC card is actually nice in the sense of security. Put your machine to sleep, pop your SDXC card out, and you basically have locked your laptop down in terms of a thief being able to try and yank whatever you were working on. There are threads out there about people dumping sleep/hibernate images and stealing sensitive data, so this is a nice little side effect of offloading swap to a little card.&lt;/p&gt;
&lt;p&gt;In any case, that&amp;#8217;s all for now. It was a thought I had the other day, so I figured I would share the idea with others. Maybe some people will think it sucks, but I think it&amp;#8217;s kind of fun. If you have a card and would like to dump back some performance data to me, that would be awesome (ie: test via Xbench or the like). And, if I ever get my own card worth testing, I&amp;#8217;ll post an update on how it went! If you&amp;#8217;d also like to tell me how dumb I am, that&amp;#8217;s okay too; I&amp;#8217;m used to it. Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/R6h73YkXN78" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2010/07/23/offload-mac-os-x-swap-with-dynamic_pager-and-an-sdxc-card/#comments" thr:count="6" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2010/07/23/offload-mac-os-x-swap-with-dynamic_pager-and-an-sdxc-card/feed/atom/" thr:count="6" />
		<thr:total>6</thr:total>
	<feedburner:origLink>http://wildpointer.org/2010/07/23/offload-mac-os-x-swap-with-dynamic_pager-and-an-sdxc-card/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[writing a custom Netscaler health check for NTP]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/-yMd9RBfn9Y/" />
		<id>http://chetnichols.org/?p=18</id>
		<updated>2010-04-11T09:13:23Z</updated>
		<published>2010-04-11T09:12:48Z</published>
		<category scheme="http://wildpointer.org" term="netscaler" /><category scheme="http://wildpointer.org" term="perl" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[There are lots of load balancing products on the market today. Some are good, some are bad. Opinions aside, one such product is the Citrix Netscaler. Now, the Netscaler has built in health checking for many different types of backend service protocols: HTTP, FTP, DNS, and more. However, one protocol not included is NTP. If [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2010/04/11/writing-a-custom-netscaler-health-check-for-ntp/">&lt;p&gt;There are lots of load balancing products on the market today. Some are good, some are bad. Opinions aside, one such product is the Citrix Netscaler.&lt;/p&gt;
&lt;p&gt;Now, the Netscaler has built in health checking for many different types of backend service protocols: HTTP, FTP, DNS, and more. However, one protocol not included is NTP. If you happen to be load balancing a farm of NTP servers, and want to ensure you&amp;#8217;re not routing to a hosed NTP daemon (even if it&amp;#8217;s ping-able), it would be nice to be able to health check the service [and take it out of rotation if it's not responding].&lt;/p&gt;
&lt;p&gt;Luckily, the Netscaler provides (with documentation) a very flexible way to write your own custom health checks. Using the system, you can test whatever you want, in any way you want, with just a little Perl. Even better, the custom health check subsystem provides a few useful things to simplify the whole process, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;passing in the service IP, and port, as arguments to your script&lt;/li&gt;
&lt;li&gt;passing in a custom argument string (key value pairs, user/pass info, whatever)
&lt;li&gt;handling the timeout for you from a higher level; if your check doesn&amp;#8217;t respond within -respTimeout seconds, it will be considered a failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, for just the basics, this monitor will actually be pretty easy to put together. We are given the IP/port to send an NTP request to, and we don&amp;#8217;t need to worry about a timeout, because the underlying subsystem will handle that for us. All we really need to do is send a request and [hope] for a response!&lt;/p&gt;
&lt;p&gt;That being said, we&amp;#8217;ll need to do a couple things to get to that point. These things are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Load the health check subsystem module.&lt;/li&gt;
&lt;li&gt;Load the Socket module, and create a socket to use to send the request [using the parameters passed in as args].&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From that point, we can build and send our request. Since we don&amp;#8217;t need to worry about handling a timeout, we can just sit there waiting for a response. First up:&lt;/p&gt;
&lt;pre&gt;
use IO::Socket;
use Netscaler::KAS;
&lt;/pre&gt;
&lt;p&gt;We&amp;#8217;ll need both of these modules &amp;#8211; one will tap into the health check subsystem, and the other is so we can send our UDP-based request.&lt;/p&gt;
&lt;p&gt;Next is our function, which we&amp;#8217;ll just call &lt;i&gt;ntp_probe&lt;/i&gt;. It assigns a few variables from &lt;i&gt;$_[0]&lt;/i&gt; (the service IP) and &lt;i&gt;$_[1]&lt;/i&gt; (the service port) as arguments, which get passed in from work within probe().&lt;/p&gt;
&lt;p&gt;So, the magic-fu to this is that, later on, we will pass our &lt;i&gt;ntp_probe&lt;/i&gt; function as a coderef to the KAS probe() command. That will ultimately result in our function being called with the arguments passed in; it is similar to this:&lt;/p&gt;
&lt;pre&gt;
$custom_function-&gt;($host,$port,$args);
&lt;/pre&gt;
&lt;p&gt;If you look at the KAS code (and since it&amp;#8217;s perl, you can), you can see the exact line; this just gives you an idea of what&amp;#8217;s going on.&lt;/p&gt;
&lt;p&gt;In any case, after that, we&amp;#8217;ll create a new UDP socket, send the NTP request message down it, and either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;return 1 if something wasn&amp;#8217;t defined (ip, port, or sock) &amp;#8211; failure!&lt;/li&gt;
&lt;li&gt;return 0 if we got a response &amp;#8211; success!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, we don&amp;#8217;t need to worry about timeouts, since the subsystem will handle that for us. So, here&amp;#8217;s the function in it&amp;#8217;s entirety:&lt;/p&gt;
&lt;pre&gt;
sub ntp_probe {

    my $host    = $_[0];
    my $port    = $_[1];
    my $req     = "\010"."\0"x47;

    if(!$host || !$port) {
        return(1,"Host or port not specified.");
    }

    my $sock = IO::Socket::INET-&gt;new(
        Proto     =&gt; "udp",
        PeerAddr  =&gt; $host,
        PeerPort  =&gt; $port,
    );

   if($sock) {
        $sock-&gt;send($req);
        $sock-&gt;recv($_,1);
        return 0;
    }

    return(1,"Could not create socket");

}
&lt;/pre&gt;
&lt;p&gt;Not bad, was it? Now that we have loaded our modules, and defined a function, the next step is to call the probe() method, with a coderef to our new function, to tell KAS what function to use for probing:&lt;/p&gt;
&lt;pre&gt;
probe(\&amp;#038;ntp_probe);
&lt;/pre&gt;
&lt;p&gt;And you&amp;#8217;re off to the races! Just don&amp;#8217;t forget to start your script with &lt;i&gt;#!/usr/bin/perl&lt;/i&gt;, and it should be good to go &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;p&gt;Now, you might be asking &amp;#8220;how do I actually configure the Netscaler to use this?&amp;#8221; That&amp;#8217;s also just as easy. Let&amp;#8217;s pretend our new script is called &lt;i&gt;customNTP.pl&lt;/i&gt;. Just plop it into the &lt;b&gt;/nsconfig/monitors/&lt;/b&gt; directory, and do something like this from the CLI:&lt;/p&gt;
&lt;pre&gt;
add lb monitor "custom-ntp-mon" USER -scriptName customNTP.pl
   -scriptArgs 1 -dispatcherIP 127.0.0.1 -dispatcherPort 3013
   -interval 20 -respTimeout 3
&lt;/pre&gt;
&lt;p&gt;With that line, you will now have a working NTP healthcheck (20 second intervals, 3 second timeout). Just bind it to your service(s) that need it and enjoy!. Note that the type of monitor is &lt;b&gt;USER&lt;/b&gt;; this is the type used for custom health checks.&lt;/p&gt;
&lt;p&gt;Well, that&amp;#8217;s all for this evening. There are bits and pieces of info like this around the web, on the Citrix AppExpert site, etc. And, even though it wasn&amp;#8217;t too difficult to figure out, hopefully this will help someone out some day.&lt;/p&gt;
&lt;p&gt;Take care!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/-yMd9RBfn9Y" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2010/04/11/writing-a-custom-netscaler-health-check-for-ntp/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2010/04/11/writing-a-custom-netscaler-health-check-for-ntp/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://wildpointer.org/2010/04/11/writing-a-custom-netscaler-health-check-for-ntp/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[apache mod_status: the misleading ReqPerSec metric]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/C6JA2lZ7hWc/" />
		<id>http://chetnichols.org/?p=77</id>
		<updated>2010-04-03T20:07:40Z</updated>
		<published>2010-04-03T18:18:40Z</published>
		<category scheme="http://wildpointer.org" term="apache" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[To be honest, I had never thought twice about it. At my past employer, we had implemented tracking request rate for the Apache hosts by parsing out Total Accesses (ie: Total Requests) from server-status (thanks to our friendly module mod_status), publish that every minute, and let our metrics collection subsystem do a delta between the [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2010/04/03/apache-mod_status-the-misleading-reqpersec-metric/">&lt;p&gt;To be honest, I had never thought twice about it. At my past employer, we had implemented tracking request rate for the Apache hosts by parsing out Total Accesses (ie: Total Requests) from server-status (thanks to our friendly module mod_status), publish that every minute, and let our metrics collection subsystem do a delta between the current and previous to determine a request rate to publish.&lt;/p&gt;
&lt;p&gt;At my new employer, I put something together where the collection subsystem won&amp;#8217;t refer to the previous total for deltas: it just takes whatever you give it and relays that to the metrics backend. Most applications provide you with a request/sec metric these days, so I figured I&amp;#8217;d just use that. Instead of doing deltas on TotalAccesses, I started just relaying ReqPerSec instead. Simple enough, right? For those of you not familiar, here&amp;#8217;s an example of server-status output:&lt;/p&gt;
&lt;pre&gt;
Total Accesses: 400
Total kBytes: 800
CPULoad: 5
Uptime: 12345
ReqPerSec: 20
BytesPerSec: 20000
BytesPerReq: 1024
BusyWorkers: 15
IdleWorkers: 5
&lt;/pre&gt;
&lt;p&gt;Well, amidst my metrics collection testing for the new system, I stumbled upon an interesting detail: I would be nailing the Apache instance with a flood of requests using my friend ab (aka: apachebench). However, I immediately noticed ReqPerSec wasn&amp;#8217;t accurate at all. For example, I would be averaging a test of 300-400 req/s, but ReqPerSec would be displaying 21 req/s. It was as if I wasn&amp;#8217;t sending it requests.&lt;/p&gt;
&lt;p&gt;That being said, the TotalAccesses metric was reflecting the requests I was sending, so I knew the web server was receiving them. Interesting.&lt;/p&gt;
&lt;p&gt;It got me thinking: &amp;#8220;I wonder how Apache determines ReqPerSec?&amp;#8221; Time for some source code action! Sure enough, here&amp;#8217;s what I found:&lt;/p&gt;
&lt;pre language="c"&gt;
ap_rprintf(r, "ReqPerSec: %g\n",
    (float) count / (float) up_time);
&lt;/pre&gt;
&lt;p&gt;Interesting! All Apache does to calculate ReqPerSec is take the total number of requests throughout the life of the parent (&lt;b&gt;count&lt;/b&gt;) and divide that by the total uptime in seconds (&lt;b&gt;up_time&lt;/b&gt;). So, really, ReqPerSec is just an *average* requests per second over the parent&amp;#8217;s lifetime. That&amp;#8217;s NOT what we want. Maybe it&amp;#8217;s useful in some scenarios, but when you need a live metric to let you know what your server is ACTUALLY doing, this isn&amp;#8217;t the one.&lt;/p&gt;
&lt;p&gt;If you want an accurate request rate, &lt;b&gt;your best bet is going to be to collect Total Accesses and do deltas off of the previous collection&lt;/b&gt;. I&amp;#8217;m glad that&amp;#8217;s how we did it before!&lt;/p&gt;
&lt;p&gt;To a point, this goes into the expense of metrics. For Apache, Total Accesses is just a simple counter. It returns an accurate value live, on-the-fly, and makes it very easy for the sys admin to collect and process. Very little work is done on it&amp;#8217;s end. Even the current implementation of ReqPerSec has very little cost: it just does some simple division on-demand, using counters it already tracks anyway.&lt;/p&gt;
&lt;p&gt;To keep an actual average request rate, there would be some more resource involved. It would need to set a timer (ie: every 60 seconds), have a callback for the timer (to actually handle the calculation), and store counters in memory to calculate deltas. However, in reality, this will really have a very minimal impact on server performance and system load (a few extra CPU hits every minute, storing two little 64-bit counters, etc).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;So what did I end up doing? I hacked up my own mod_status using shared memory!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Using the existing mod_status code, I pulled some code from a shared memory module example and smashed them together to calculate an accurate ReqPerSec metric on the fly, returned when you request server-status.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;How does it work?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When you request server-status, it will go into shared memory, pull out the total accesses and uptime from the previous server-status request, do deltas on the current total accesses and uptime, then return the rate. It will then put the current total accesses and uptime back into shared memory for the next poll (&lt;b&gt;base&lt;/b&gt; is our shared memory baseline).&lt;/p&gt;
&lt;pre&gt;
ap_rprintf(r, "ReqPerSec: %g\n", (
    ( (float)count - (float)base-&gt;prev_req_count ) /
    ( (float)up_time - (float)base-&gt;prev_uptime ) )
);
&lt;/pre&gt;
&lt;p&gt;There is of course all of the shared memory code, but the end result is the calculation above. We poll every 60 seconds, so we incur a small cost every minute, but, like I mentioned before, it&amp;#8217;s not noticeable, and it gives us the view we need into the environment.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Some of you may also wonder what happens to the first request, since there isn&amp;#8217;t any data in our shared memory space yet. For now, it will be inaccurate, but only for the first request in the lifetime of the parent, which I can deal with until I make it better&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Well, that&amp;#8217;s all for this one. It was an interesting discovery in the world of Apache metrics collection, and an interesting adventure to hack together the shared memory module. I&amp;#8217;m sure there are other scenarios out there like this one; if you come across one, feel free to drop a comment!&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m off to the Apple Store now- it&amp;#8217;s iPad launch day &lt;img src='http://wildpointer.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /&gt; &lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/C6JA2lZ7hWc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2010/04/03/apache-mod_status-the-misleading-reqpersec-metric/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2010/04/03/apache-mod_status-the-misleading-reqpersec-metric/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://wildpointer.org/2010/04/03/apache-mod_status-the-misleading-reqpersec-metric/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[use perl: pack() to send floats between intel/sparc with proper endian-ness.]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/wTUqPPoplNA/" />
		<id>http://chetnichols.org/?p=78</id>
		<updated>2010-02-22T08:17:51Z</updated>
		<published>2010-02-22T08:13:39Z</published>
		<category scheme="http://wildpointer.org" term="perl" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[So I like using Perl, if anyone hasn&#8217;t realized yet. Python seems awesome and all, but I haven&#8217;t had the time to start writing things in Python. I&#8217;m still at the stage when, if a tool needs to be put together, it needs to be done ASAP; I can&#8217;t delay trying to figure out Python [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2010/02/22/use-perl-pack-to-send-floats-between-intelsparc-with-proper-endian-ness/">&lt;p&gt;So I like using Perl, if anyone hasn&amp;#8217;t realized yet. Python seems awesome and all, but I haven&amp;#8217;t had the time to start writing things in Python. I&amp;#8217;m still at the stage when, if a tool needs to be put together, it needs to be done ASAP; I can&amp;#8217;t delay trying to figure out Python particulars. &lt;/p&gt;
&lt;p&gt;In any case, one of our metrics publishing systems is wrapped by a few different object classes I put together in Perl (follows a certain protocol created by another group, etc). Of the many data types supported by our metrics receivers, we can do things like 32-bit unsigned integers, single precision (32-bit) floating points, and a few others.&lt;/p&gt;
&lt;p&gt;Now, when I would publish the 32-bit uint&amp;#8217;s, it would work great- no issues. The receivers would expect a byte stream, so I would use pack() to send my values as binary. For example:&lt;/p&gt;
&lt;pre code="Perl"&gt;
$val=29;
print $sock pack('N',$val);
&lt;/pre&gt;
&lt;p&gt;Easy, whatever. However, when I would send values as a single precision float, it would totally be hosed on the other end. For example:&lt;/p&gt;
&lt;pre code="Perl"&gt;
$val="30.0";
print $sock pack('f',$val);
&lt;/pre&gt;
&lt;p&gt;On the other end, they would get some massive negative number. I don&amp;#8217;t deal with this too much, things usually just work. Thankfully, my mind was jogged in regards to standards- there are lots of standards around byte order for integers (16 bit, 32 bit, 64 bit), but not as much for float; one architecture may use big-endian, and another architecture might use little-endian.&lt;/p&gt;
&lt;p&gt;In my searches, I found that Intel stores floating points in little-endian byte order, and Sparc stores them in big-endian byte order. Sure enough, I was trying to publish from an Intel-based BSD host to a Sparc based Solaris host. Aha!&lt;/p&gt;
&lt;p&gt;Luckily, pack() can *also* handle this for us! With a simple carat added to the templates section of pack(), I can easily pack the value in big-endian byte order and resolve our issue. I do that like so:&lt;/p&gt;
&lt;pre code="Perl"&gt;
$val="30.0";
print $sock pack('f&gt;',$val);
&lt;/pre&gt;
&lt;p&gt;And, ta da! Worked like a charm. Was it difficult to get it working? No. But, it was fun to have to deal with something like this. On any given day, you don&amp;#8217;t really worry about endian-ness; things just work. This was one of those days where I actually had to use the old noggin, and that was refreshing.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/wTUqPPoplNA" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2010/02/22/use-perl-pack-to-send-floats-between-intelsparc-with-proper-endian-ness/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2010/02/22/use-perl-pack-to-send-floats-between-intelsparc-with-proper-endian-ness/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	<feedburner:origLink>http://wildpointer.org/2010/02/22/use-perl-pack-to-send-floats-between-intelsparc-with-proper-endian-ness/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[calculating dequeue time to tune load balancer queue handling]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/rIDet9VL5cs/" />
		<id>http://chetnichols.org/?p=73</id>
		<updated>2010-05-03T04:51:23Z</updated>
		<published>2009-12-26T11:14:03Z</published>
		<category scheme="http://wildpointer.org" term="scalability" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[Maybe there&#8217;s already some obvious answer to this that I just ignored sometime in years past, but at some point, you may use a load balancer that will allow you to queue requests up in the event the backend apps are running slower than normal. Instead of killing the apps, the load balancer sets requests [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2009/12/26/calculating-dequeue-time-to-tune-load-balancer-queue-handling/">&lt;p&gt;Maybe there&amp;#8217;s already some obvious answer to this that I just ignored sometime in years past, but at some point, you may use a load balancer that will allow you to queue requests up in the event the backend apps are running slower than normal. Instead of killing the apps, the load balancer sets requests aside until the app is ready for more, then it sends it off.&lt;/p&gt;
&lt;p&gt;However, what happens if the app is &lt;strong&gt;REALLY&lt;/strong&gt; in trouble? Your connection queue could very easily grow into thousands of piled up requests all waiting to be serviced. At some point, you&amp;#8217;re going to have to start dropping requests from the queue: it will get so large, that even after the app comes back, you may never recover from the pile of requests (or if you do, it might be 60 seconds worth, at which point your user will probably have given up anyway).&lt;/p&gt;
&lt;p&gt;So, here we go.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;: how many requests per second (max_requests) can your application slice handle? In this case, your application slice will be however many services are being load balanced. Depending on the max_requests, that will allow us to know how much headroom will be available for a given slice utilization; we will use that headroom to determine how many requests over and above the current utilization are available to help dequeue.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Second&lt;/strong&gt;: What is our average utilization? If on a given day we are 60% utilized, then we should in theory have 40% capacity available to help dequeue in the event of a surge/backup/whatever. That is, once we begin to dequeue, we will actually be running at a full 100% until we&amp;#8217;re back from being under, then we&amp;#8217;ll be back at the usual 40%.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Third&lt;/strong&gt;: How long were we backing up for, ie: what is the worst-case scenario we want to prepare for? If underlying apps rely on a database, and the database locks up for 10 seconds, then that will be 10 seconds of queueing we will get to enjoy. If we can&amp;#8217;t afford 10 seconds, then what is the most we&amp;#8217;re willing to deal with?&lt;/p&gt;
&lt;p&gt;Equation time! Here are the three variables we have to deal with:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;max_requests&lt;/strong&gt; = number of requests/sec that our load balanced slice can handle (ie: 400 .. as in 400 req/s)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;utilization&lt;/strong&gt; = percentage of our average utilization that we want to plan around (ie: 0.6 .. as in 60% avg utilization)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;queue_time&lt;/strong&gt; = number of seconds we were queueing for (ie: 10 .. in which the db locked up)&lt;/p&gt;
&lt;p&gt;And here are some things we can derive:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;current_requests&lt;/strong&gt; = ( max_requests * utilization) &lt;em&gt;&lt;--- ie: req/s utilized&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;available_requests&lt;/strong&gt; = ( max_requests * ( 1 &amp;#8211; utilization ) ) &lt;em&gt;&lt;--- req/s available ... this is also what you should consider headroom&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;queue_size&lt;/strong&gt; = ( current_requests * queue_time )&lt;/p&gt;
&lt;p&gt;At this point, it&amp;#8217;s simple:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;time_to_dequeue&lt;/strong&gt; = ( queue_size / available_requests )&lt;/p&gt;
&lt;p&gt;Basically, all we&amp;#8217;re saying is, take the number of current requests/sec we&amp;#8217;re handling, and multiply it by the number of seconds we were queueing. This will give us the number of requests that are backed up.&lt;/p&gt;
&lt;p&gt;Once our queuing has stopped, and we can begin to dequeue, we will still be handling the usual rate of requests (ie: 60% of our max_requests), but we have that 40% of headroom (ie: available_requests) to handle the queue, so we divide our total queue_size up by the available_requests rate, and that will give us the number of seconds our load balancer will take to dequeue.&lt;/p&gt;
&lt;p&gt;Expanded, the equation is this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;time_to_dequeue&lt;/strong&gt; = ( ( ( max_requests * utilization ) * queue_time ) / ( max_requests * ( 1- utilization ) ) )&lt;/p&gt;
&lt;p&gt;But wait! The beauty of this is, the time_to_dequeue is going to be the same for any given max_requests (you can see that from the equation). Regardless of our request rate, the rate at which we dequeue will be same relative to the percentage of utilization and a given queue_time.&lt;/p&gt;
&lt;p&gt;So, we can simplify, removing anything having to do with request rates, allowing us to place time calculations for anything where we know the utilization and time we were queueing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;time_to_dequeue&lt;/strong&gt; = ( ( utilization * queue_time ) / ( 1 &amp;#8211; utilization ) )&lt;/p&gt;
&lt;p&gt;Now, a lot of the times, we need to know how LARGE the queue will be at the given peak (to configure the load balancer accordingly), and in that case, we will need to know request rates.&lt;/p&gt;
&lt;p&gt;Either way, I found this to be an interesting little exercise- got my mind thinking about math, and having an equation was much easier to help me build a table of data and pump it into gnuplot.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/rIDet9VL5cs" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2009/12/26/calculating-dequeue-time-to-tune-load-balancer-queue-handling/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2009/12/26/calculating-dequeue-time-to-tune-load-balancer-queue-handling/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://wildpointer.org/2009/12/26/calculating-dequeue-time-to-tune-load-balancer-queue-handling/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[adventures in perl: foreach returns pointers to elements]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/n24TGKklnHc/" />
		<id>http://chetnichols.org/?p=55</id>
		<updated>2009-12-17T18:54:08Z</updated>
		<published>2009-12-17T08:58:50Z</published>
		<category scheme="http://wildpointer.org" term="perl" /><category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[I&#8217;m not sure how I&#8217;ve never run into this issue before. In some work I was doing recently, I ran into what I thought was a nasty bug [in my code] but couldn&#8217;t explain it. Without thinking, I started trying to undo this, fix that, hack this, and ignore that. After the meeting I was [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2009/12/17/adventures-in-perl-foreach-returns-pointers-to-elements/">&lt;p&gt;I&amp;#8217;m not sure how I&amp;#8217;ve never run into this issue before. In some work I was doing recently, I ran into what I thought was a nasty bug [in my code] but couldn&amp;#8217;t explain it. Without thinking, I started trying to undo this, fix that, hack this, and ignore that. &lt;/p&gt;
&lt;p&gt;After the meeting I was in finished, I was able to sit down and actually put some thought into what was happening. The one thing that stood out was interesting, but until then, I had no clue it was how Perl interpreted [in that scenario]. So, I wrote a short test script, sure enough proving the theory, and was able to fix my error.&lt;/p&gt;
&lt;p&gt;Take a look at this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;cat&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;dog&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;emu&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;frog&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;do not eat the %s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;which dumps out this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;do not eat the cat&lt;br /&gt;
do not eat the dog&lt;br /&gt;
do not eat the emu&lt;br /&gt;
do not eat the frog&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;In my head&lt;/b&gt;, the code above would work like this: for each element in the array @animals, copy the data from that element into a new scalar $animal, then print it out. Simple enough. Now, consider this sample:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;cat&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;dog&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;emu&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;lemur&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;do not eat the %s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066;"&gt;sprintf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;rabid %s&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;do not eat the %s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$animal&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I had *EXPECTED* it to output this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;do not eat the cat&lt;br /&gt;
do not eat the dog&lt;br /&gt;
do not eat the emu&lt;br /&gt;
do not eat the frog&lt;/p&gt;
&lt;p&gt;do not eat the cat&lt;br /&gt;
do not eat the dog&lt;br /&gt;
do not eat the emu&lt;br /&gt;
do not eat the frog&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For the first loop, again, &lt;b&gt;my thinking&lt;/b&gt; was that we copy each array element&amp;#8217;s data into the new scalar $animal, print it, modify it (by adding &amp;#8216;rabid&amp;#8217; to it), but do nothing with the modification (we are just modifying $animal, which should be assigned by copy, of which would be lost when we iterate to the next element). Then, in our next loop, we iterate over @animals again, initializing $animal yet again for each element, so we just hit the un-modified @animals array and see the same thing.&lt;/p&gt;
&lt;p&gt;[un]Surprisingly, &lt;b&gt;I was totally wrong&lt;/b&gt;. This was the output I got:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;do not eat the cat&lt;br /&gt;
do not eat the dog&lt;br /&gt;
do not eat the emu&lt;br /&gt;
do not eat the frog&lt;/p&gt;
&lt;p&gt;do not eat the rabid cat&lt;br /&gt;
do not eat the rabid dog&lt;br /&gt;
do not eat the rabid emu&lt;br /&gt;
do not eat the rabid frog&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Wow! What happened? Turns out, like the title suggests, when you use foreach in Perl, &lt;b&gt;it actually assigns $animal to be a pointer&lt;/b&gt; (reference, whatever) to that array element, and not a copy. When you make any changes, the change applies directly to the element the array. As another example, it&amp;#8217;s for-loop equivalent would be this:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;cat&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;dog&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;emu&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;lemur&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;for&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt;&lt;span style="color: #339933;"&gt;=&lt;/span&gt;&lt;span style="color: #cc66cc;"&gt;0&lt;/span&gt; &lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;@animals&lt;/span&gt; &lt;span style="color: #339933;"&gt;;&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt;&lt;span style="color: #339933;"&gt;++&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
    &lt;span style="color: #000066;"&gt;printf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;do not eat the %s&lt;span style="color: #000099; font-weight: bold;"&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
    &lt;span style="color: #0000ff;"&gt;$animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000066;"&gt;sprintf&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt; &lt;span style="color: #ff0000;"&gt;&amp;quot;rabid %s&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$animals&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#91;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$index&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#93;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Fun! Doing some research after the fact, it turns out there has been some mild discussion on the topic. Some consider it a bug, but &lt;b&gt;in reality, it works by design&lt;/b&gt;. What does this mean for you? Well, if you happen to be iterating over an array using foreach, and want to modify each element, and plan on looping over the array multiple times, make sure you understand what&amp;#8217;s going on behind the scenes, or else you&amp;#8217;ll run into the same issue I did. You can create a temporary variable (which will assign by copy), ie:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;my $new_animal = $animal;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;or you can iterate using a for-loop and just do it like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;my $animal = $animals[$index];&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;There of course may be some cases where you want to take advantage of the referencing feature, and if you do, all the more power to you.&lt;/p&gt;
&lt;p&gt;Well, that&amp;#8217;s all I have for now. Hopefully this helps someone out some day. Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/n24TGKklnHc" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2009/12/17/adventures-in-perl-foreach-returns-pointers-to-elements/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2009/12/17/adventures-in-perl-foreach-returns-pointers-to-elements/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	<feedburner:origLink>http://wildpointer.org/2009/12/17/adventures-in-perl-foreach-returns-pointers-to-elements/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[nxdomain redirection with powerdns and lua]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/D3rkhyNWvKk/" />
		<id>http://chetnichols.org/?p=20</id>
		<updated>2009-11-25T11:33:35Z</updated>
		<published>2009-11-25T11:31:16Z</published>
		<category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[For those of you unfamiliar, NXDOMAIN is a DNS query response for non-existent domain. An example would be if you start typing google.com, but sneeze halfway through, and end up going to gegooele.com. That domain doesn&#8217;t exist, and you will ultimately receive an NXDOMAIN response from your upstream DNS server instead of an A record [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2009/11/25/nxdomain-redirection-with-powerdns-and-lua/">&lt;p&gt;For those of you unfamiliar, NXDOMAIN is a DNS query response for non-existent domain. An example would be if you start typing google.com, but sneeze halfway through, and end up going to gegooele.com. That domain doesn&amp;#8217;t exist, and you will ultimately receive an NXDOMAIN response from your upstream DNS server instead of an A record with the IP of the domain.&lt;/p&gt;
&lt;p&gt;These days, a lot of ISPs have been doing NXDOMAIN redirection. Instead of handing back the NXDOMAIN response, they will intercept it and send you back an A record with an IP of one of their web servers (lets say 1.2.3.4 as an example). Your machine will ultimately think that gegooele.com has the IP 1.2.3.4, connect to that IP, and do a GET request with the HTTP host header of gegooele.com. The ISP&amp;#8217;s web server, which specifically handles NXDOMAIN &amp;#8220;redirected&amp;#8221; HTTP requests, will then take that host header, pass it through some type of dynamic script, and display a nice custom error page with possible corrections, advertisements, etc.&lt;/p&gt;
&lt;p&gt;Now, here&amp;#8217;s where PowerDNS comes in: there are companies out there whose specialty is to sell DNS appliances and software solutions, solely for the purpose of doing NXDOMAIN redirection. However, if you are in the market for doing something like this (which is a whole separate discussion altogether, since there are strong opinions about this subject), you can save yourself a chunk of change by instead using PowerDNS (pdns-recursor, to be exact) with built-in Lua scripting. PowerDNS is open source, free, awesome.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re going to skip the build/compile details for now, and assume you have the latest PowerDNS recursor installed, and that Lua scripting has been compiled in. Chances are, it has. If not, check out &lt;a href="http://www.powerdns.com"&gt;http://www.powerdns.com&lt;/a&gt; and download the latest source. Once it&amp;#8217;s installed, you just need to write a Lua script to modify DNS results, configure your recursor to use the script, and start up pdns-recursor. Let&amp;#8217;s get to it.&lt;/p&gt;
&lt;p&gt;First, you need to define a Lua script to handle DNS responses. Currently, Lua will only handle two types of responses: nxdomain, and preresolve. Preresolve is a response to give before any resolution has taken place. This is to basically hijack requests with a static response.&lt;/p&gt;
&lt;p&gt;To define, we&amp;#8217;ll add this line to our &lt;em&gt;recursor.conf&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lua-dns-script=/opt/pdns/bin/nxdomain.lua&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now, let&amp;#8217;s write our script. At it&amp;#8217;s most basic level, it&amp;#8217;s really easy:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;function nxdomain (ip,domain,query_type)&lt;br /&gt;
  ips={}&lt;br /&gt;
  if query_type ~= pdns.A then return -1, ret end&lt;br /&gt;
    ips[1]={ query_type=pdns.A, content="1.2.3.4" }&lt;br /&gt;
    ips[2]={ query_type=pdns.A, content="5.6.7.8" }&lt;br /&gt;
    return 0, ips&lt;br /&gt;
end&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This script will first make sure our NXDOMAIN response is the result of a request for an A record. As long as it is, we will build an A record response to return instead of an NXDOMAIN. Per this code, the client will ultimately receive an A rotor response with two records.&lt;/p&gt;
&lt;p&gt;Now that our script has been written and added to our recursor.conf, let&amp;#8217;s start up the recursor and try it out!&lt;/p&gt;
&lt;p&gt;&lt;i&gt;$ /opt/pdns/sbin/pdns_recursor &amp;#8211;config-dir=/opt/pdns/etc&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Assuming the script is loaded successfully, you will see the following from the startup output:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nov 25 03:09:36 Loaded &amp;#8216;lua&amp;#8217; script from &amp;#8216;/opt/pdns/bin/nxdomain.lua&amp;#8217;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Looks good. Now, let&amp;#8217;s see what happens when we try to hit our non-existent gegooele.com:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ host gegooele.com&lt;br /&gt;
gegooele.com has address 1.2.3.4&lt;br /&gt;
gegooele.com has address 5.6.7.8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And there we go! NXDOMAIN redirection without the need for a commercial solution. Of course, there are more things you can do [with the Lua script]. WIth the proper log level, you can have it log every time the handler is called. For example, you can add a simple print line:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;print ("nxdomain handler received: ", ip, domain, query_type)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can also have it make decisions based on incoming IP, hostname/domain, and query type. However, the point of this was just to show the basics with what you can do. For more Lua syntax, and PowerDNS capabilities with Lua, check out the Lua website and PowerDNS wiki. Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/D3rkhyNWvKk" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2009/11/25/nxdomain-redirection-with-powerdns-and-lua/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2009/11/25/nxdomain-redirection-with-powerdns-and-lua/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	<feedburner:origLink>http://wildpointer.org/2009/11/25/nxdomain-redirection-with-powerdns-and-lua/</feedburner:origLink></entry>
		<entry>
		<author>
			<name>chet</name>
						<uri>http://chetnichols.org</uri>
					</author>
		<title type="html"><![CDATA[efficient reads on perl file handles: while vs. foreach]]></title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/chet/~3/3kLJNJ_bP6w/" />
		<id>http://chetnichols.org/?p=30</id>
		<updated>2009-11-17T05:32:13Z</updated>
		<published>2009-11-15T11:58:47Z</published>
		<category scheme="http://wildpointer.org" term="tech" />		<summary type="html"><![CDATA[A while back, I had put a Perl script together to read in some large files, do some data mining, and dump out the results I wanted to see (well, maybe they weren&#8217;t the results I was hoping for, but results nonetheless). Now, when the script ran, it would go through it&#8217;s first few routines [...]]]></summary>
		<content type="html" xml:base="http://wildpointer.org/2009/11/15/efficient-reads-on-perl-file-handles-while-vs-foreach/">&lt;p&gt;A while back, I had put a Perl script together to read in some large files, do some data mining, and dump out the results I wanted to see (well, maybe they weren&amp;#8217;t the results I was hoping for, but results nonetheless). Now, when the script ran, it would go through it&amp;#8217;s first few routines nice and quick-like, but when it went to the following routine, it would become unbearably slow. The first couple of times, I didn&amp;#8217;t think much of it; I liked feeling that the script was hard at work (of course).&lt;/p&gt;
&lt;p&gt;However, after a few more runs, it was getting kind of ridiculous: the routine in question was the one that did reads from the file handle. Now, I can understand on a multi-gigabyte file it might take a while (read in each line, parse it through a regex, and populate a data structure). However, it was causing the entire system to hang, and that made no sense at all given it&amp;#8217;s relatively easy instructions. Here&amp;#8217;s an example of what I was doing:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$fd&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; IO&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;File&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;new&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;data.out&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;O_RDONLY&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;foreach&lt;/span&gt; &lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$line&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$fd&lt;/span&gt;&lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;@data&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$line&lt;/span&gt; &lt;span style="color: #339933;"&gt;=~&lt;/span&gt; &lt;span style="color: #009966; font-style: italic;"&gt;/regex_pattern/&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Simple enough. So, on the next run, I started tracking the PID. Now, I saw two things: 1) the CPU was pinned, and 2) memory utilization was going through the roof. Bingo. Basically, my multi-gigabyte file was being read into memory, eating up all the remaining free physical memory, which was forcing the box to start swapping (which was eating up the CPU). Now it made sense why things were going ridiculously slow.&lt;/p&gt;
&lt;p&gt;Now, what didn&amp;#8217;t make sense was the fact this was happening at all. For each line of data, I was only pulling about 10% of it into my data structure (bytes parsed vs bytes per line), so I shouldn&amp;#8217;t see memory utilization match that of the file. Additionally, I had worked with large files like this before, on systems with less memory, and never had an issue. What was different?&lt;/p&gt;
&lt;p&gt;I took lunch, thought about it, and somewhere in there thought to myself, &amp;#8220;hrmm, I wonder if it has to do with the foreach loop.&amp;#8221; In the past, I had always used a while-loop, but didn&amp;#8217;t really consider there might be an extreme difference between how each was interpreted when reading a file handle. I went back to my desk and modified the code to use a while loop instead:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;table&gt;&lt;tr&gt;&lt;td class="line_numbers"&gt;&lt;pre&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;pre class="perl" style="font-family:monospace;"&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$fd&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; IO&lt;span style="color: #339933;"&gt;::&lt;/span&gt;&lt;span style="color: #006600;"&gt;File&lt;/span&gt;&lt;span style="color: #339933;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #006600;"&gt;new&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&amp;quot;data.out&amp;quot;&lt;/span&gt;&lt;span style="color: #339933;"&gt;,&lt;/span&gt;O_RDONLY&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span style="color: #b1b100;"&gt;while&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #b1b100;"&gt;my&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$line&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;$fd&lt;/span&gt;&lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   &lt;span style="color: #0000ff;"&gt;@data&lt;/span&gt; &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;$line&lt;/span&gt; &lt;span style="color: #339933;"&gt;=~&lt;/span&gt; &lt;span style="color: #009966; font-style: italic;"&gt;/regex_pattern/&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sure enough, it tore right through the file, did it&amp;#8217;s parsing, and was done very shortly after. Interesting! So, what happened?&lt;/p&gt;
&lt;p&gt;Basically, it&amp;#8217;s a major difference in how Perl handles while loops vs. foreach loops.&lt;/p&gt;
&lt;p&gt;In a while-loop, Perl will blindly shift lines one-by-one off of the array/fd you pass until it reaches an EOF. Once it does, it breaks out and you&amp;#8217;re done. This is how it should work (and does exactly what we expect it to do), so that makes sense.&lt;/p&gt;
&lt;p&gt;Now, in a foreach-loop, the Perl interpreter needs to know the end of the array before it begins iterating over it (whereas with a while loop we just go until EOF). If the data is already an array, that&amp;#8217;s not a problem. However, if the data is a file handle, then the only way it can know the end is by reading the entire file into memory and ultimately create an array of the data to return back to the foreach iterator.&lt;/p&gt;
&lt;p&gt;Most of the time, people aren&amp;#8217;t running through multi-gigabyte files, so doing a foreach or a while on a file handle won&amp;#8217;t really be noticeable, even though there are two completely different logic paths being followed behind the scenes.&lt;/p&gt;
&lt;p&gt;Ultimately, &lt;strong&gt;use a while loop when reading off of a file handle&lt;/strong&gt;. It&amp;#8217;s cleaner, uses less overhead, and has obviously proven itself to be more fit for this task.&lt;/p&gt;
&lt;p&gt;There are a lot of Perl hackers out there (many of whom I have worked with) who may end up commenting or shed some deeper technical insight. By all means, I would love to hear it! If you think I&amp;#8217;ve done a good job summarizing and detailing the issue, that works just as well! Enjoy!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/chet/~4/3kLJNJ_bP6w" height="1" width="1"/&gt;</content>
		<link rel="replies" type="text/html" href="http://wildpointer.org/2009/11/15/efficient-reads-on-perl-file-handles-while-vs-foreach/#comments" thr:count="4" />
		<link rel="replies" type="application/atom+xml" href="http://wildpointer.org/2009/11/15/efficient-reads-on-perl-file-handles-while-vs-foreach/feed/atom/" thr:count="4" />
		<thr:total>4</thr:total>
	<feedburner:origLink>http://wildpointer.org/2009/11/15/efficient-reads-on-perl-file-handles-while-vs-foreach/</feedburner:origLink></entry>
	</feed>

