<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jason Mooberry</title>
	<atom:link href="http://blog.jasonmooberry.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jasonmooberry.com</link>
	<description>Stuff I did for you.</description>
	<lastBuildDate>Mon, 15 Oct 2012 19:21:06 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>A sample Go RPC server/client over TCP</title>
		<link>http://blog.jasonmooberry.com/2012/10/a-sample-go-rpc-serverclient-over-tcp/</link>
		<comments>http://blog.jasonmooberry.com/2012/10/a-sample-go-rpc-serverclient-over-tcp/#comments</comments>
		<pubDate>Mon, 15 Oct 2012 19:21:06 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[go]]></category>
		<category><![CDATA[rpc]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[tcp]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=352</guid>
		<description><![CDATA[So I was looking into building a quick, fast rpc server in Go for one of our office projects.  It may end up becoming opensourced, but for now I can only share the sample server/client that I set up to test the possible performance.  Go&#8217;s RPC docs give an example of how to run an [...]]]></description>
			<content:encoded><![CDATA[<p>So I was looking into building a quick, fast rpc server in Go for one of our office projects.  It may end up becoming opensourced, but for now I can only share the sample server/client that I set up to test the possible performance.  <a href="http://golang.org/pkg/net/rpc/" target="_blank">Go&#8217;s RPC docs</a> give an example of how to run an HTTP RPC server, but nothing about how to run one from a simple TCP port.  When performance is priority, cutting the overhead of HTTP request/response headers and the two-request style (<code>CONNECT</code>, <code>GET</code>) of RPC calls can make a huge difference.</p>
<p>Running a client/server ping test between two vps servers with 4 procs and 4GB of memory I saw <strong>~30k reqs/sec</strong>.  Interestingly it performed the best when I did not enable more cores with <code>runtime.GOMAXPROCS(runtime.NumCPU())</code>.  Enabling more cores on either the client, the server, or both reduced the reqs/sec by several thousand.  I suspect it&#8217;s due to the test RPC method basically doing very little work.  Given a heavier task per RPC method, ramping up <code>GOMAXPROCS</code> probably has a positive impact on performance. </p>
<p>Here&#8217;s how I got it working:</p>
<div id="gist3894210" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-server-go-L1" rel="file-server-go-L1">1</span>
          <span class="line-number" id="file-server-go-L2" rel="file-server-go-L2">2</span>
          <span class="line-number" id="file-server-go-L3" rel="file-server-go-L3">3</span>
          <span class="line-number" id="file-server-go-L4" rel="file-server-go-L4">4</span>
          <span class="line-number" id="file-server-go-L5" rel="file-server-go-L5">5</span>
          <span class="line-number" id="file-server-go-L6" rel="file-server-go-L6">6</span>
          <span class="line-number" id="file-server-go-L7" rel="file-server-go-L7">7</span>
          <span class="line-number" id="file-server-go-L8" rel="file-server-go-L8">8</span>
          <span class="line-number" id="file-server-go-L9" rel="file-server-go-L9">9</span>
          <span class="line-number" id="file-server-go-L10" rel="file-server-go-L10">10</span>
          <span class="line-number" id="file-server-go-L11" rel="file-server-go-L11">11</span>
          <span class="line-number" id="file-server-go-L12" rel="file-server-go-L12">12</span>
          <span class="line-number" id="file-server-go-L13" rel="file-server-go-L13">13</span>
          <span class="line-number" id="file-server-go-L14" rel="file-server-go-L14">14</span>
          <span class="line-number" id="file-server-go-L15" rel="file-server-go-L15">15</span>
          <span class="line-number" id="file-server-go-L16" rel="file-server-go-L16">16</span>
          <span class="line-number" id="file-server-go-L17" rel="file-server-go-L17">17</span>
          <span class="line-number" id="file-server-go-L18" rel="file-server-go-L18">18</span>
          <span class="line-number" id="file-server-go-L19" rel="file-server-go-L19">19</span>
          <span class="line-number" id="file-server-go-L20" rel="file-server-go-L20">20</span>
          <span class="line-number" id="file-server-go-L21" rel="file-server-go-L21">21</span>
          <span class="line-number" id="file-server-go-L22" rel="file-server-go-L22">22</span>
          <span class="line-number" id="file-server-go-L23" rel="file-server-go-L23">23</span>
          <span class="line-number" id="file-server-go-L24" rel="file-server-go-L24">24</span>
          <span class="line-number" id="file-server-go-L25" rel="file-server-go-L25">25</span>
          <span class="line-number" id="file-server-go-L26" rel="file-server-go-L26">26</span>
          <span class="line-number" id="file-server-go-L27" rel="file-server-go-L27">27</span>
          <span class="line-number" id="file-server-go-L28" rel="file-server-go-L28">28</span>
          <span class="line-number" id="file-server-go-L29" rel="file-server-go-L29">29</span>
          <span class="line-number" id="file-server-go-L30" rel="file-server-go-L30">30</span>
          <span class="line-number" id="file-server-go-L31" rel="file-server-go-L31">31</span>
          <span class="line-number" id="file-server-go-L32" rel="file-server-go-L32">32</span>
          <span class="line-number" id="file-server-go-L33" rel="file-server-go-L33">33</span>
          <span class="line-number" id="file-server-go-L34" rel="file-server-go-L34">34</span>
          <span class="line-number" id="file-server-go-L35" rel="file-server-go-L35">35</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-server-go-LC1"><span class="kn">package</span> <span class="nx">main</span></div><div class="line" id="file-server-go-LC2">&nbsp;</div><div class="line" id="file-server-go-LC3"><span class="kn">import</span> <span class="p">(</span></div><div class="line" id="file-server-go-LC4">	<span class="s">&quot;log&quot;</span></div><div class="line" id="file-server-go-LC5">	<span class="s">&quot;net&quot;</span></div><div class="line" id="file-server-go-LC6">	<span class="s">&quot;net/rpc&quot;</span></div><div class="line" id="file-server-go-LC7"><span class="p">)</span></div><div class="line" id="file-server-go-LC8">&nbsp;</div><div class="line" id="file-server-go-LC9"><span class="kd">type</span> <span class="nx">System</span> <span class="kt">int</span></div><div class="line" id="file-server-go-LC10">&nbsp;</div><div class="line" id="file-server-go-LC11"><span class="kd">func</span> <span class="p">(</span><span class="nx">System</span><span class="p">)</span> <span class="nx">Ping</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="nx">reply</span> <span class="o">*</span><span class="kt">string</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span></div><div class="line" id="file-server-go-LC12">&nbsp;</div><div class="line" id="file-server-go-LC13">	<span class="k">if</span> <span class="o">*</span><span class="nx">message</span> <span class="o">==</span> <span class="s">&quot;ping&quot;</span> <span class="p">{</span></div><div class="line" id="file-server-go-LC14">		<span class="o">*</span><span class="nx">reply</span> <span class="p">=</span> <span class="s">&quot;pong&quot;</span></div><div class="line" id="file-server-go-LC15">	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></div><div class="line" id="file-server-go-LC16">		<span class="o">*</span><span class="nx">reply</span> <span class="p">=</span> <span class="s">&quot;wut?&quot;</span></div><div class="line" id="file-server-go-LC17">	<span class="p">}</span></div><div class="line" id="file-server-go-LC18">&nbsp;</div><div class="line" id="file-server-go-LC19">	<span class="k">return</span> <span class="kc">nil</span></div><div class="line" id="file-server-go-LC20"><span class="p">}</span></div><div class="line" id="file-server-go-LC21">&nbsp;</div><div class="line" id="file-server-go-LC22"><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span></div><div class="line" id="file-server-go-LC23">&nbsp;</div><div class="line" id="file-server-go-LC24">	<span class="nx">sys</span> <span class="o">:=</span> <span class="nb">new</span><span class="p">(</span><span class="nx">System</span><span class="p">)</span></div><div class="line" id="file-server-go-LC25">	<span class="nx">server</span> <span class="o">:=</span> <span class="nx">rpc</span><span class="p">.</span><span class="nx">NewServer</span><span class="p">()</span></div><div class="line" id="file-server-go-LC26">	<span class="nx">server</span><span class="p">.</span><span class="nx">Register</span><span class="p">(</span><span class="nx">sys</span><span class="p">)</span></div><div class="line" id="file-server-go-LC27">&nbsp;</div><div class="line" id="file-server-go-LC28">	<span class="nx">l</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">Listen</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;:8080&quot;</span><span class="p">)</span></div><div class="line" id="file-server-go-LC29">	<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span></div><div class="line" id="file-server-go-LC30">		<span class="nx">log</span><span class="p">.</span><span class="nx">Fatal</span><span class="p">(</span><span class="s">&quot;listen error:&quot;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span></div><div class="line" id="file-server-go-LC31">	<span class="p">}</span></div><div class="line" id="file-server-go-LC32">&nbsp;</div><div class="line" id="file-server-go-LC33">	<span class="nx">server</span><span class="p">.</span><span class="nx">Accept</span><span class="p">(</span><span class="nx">l</span><span class="p">)</span></div><div class="line" id="file-server-go-LC34">&nbsp;</div><div class="line" id="file-server-go-LC35"><span class="p">}</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/jasonmoo/3894210/raw/69c851b2c1a15324ae7d6f3661f9ffa64b9a3da3/server.go" style="float:right">view raw</a>
          <a href="https://gist.github.com/jasonmoo/3894210#file-server-go" style="float:right; margin-right:10px; color:#666;">server.go</a>
          <a href="https://gist.github.com/jasonmoo/3894210">This Gist</a> brought to you by <a href="https://github.com">GitHub</a>.
        </div>
      </div>
</div>

<div id="gist3894201" class="gist">
      <div class="gist-file">
        <div class="gist-data gist-syntax">



  <div class="file-data">
    <table cellpadding="0" cellspacing="0" class="lines highlight">
      <tr>
        <td class="line-numbers">
          <span class="line-number" id="file-client-go-L1" rel="file-client-go-L1">1</span>
          <span class="line-number" id="file-client-go-L2" rel="file-client-go-L2">2</span>
          <span class="line-number" id="file-client-go-L3" rel="file-client-go-L3">3</span>
          <span class="line-number" id="file-client-go-L4" rel="file-client-go-L4">4</span>
          <span class="line-number" id="file-client-go-L5" rel="file-client-go-L5">5</span>
          <span class="line-number" id="file-client-go-L6" rel="file-client-go-L6">6</span>
          <span class="line-number" id="file-client-go-L7" rel="file-client-go-L7">7</span>
          <span class="line-number" id="file-client-go-L8" rel="file-client-go-L8">8</span>
          <span class="line-number" id="file-client-go-L9" rel="file-client-go-L9">9</span>
          <span class="line-number" id="file-client-go-L10" rel="file-client-go-L10">10</span>
          <span class="line-number" id="file-client-go-L11" rel="file-client-go-L11">11</span>
          <span class="line-number" id="file-client-go-L12" rel="file-client-go-L12">12</span>
          <span class="line-number" id="file-client-go-L13" rel="file-client-go-L13">13</span>
          <span class="line-number" id="file-client-go-L14" rel="file-client-go-L14">14</span>
          <span class="line-number" id="file-client-go-L15" rel="file-client-go-L15">15</span>
          <span class="line-number" id="file-client-go-L16" rel="file-client-go-L16">16</span>
          <span class="line-number" id="file-client-go-L17" rel="file-client-go-L17">17</span>
          <span class="line-number" id="file-client-go-L18" rel="file-client-go-L18">18</span>
          <span class="line-number" id="file-client-go-L19" rel="file-client-go-L19">19</span>
          <span class="line-number" id="file-client-go-L20" rel="file-client-go-L20">20</span>
          <span class="line-number" id="file-client-go-L21" rel="file-client-go-L21">21</span>
          <span class="line-number" id="file-client-go-L22" rel="file-client-go-L22">22</span>
          <span class="line-number" id="file-client-go-L23" rel="file-client-go-L23">23</span>
          <span class="line-number" id="file-client-go-L24" rel="file-client-go-L24">24</span>
          <span class="line-number" id="file-client-go-L25" rel="file-client-go-L25">25</span>
          <span class="line-number" id="file-client-go-L26" rel="file-client-go-L26">26</span>
          <span class="line-number" id="file-client-go-L27" rel="file-client-go-L27">27</span>
          <span class="line-number" id="file-client-go-L28" rel="file-client-go-L28">28</span>
          <span class="line-number" id="file-client-go-L29" rel="file-client-go-L29">29</span>
          <span class="line-number" id="file-client-go-L30" rel="file-client-go-L30">30</span>
          <span class="line-number" id="file-client-go-L31" rel="file-client-go-L31">31</span>
          <span class="line-number" id="file-client-go-L32" rel="file-client-go-L32">32</span>
          <span class="line-number" id="file-client-go-L33" rel="file-client-go-L33">33</span>
          <span class="line-number" id="file-client-go-L34" rel="file-client-go-L34">34</span>
          <span class="line-number" id="file-client-go-L35" rel="file-client-go-L35">35</span>
          <span class="line-number" id="file-client-go-L36" rel="file-client-go-L36">36</span>
          <span class="line-number" id="file-client-go-L37" rel="file-client-go-L37">37</span>
          <span class="line-number" id="file-client-go-L38" rel="file-client-go-L38">38</span>
          <span class="line-number" id="file-client-go-L39" rel="file-client-go-L39">39</span>
          <span class="line-number" id="file-client-go-L40" rel="file-client-go-L40">40</span>
          <span class="line-number" id="file-client-go-L41" rel="file-client-go-L41">41</span>
          <span class="line-number" id="file-client-go-L42" rel="file-client-go-L42">42</span>
          <span class="line-number" id="file-client-go-L43" rel="file-client-go-L43">43</span>
          <span class="line-number" id="file-client-go-L44" rel="file-client-go-L44">44</span>
          <span class="line-number" id="file-client-go-L45" rel="file-client-go-L45">45</span>
          <span class="line-number" id="file-client-go-L46" rel="file-client-go-L46">46</span>
          <span class="line-number" id="file-client-go-L47" rel="file-client-go-L47">47</span>
          <span class="line-number" id="file-client-go-L48" rel="file-client-go-L48">48</span>
          <span class="line-number" id="file-client-go-L49" rel="file-client-go-L49">49</span>
          <span class="line-number" id="file-client-go-L50" rel="file-client-go-L50">50</span>
          <span class="line-number" id="file-client-go-L51" rel="file-client-go-L51">51</span>
          <span class="line-number" id="file-client-go-L52" rel="file-client-go-L52">52</span>
          <span class="line-number" id="file-client-go-L53" rel="file-client-go-L53">53</span>
          <span class="line-number" id="file-client-go-L54" rel="file-client-go-L54">54</span>
        </td>
        <td class="line-data">
          <pre class="line-pre"><div class="line" id="file-client-go-LC1"><span class="kn">package</span> <span class="nx">main</span></div><div class="line" id="file-client-go-LC2">&nbsp;</div><div class="line" id="file-client-go-LC3"><span class="kn">import</span> <span class="p">(</span></div><div class="line" id="file-client-go-LC4">	<span class="s">&quot;log&quot;</span></div><div class="line" id="file-client-go-LC5">	<span class="s">&quot;net&quot;</span></div><div class="line" id="file-client-go-LC6">	<span class="s">&quot;net/rpc&quot;</span></div><div class="line" id="file-client-go-LC7">	<span class="s">&quot;sync&quot;</span></div><div class="line" id="file-client-go-LC8">	<span class="s">&quot;time&quot;</span></div><div class="line" id="file-client-go-LC9"><span class="p">)</span></div><div class="line" id="file-client-go-LC10">&nbsp;</div><div class="line" id="file-client-go-LC11"><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC12">&nbsp;</div><div class="line" id="file-client-go-LC13">	<span class="nx">reqs</span> <span class="o">:=</span> <span class="mi">100000</span></div><div class="line" id="file-client-go-LC14">&nbsp;</div><div class="line" id="file-client-go-LC15">	<span class="nx">address</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">ResolveTCPAddr</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;localhost:8080&quot;</span><span class="p">)</span></div><div class="line" id="file-client-go-LC16">	<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC17">		<span class="nx">log</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span></div><div class="line" id="file-client-go-LC18">		<span class="nx">log</span><span class="p">.</span><span class="nx">Fatal</span><span class="p">(</span><span class="s">&quot;Unable to resolve address&quot;</span><span class="p">)</span></div><div class="line" id="file-client-go-LC19">	<span class="p">}</span></div><div class="line" id="file-client-go-LC20">&nbsp;</div><div class="line" id="file-client-go-LC21">	<span class="nx">conn</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nx">DialTCP</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">address</span><span class="p">)</span></div><div class="line" id="file-client-go-LC22">	<span class="k">defer</span> <span class="nx">conn</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span></div><div class="line" id="file-client-go-LC23">&nbsp;</div><div class="line" id="file-client-go-LC24">	<span class="nx">client</span> <span class="o">:=</span> <span class="nx">rpc</span><span class="p">.</span><span class="nx">NewClient</span><span class="p">(</span><span class="nx">conn</span><span class="p">)</span></div><div class="line" id="file-client-go-LC25">	<span class="k">defer</span> <span class="nx">client</span><span class="p">.</span><span class="nx">Close</span><span class="p">()</span></div><div class="line" id="file-client-go-LC26">&nbsp;</div><div class="line" id="file-client-go-LC27">	<span class="nx">w</span> <span class="o">:=</span> <span class="nb">new</span><span class="p">(</span><span class="nx">sync</span><span class="p">.</span><span class="nx">WaitGroup</span><span class="p">)</span></div><div class="line" id="file-client-go-LC28">	<span class="nx">w</span><span class="p">.</span><span class="nx">Add</span><span class="p">(</span><span class="nx">reqs</span><span class="p">)</span></div><div class="line" id="file-client-go-LC29">&nbsp;</div><div class="line" id="file-client-go-LC30">	<span class="nx">start</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Now</span><span class="p">()</span></div><div class="line" id="file-client-go-LC31">&nbsp;</div><div class="line" id="file-client-go-LC32">	<span class="k">for</span> <span class="nx">i</span> <span class="o">:=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="p">&lt;</span> <span class="nx">reqs</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC33">		<span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC34">&nbsp;</div><div class="line" id="file-client-go-LC35">			<span class="kd">var</span> <span class="nx">reply</span> <span class="kt">string</span></div><div class="line" id="file-client-go-LC36">			<span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nx">Call</span><span class="p">(</span><span class="s">&quot;System.Ping&quot;</span><span class="p">,</span> <span class="s">&quot;ping&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">reply</span><span class="p">)</span></div><div class="line" id="file-client-go-LC37">			<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC38">				<span class="nx">log</span><span class="p">.</span><span class="nx">Fatal</span><span class="p">(</span><span class="s">&quot;ping error:&quot;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span></div><div class="line" id="file-client-go-LC39">			<span class="p">}</span></div><div class="line" id="file-client-go-LC40">			<span class="k">if</span> <span class="nx">reply</span> <span class="o">!=</span> <span class="s">&quot;pong&quot;</span> <span class="p">{</span></div><div class="line" id="file-client-go-LC41">				<span class="nx">log</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;ping error: did not receive pong&quot;</span><span class="p">)</span></div><div class="line" id="file-client-go-LC42">			<span class="p">}</span></div><div class="line" id="file-client-go-LC43">			<span class="c1">// log.Println(reply)</span></div><div class="line" id="file-client-go-LC44">			<span class="nx">w</span><span class="p">.</span><span class="nx">Done</span><span class="p">()</span></div><div class="line" id="file-client-go-LC45">		<span class="p">}()</span></div><div class="line" id="file-client-go-LC46">	<span class="p">}</span></div><div class="line" id="file-client-go-LC47">	<span class="nx">w</span><span class="p">.</span><span class="nx">Wait</span><span class="p">()</span></div><div class="line" id="file-client-go-LC48">&nbsp;</div><div class="line" id="file-client-go-LC49">	<span class="nx">run_time</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Since</span><span class="p">(</span><span class="nx">start</span><span class="p">)</span></div><div class="line" id="file-client-go-LC50">&nbsp;</div><div class="line" id="file-client-go-LC51">	<span class="nx">log</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">&quot;total time: %s\n&quot;</span><span class="p">,</span> <span class="nx">run_time</span><span class="p">)</span></div><div class="line" id="file-client-go-LC52">	<span class="nx">log</span><span class="p">.</span><span class="nx">Printf</span><span class="p">(</span><span class="s">&quot;reqs/sec: %.0f\n&quot;</span><span class="p">,</span> <span class="nb">float64</span><span class="p">(</span><span class="nx">reqs</span><span class="p">)</span><span class="o">/</span><span class="nb">float64</span><span class="p">(</span><span class="nx">run_time</span><span class="p">.</span><span class="nx">Seconds</span><span class="p">()))</span></div><div class="line" id="file-client-go-LC53">&nbsp;</div><div class="line" id="file-client-go-LC54"><span class="p">}</span></div></pre>
        </td>
      </tr>
    </table>
  </div>

        </div>

        <div class="gist-meta">
          <a href="https://gist.github.com/jasonmoo/3894201/raw/efc6003c52cc14d87d66e1c2e4b5bce6893fff5a/client.go" style="float:right">view raw</a>
          <a href="https://gist.github.com/jasonmoo/3894201#file-client-go" style="float:right; margin-right:10px; color:#666;">client.go</a>
          <a href="https://gist.github.com/jasonmoo/3894201">This Gist</a> brought to you by <a href="https://github.com">GitHub</a>.
        </div>
      </div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2012/10/a-sample-go-rpc-serverclient-over-tcp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What I learned from my first c coding challenge</title>
		<link>http://blog.jasonmooberry.com/2012/09/what-i-learned-from-my-first-c-coding-challenge/</link>
		<comments>http://blog.jasonmooberry.com/2012/09/what-i-learned-from-my-first-c-coding-challenge/#comments</comments>
		<pubDate>Tue, 04 Sep 2012 17:03:52 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[c]]></category>
		<category><![CDATA[code challenge]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=342</guid>
		<description><![CDATA[Last week at Vimeo we had a challenge. Build a better query string parameter sorter for a Varnish plugin. The gauntlet was thrown down at 5pm on a Friday and by 2am Friday night we had our first contender. I arrived home to see the code and decided to throw my hat into the ring. [...]]]></description>
			<content:encoded><![CDATA[<p>Last week at Vimeo we had a challenge. Build a better query string parameter sorter for a <a href="https://www.varnish-cache.org/" target="_blank">Varnish</a> plugin. The gauntlet was thrown down at 5pm on a Friday and by 2am Friday night we had our first contender. I arrived home to see the code and decided to throw my hat into the ring. I had made some attempts at c plugins for php but never really got anything off the ground. The <a href="http://www.amazon.com/C-Programming-Language-2nd-Edition/dp/0131103628" target="_blank">K&amp;R book</a> had been a fascination for me but now it was time to put it into practice.</p>
<p>While this is not in the Varnish module format yet, my still-evolving entry is here:  <a href="https://github.com/jasonmoo/skwurly" target="_blank">https://github.com/jasonmoo/skwurly</a></p>
<p><strong>The challenge:</strong></p>
<p>Take an input <code>const char*</code> url:</p>
<pre>/test.php?b=b&amp;c=bb&amp;a=3&amp;a=4</pre>
<p>and output in a standardized format:</p>
<pre>/test.php?a=3&amp;a=4&amp;b=b&amp;c=bb</pre>
<p>The goal here is to standardize a url so that it may be used as a key in a hash function of an http cache, thereby preventing duplicate pages in cache for the same url with differently ordered parameters. The sorted order is optional, so long as a canonical url is derived from any ordering of query string parameters.</p>
<p>It’s worth noting that since this was a friendly competition, much code sharing and talking over strategies and optimizations took place over the course of the week.</p>
<p><strong>Initial strategy</strong><br />
My initial strategy was slow and inefficient. Scan the url and count the number of ampersands so that I can allocate an array of structs of sufficient size. Scan again to grab pointers to the first character in the param and the param length and store them in the structs. Using qsort and strcmp sort the array of structs in alphabetical order. Allocate a string of duplicate size to the input. Iterate over the param struct and using pointer assignment to replace each character in sorted order.</p>
<p>With the exception of the return string all of the memory used is stack allocated. This attempt produced a program that could sort <em>~400k urls/sec on my macbook pro</em>. Not bad, but not nearly as good as it gets.</p>
<p>After getting a code review from a few other c devs I set out to take a different tack. The goal was only going touching each character of the input url once. I very nearly achieve that and it’s brought the performance up to <em>~1.8m urls/sec on my mbp</em>.</p>
<p>This is the breakdown of all the optimizations that I tried and kept/discarded. Many great devs assisted me in this process. They are listed at the bottom of the page and I am very grateful for the time they spent with me!</p>
<h3>Memory Matters</h3>
<p>So it turns out the two arrays (one of <code>const char*</code>, one of <code>unsigned short</code>) performs better than an array of pointers to structs containing the same value types.  The two values to track are the starting character position of the param in the url and it&#8217;s length.</p>
<pre>struct param {
    const char* start;
    unsigned short length;
}
param* params[];</pre>
<p>vs</p>
<pre>const char* params[];
unsigned short param_lengths[];</pre>
<p>This was a bit of a surprise to me. I had assumed that sorting a single pointer array would be faster than keeping track of two arrays. I was wrong. I tried different ordering of the elements of the struct, using a <code>long</code> to track length as an attempt at better memory alignment, doing array style access to elements vs incrementing pointer access. Each had different impacts but at the end of it all using two arrays was just faster. Also faster was an <code>unsigned short</code> array vs an <code>int</code> array.</p>
<p><strong>Variable Locality</strong><br />
Another optimization was to copy a <code>const char*</code> value into a <code>char</code> when I needed to test it multiple times. I had heard that this may be the case due to register use. I found it to be a minor increase in speed.</p>
<p><strong>Testing for zero</strong><br />
When iterating through a loop and testing that my index was less than the number of elements that were in the loop, I thought I was being efficient. But what I found was taking the number of elements and assigning it to a variable and decrementing that variable each time through the loop and testing when it was zero was faster. <em>It’s a cheaper test to test for <code>0</code> than to compare two numbers</em>.</p>
<p><strong>Pointer arithmetic</strong><br />
I have always heard of pointer arithmetic but now I understand why it’s so useful. Taking a pointer to the first element in an array and incrementing it to iterate through it’s elements is elegant and more efficient than taking an integer i and using it as an array index. I wish more languages afforded this.</p>
<p><strong>Hashing costs</strong><br />
A great suggestion from a friend was to hash each param to an integer and sort by the integers. In theory this would allow for touching each character of the input url only once before sorting was possible. I used a cheap hash called <a href="http://cr.yp.to/cdb/cdb.txt" target="_blank">djb</a>. I inlined it to reduce any function call overhead.</p>
<pre>// djb hash
int hash = 5381;
while (*url &amp;&amp; *url != '&amp;')
    hash = ((hash &lt;&lt; 5) + hash) ^ *url++;</pre>
<p>What I found was that it was a little bit slower. Why? Aside from the extra arithmetic that was being processed on every character, most query string parameters are sortable by looking at the first character of the param name only. <code>name=jason&amp;job=dev&amp;company=vimeo</code> for example, doesn’t require looking at any but the first character of each param. So I opted for character comparison.</p>
<p><strong><code>strcmp</code> vs hand rolled</strong><br />
Unforseen to me, a hand rolled string compare function performed better than native <code>strcmp</code>. I assumed that a native func would be all kinds of optimized but in the end a simple k&amp;r style character by character comparison performed better than <code>strcmp</code>. Dumping the assembly for both showed many more instructions for the <code>strcmp</code> version.</p>
<p><strong><code>qsort</code> vs insertion sort</strong><br />
I set out to use as many native funcs as I could but again found that it’s not always the most optimal path. A hand rolled insertion sort performed better than the <code>qsort</code> native function. But I found an even more performant way to sort params that reduced constant time and allowed me to return early when a url was already in sorted order.</p>
<p><strong>double-wide insertion sort</strong><br />
I was at a bar in the east village called double-wide and after much merriment came home to work on my url sorter. I had the thought that if I used an array of twice the size of the params, I could set the middle element as the zero index and this would allow me to prepend and append elements in O(1) time. This would save having to shuffle the entire array up one every time I had to put an element at the beginning. While this would be easily implemented in a linked list, the performance was still better with a double-wide array in my use case. I only needed to keep track of the head and tail elements of the array for easy iteration over them later. And if I only appended each param, I knew the params were already sorted. So I could return the original url.</p>
<p>(In this particular context the plugin architecture we were writing against allowed for returning the original string or a new malloc’d string)</p>
<p><strong>Zero or one param</strong><br />
Returning early when only a single param or zero params were present was another more obvious optimization.</p>
<h3>Optimizations that didn’t work:</h3>
<p><strong>Loop unrolling</strong><br />
In my feverish search for more and more obscure optimizations I stumbled upon a mind-bending gem called <a href="http://www.lysator.liu.se/c/duffs-device.html" target="_blank">Duff’s device</a>. On first glance I assumed my iphone had rendered the code wrong. After repeated attempts to understand, it slowly emerged in my mind. A loop unroller. In the author’s own words “disgusting”, and amazing.</p>
<pre>send(to, from, count)
register short *to, *from;
register count;
{
    register n=(count+7)/8;
    switch(count%8){
        case 0: do{ *to = *from++;
        case 7: *to = *from++;
        case 6: *to = *from++;
        case 5: *to = *from++;
        case 4: *to = *from++;
        case 3: *to = *from++;
        case 2: *to = *from++;
        case 1: *to = *from++; }while(--n&gt;0);
    }
}</pre>
<p>I built a <code>while</code>-less version that optimized for 6 params or fewer where the <code>switch</code> cases fell through to a default of my original <code>for</code> loop. Initially I found a minor speed up. However it turned out to be due to an inefficiency in my loop code! Once fixed, they performed the same.</p>
<p>A fellow coder pointed out that loops have been pretty heavily optimized by compilers and unrolling almost never produces any benefit any more.</p>
<p><strong>Single character comparison before a function call to str_compare</strong><br />
I had the idea that taking the first character of each param and comparing it inline and if they were the same, only then calling the str_compare function on the two params would cut many function calls and perform better.</p>
<pre>if ((c == 0 &amp;&amp; str_compare(params[TAIL], p) &lt; -1) || c &lt; -1)</pre>
<p>vs</p>
<pre>if (str_compare(params[TAIL], p) &lt; -1)</pre>
<p>What I found was that the extra logic was slowing things down. I learned a little bit about branching and how processors optimize code paths by executing as many possible branches as they can in parallel. So a simple function call (although declared as inline), beat the character comparison.</p>
<p><strong><code>memmove</code> vs pointer assigment</strong><br />
This one is probably due to the number of elements being dealt with when shuffling elements in my sorting algorithm, but there was no speedup, only slowdown, when using <code>memmove</code> to move elements in the array up before inserting a new one. Simple pointer assignment beat it.</p>
<h3>Profiling and analysing</h3>
<p>Late in the game a friend showed me how to profile my code. Using <code>gprof</code>, <code>gcov</code>, and <code>valgrind</code> gave me more information on how to tweak my code and how exactly it was being executed. <code>gcov -b</code> for branch tracking was an enlightening experience as a programmer. And in the next competition I’ll be reaching for these tools much earlier in the game.</p>
<h4>Conclusion</h4>
<p>While our competition may be near it’s end, I suspect we’ll never stop tweaking our code. Finding new ways to shave time and memory off our performance. It&#8217;s been such a great way to get acquainted with programming tactics in a language.  I&#8217;m thoroughly looking forward to the next.</p>
<p>At this point I am slightly behind the leader.<br />
#1: 2.17m urls/sec<br />
<strong>#2: 2.08m urls/sec (me)<br />
</strong>#3 1.83m urls/sec</p>
<p>Once we have a winner and we build the code into a proper Varnish module, we will open source it on <a href="https://github.com/vimeo">Vimeo&#8217;s github</a>.</p>
<p><strong>Awesome people</strong><br />
Thanks to <a href="http://dev.doorul.com/" target="_blank">Naren</a>, Carlos, <a href="https://github.com/dwbuiten" target="_blank">Derek</a>, Paul, <a href="https://twitter.com/won3d" target="_blank">Won</a>, Mashiat. Good hackin with you guys.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2012/09/what-i-learned-from-my-first-c-coding-challenge/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>The how behind the homepage</title>
		<link>http://blog.jasonmooberry.com/2011/10/the-how-behind-the-homepage/</link>
		<comments>http://blog.jasonmooberry.com/2011/10/the-how-behind-the-homepage/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 23:18:23 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=302</guid>
		<description><![CDATA[I recently built a new homepage to celebrate Fall and kill a few weekends playing with canvas, javascript and CA. A little while back I had an idea to use Cellular Automata rules to generate random groupings of xy coordinates. This worked well as a way to generate a rock pattern for my canvas drawing. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently built a <a href="http://jasonmooberry.com">new homepage</a> to celebrate Fall and kill a few weekends playing with canvas, javascript and CA.</p>
<p>A little while back I had an idea to use <a href="http://en.wikipedia.org/wiki/Cellular_automaton">Cellular Automata</a> rules to generate random groupings of xy coordinates.  This worked well as a way to generate a rock pattern for my <a href="http://blog.jasonmooberry.com/2011/05/death-valley-cellular-automata-and-html5-canvas/">canvas drawing</a>.  I even developed a <a href="http://local.jasonmooberry.com/dev/ca_helper.html">little tool</a> to help me refine the parameters to use that produced the pattern I wanted.</p>
<style>
#tools { margin:10px auto; width:620px; height:300px; }
#tools img { border:1px solid #ccc; }
</style>
<div id="tools">
<a href="http://jasonmooberry.com/dev/ca_fluid_animation.html" style="float:right;"><img src="http://jasonmooberry.com/dev/img/ca_animator.gif" /></a><br />
<a href="http://jasonmooberry.com/dev/ca_helper.html" style="float:left;"><img src="http://jasonmooberry.com/dev/img/ca_helper.gif"  /></a>
</div>
<p>I wanted to expand on that approach to make something more abstract and vizzy.  And animation seemed like the next step.  So I built <a href="http://jasonmooberry.com/dev/ca_fluid_animation.html">another tool</a> that allowed me to play around with animating generated CA sets of cells from one state to the next. </p>
<p>It lets you embed js into the callbacks for the driving parameters and even saves your settings into the hash tag so you can bookmark settings that you like and link to them.</p>
<p>So I&#8217;m publishing them both here for you to play with.  <img src='http://blog.jasonmooberry.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2011/10/the-how-behind-the-homepage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Password management with TrueCrypt and Dropbox</title>
		<link>http://blog.jasonmooberry.com/2011/08/password-management-with-truecrypt-and-dropbox/</link>
		<comments>http://blog.jasonmooberry.com/2011/08/password-management-with-truecrypt-and-dropbox/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 18:39:09 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[command line fu]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[passwords]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=284</guid>
		<description><![CDATA[Maintaining passwords for multiple servers across multiple development environments is a pain. A few weeks back there was a downed service on one of my servers and I was at a computer without my passwords and hosts files. The debugging session that followed required hopping through multiple servers and in general took a lot longer [...]]]></description>
			<content:encoded><![CDATA[<p>Maintaining passwords for multiple servers across multiple development environments is a pain.  A few weeks back there was a downed service on one of my servers and I was at a computer without my passwords and hosts files.  The debugging session that followed required hopping through multiple servers and in general took a lot longer than it should.  </p>
<p>I decided to use <a href="http://www.dropbox.com/" target="_blank">DropBox</a> and <a href="http://www.truecrypt.org/" target="_blank">TrueCrypt</a> to setup a secure password file that was synchronized across all of my environments.  The setup for both is dirt simple.  I created a 10mb encrypted file called <code>SAFEFILE</code> in my Dropbox, then add a <code>passwords.txt</code> to it.  </p>
<p>Then I evolved some code a friend threw my way for generating passwords.  Creating a password and storing it directly in my passwords.txt file, and retrieving it is now a snap.  The functions copy the password directly to the clipboard for easy pastin.</p>
<p>Adding my <code>~/.ssh</code>, <code>/etc/hosts</code>, <code>~/.profile</code> and a few other dotfiles to my Dropbox and symlinking them to my home directory keeps me standard across any environment I use.</p>
<p>Generate a random string 30 chars long for test.account:</p>
<pre>
jmooberry@local ~ : genpass 30 test.account
password added to passwords.txt as test.account
password copied to clipboard.
//  ole2iUmIGwDxtC9xVqPZiEr34ZJVwD
</pre>
<p>Grab the password for test.account:</p>
<pre>
jmooberry@local ~ : getpass test
password for (test.account) copied to clipboard.
// ole2iUmIGwDxtC9xVqPZiEr34ZJVwD
</pre>
<p><code>.profile</code> helpers functions:</p>
<pre>
# password generator
# Usage: genpass 30 test.account.name
function genpass() { 
  if [ $# == 0 ]; then
      length=30
  else
      length=$1
  fi
  pass=$(< /dev/random strings | perl -pe 's/\W//g;' | head -c$length)
  echo -n $pass | pbcopy
  if [ $# == 2 ]; then
    echo -en "\n$2\t$pass" >> /Volumes/SAFEFILE/passwords.txt
    echo "password added to passwords.txt as $2"
  fi
  echo "password copied to clipboard."
}

# password grabber
# Usage: getpass test.account.name
function getpass() { 
  pass=$(grep $1 /Volumes/SAFEFILE/passwords.txt | perl -pe 's/.+?(\w+)$/$1/;')
  name=$(grep $1 /Volumes/SAFEFILE/passwords.txt | perl -pe 's/(.+?)\s+\w+$/$1/;')
  echo -n $pass | pbcopy
  echo "password for ($name) copied to clipboard."
}

# it's important.
if [ ! -d "/Volumes/SAFEFILE" ]; then
  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
  echo "TRUECRYPT DIRECTORY NOT MOUNTED!!!"
  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
fi
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2011/08/password-management-with-truecrypt-and-dropbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick encrypt for your coffee shop traffic.</title>
		<link>http://blog.jasonmooberry.com/2011/05/quick-encrypt-for-your-coffee-shop-traffic/</link>
		<comments>http://blog.jasonmooberry.com/2011/05/quick-encrypt-for-your-coffee-shop-traffic/#comments</comments>
		<pubDate>Mon, 16 May 2011 04:19:54 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[command line fu]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[coffee shop]]></category>
		<category><![CDATA[secure networking]]></category>
		<category><![CDATA[socks proxy]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=276</guid>
		<description><![CDATA[Just a little function to add to your .profile that automatically turns on a socks proxy and tunnels all your traffic through the server of your choice. It&#8217;s a simple setup and &#60;CTRL&#62;-C kills the connection and shuts off the proxy. This assumes that you have shell access to some server that you trust to [...]]]></description>
			<content:encoded><![CDATA[<p>Just a little function to add to your <code>.profile</code> that automatically turns on a socks proxy and tunnels all your traffic through the server of your choice.  It&#8217;s a simple setup and &lt;CTRL&gt;-C kills the connection and shuts off the proxy.  This assumes that you have shell access to some server that you trust to run your traffic through. </p>
<p>I recommend setting up <a href="http://stackoverflow.com/questions/7260/how-do-i-setup-public-key-authentication" target="_blank">public key authentication</a> for ease of use.</p>
<pre>
# warm feet
function socks() { 
  networksetup -setsocksfirewallproxy AirPort localhost 9999
  ssh -ND 9999 -C username@domain
  networksetup -setsocksfirewallproxystate AirPort off
}
</pre>
<p>(One caveat:  If you happen to close the window of your terminal without hitting &lt;CTRL&gt;-C first, it will not disable the socks proxy.)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2011/05/quick-encrypt-for-your-coffee-shop-traffic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drawing with Cellular Automata and HTML5 Canvas</title>
		<link>http://blog.jasonmooberry.com/2011/05/death-valley-cellular-automata-and-html5-canvas/</link>
		<comments>http://blog.jasonmooberry.com/2011/05/death-valley-cellular-automata-and-html5-canvas/#comments</comments>
		<pubDate>Wed, 11 May 2011 03:00:22 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Me]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[game of life]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[PHI]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=227</guid>
		<description><![CDATA[This weekend I set out to do some canvas drawings. The first one ended up being the centerpiece of my home page. It was inspired by the leaves of a tree on my street. Oh it&#8217;s good to be back in the deciduous loving climate. The second drawing was inspired by a recent campout in [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend I set out to do some canvas drawings.  The first one ended up being the centerpiece of my <a href="http://jasonmooberry.com" target="_blank">home page</a>.  It was inspired by the leaves of a tree on my street.  Oh it&#8217;s good to be back in the deciduous loving climate.</p>
<p>The second drawing was inspired by a recent campout in Death Valley.  The contrast of the blue sky, desert floor, and red coleman tent leave a strong imprint on me every time.</p>
<div style="text-align:center;">
<a href="http://jasonmooberry.com/dev/img/dv.jpg" target="_blank" ><img src="http://jasonmooberry.com/dev/img/dv_sm.jpg" style="margin:10px;" /></a> <a href="http://jasonmooberry.com/dev/dv_drawing.html" target="_blank"><img src="http://jasonmooberry.com/dev/img/dv_drawing.jpg" style="margin:10px;width:300px;height:225px;" /></a>
</div>
<p>The end result should resemble the <a href="http://jasonmooberry.com/dev/dv_drawing.html" target="_blank">picture on the right.</a>  The page load time is a few seconds on my MBP and it looks quite a lot better in Chrome.  The canvas size is determined at load so if you have the horses, full-screen your browser.  </p>
<p>I say resemble because the drawing is generated using canvas and cellular automata, and derived from a random data set every time it is rendered.  </p>
<p>One of the difficulties of drawing a picture of landscape is the seemingly random variations found in it.  Not totally random because each element interacts and affects the others.  The stone pattern on the drawing was the first thing I set out to solve.</p>
<p>Initially I was hoping to hit on some semi-random scatter pattern using PHI and a lot of trial and error.  This produced a fairly uniform random scatter of stones.  What I wanted to draw resembled clumps more than anything.  </p>
<p>While scatter patterning away I happened to over hear a gentlemen at the coffee shop mentioning cellular automata and emergent systems as they explain the state of the universe.  It&#8217;s kindof a hippie coffee shop but this guy is clearly in a league of his own.  At first I dismissed it and then the idea grew on me that I could generate these clumps with CA.  I had used CA for Conway&#8217;s game of life and a few other toy systems to experiment in the past and it was always fun.</p>
<p>So I generated a map of pixels that were randomly turned on.  I weighted the initial data set to be very switched on (baby!).  My reasoning was that I wanted grouping to occur within a few mutations and a seriously overcrowded starting set should do just that.  The size of the canvas element was prohibitively large so I added a resolution factor.  It causes striations in the starting set view but it doesn&#8217;t affect the CA mutations.</p>
<pre>
// set up psuedo random cell set
for (var i=0; i < total; i++) {
  if (Math.random() > .2) {
    cells[i] = 1;
  }
}
</pre>
<div style="text-align:center;"><a href="http://jasonmooberry.com/dev/ca_helper.html" target="_blank"><img src="http://jasonmooberry.com/dev/img/dv_initial_set.gif" /></a><br />
with resolution factor:<br />
<a href="http://jasonmooberry.com/dev/ca_helper.html" target="_blank"><img src="http://jasonmooberry.com/dev/img/dv_initial_set_r.gif" /></a></div>
<p>Let&#8217;s grind this set down with Conway&#8217;s game of life rules and see what comes out:</p>
<pre>
// mutate m number of times
while (m--) {
  var next = {};
  for (p in cells) { next[p] = 1; }
  
  for (var i=0; i < total; i++) {
    var above = i-w < 0 ? i-w+total : i-w,  // wrap 
      below = i+w > total ? i+w-total : i+w, // wrap
      neighbors = [above-1,above,above+1,i-1,i+1,below-1,below,below+1],
      active = 0,
      j = neighbors.length-1;

    while (j--) {
      active += (typeof cells[neighbors[j]] === 'number' &#038;&#038; cells[neighbors[j]] === 1)|0;
    }
    // rule check
    // Any dead cell with exactly three live neighbours becomes a live cell.
    if (active === 3 &#038;&#038; typeof cells[i] === 'undefined') {
      next[i] = 1; 
    } 
    // Any live cell with two or three live neighbours lives on to the next generation.
    // Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
    // Any live cell with more than three live neighbours dies, as if by overcrowding.
    else if (active < 2 || active > 3) {
      delete next[i];
    }
  }
  var cells = {};
  for (p in next) { cells[p] = 1; }
}
</pre>
<div style="text-align:center;"><a href="http://jasonmooberry.com/dev/ca_helper.html" target="_blank"><img src="http://jasonmooberry.com/dev/img/dv_pass_1.gif" /></p>
<p><img src="http://jasonmooberry.com/dev/img/dv_pass_3.gif" /></p>
<p><img src="http://jasonmooberry.com/dev/img/dv_pass_8.gif" /></a></div>
<p>As you can see the first pass cleared out a bunch of em.  The resolution factor has spaced the pixels apart but you can see the basics of game of life players emerging.  By pass 3 it&#8217;s in a much more spare state but still larger groups than I want.  By pass 8 the groups have moved away from each other a bit more and formed a decent pattern. Since this pattern is generated fresh from a random data set every time, we just need something that&#8217;s right most of the time.  </p>
<p>What I like about this approach is that it gives some credence to the hippie coffee shop guy&#8217;s words.  I don&#8217;t think the world runs on CA rules, but iterative, interactive rules seem to give rise to interesting &#8220;random&#8221; patterns.</p>
<p>The dataset produced from these mutations can now be used to render a rock pattern with a little magic for the coloring/size.  </p>
<pre>
for (var i in cells) {
  c.beginPath();
  var x = (i*r)%w,
    y = (i*r)/w|0;
  c.strokeStyle = (['rgba(116,116,108,.7);','rgba(87,93,55,.9);'])[i%15===0|0];
  c.lineWidth = Math.max(30,50*(y/h));
  c.arc(x,y,3,0,360,false);
  c.stroke();
}
</pre>
<div style="text-align:center;"><a href="http://jasonmooberry.com/dev/ca_helper.html" target="_blank"><img src="http://jasonmooberry.com/dev/img/dv_render.gif" /></a></div>
<h3>tl dr;</h3>
<p>Using Cellular Automata rules to mutate random datasets can produce interesting and unique landscape patterns.  This approach was super useful for me in drawing an impressionist picture of my favorite camping spot.</p>
<p>I wrote a <a href="http://jasonmooberry.com/dev/ca_helper.html" target="_blank">simple tool</a> to experiment with different factors for generating these patterns.</p>
<p>And <a href="http://jasonmooberry.com/dev/dv_drawing.html" target="_blank">here&#8217;s the picture</a> that is generated from random CA patterns.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2011/05/death-valley-cellular-automata-and-html5-canvas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to refactor other&#8217;s code.</title>
		<link>http://blog.jasonmooberry.com/2011/02/how-to-refactor-others-code/</link>
		<comments>http://blog.jasonmooberry.com/2011/02/how-to-refactor-others-code/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 03:14:16 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[people]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=222</guid>
		<description><![CDATA[I was in a position today to refactor some code that didn&#8217;t belong to me. Without going into much detail I was asked to implement a feature that required some significant changes to some fresh code. A friend was online at the time. I remembered he had a very gentle way of dealing with other [...]]]></description>
			<content:encoded><![CDATA[<p>I was in a position today to refactor some code that didn&#8217;t belong to me.  Without going into much detail I was asked to implement a feature that required some significant changes to some fresh code.  </p>
<p>A friend was online at the time.  I remembered he had a very gentle way of dealing with other programmers.  He happens to be very smart and, as such, was in a position to review/teach most of the people at the company we worked at together.  I asked him how to do it:</p>
<p>me:</p>
<blockquote><p>hey i have a question.  how do you refactor someone else&#8217;s code without being &#8220;that jerk who&#8217;s refactoring my code&#8221;?  is it possible?
</p></blockquote>
<p>him: </p>
<blockquote><p>That is very hard.  When I approach that issue I always remember a quotation even though I forgot who said it: &#8220;To successfully critique something you must first learn to love it.&#8221;</p>
<p>Also I&#8217;m probably rewriting the quote somehow</p>
<p>If you approach someone about refactoring their code and show them that you&#8217;ve taken the time to understand why their code was written the way it was, or, if it&#8217;s super crappy, why they were in a compressed time schedule while writing it, or why it would help them to work with you to learn it better, etc. etc…. basically if you approach them with respect and compassion, and they get all pissy, at that point it&#8217;s their fault </p>
<p>But the best thing is to communicate period, often times I&#8217;ve seen people shrink away from communicating because they don&#8217;t want to confront the other person, and they end up rewriting the code without consulting with the original coder, or, worse, not dealing with the issue and leaving the bad code to rot.  Confrontation, even if it pisses the person off, is always better than doing nothing or doing something around the person
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2011/02/how-to-refactor-others-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ecsmas and Tron</title>
		<link>http://blog.jasonmooberry.com/2010/12/ecsmas-and-tron/</link>
		<comments>http://blog.jasonmooberry.com/2010/12/ecsmas-and-tron/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 08:09:19 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[ecsmas]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[tron]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=212</guid>
		<description><![CDATA[Well I really had a blast working with @darkgoyle on the Merry Ecsmas project on Christmas Eve. It was my first attempt at a canvas creation and it came together great. I am still finding myself creating snowflakes there! All this canvas exposure and seeing how @darkgoyle does his maths got me in a mood [...]]]></description>
			<content:encoded><![CDATA[<p>Well I really had a blast working with <a href="http://twitter.com/@darkgoyle">@darkgoyle</a> on the <a href="http://ecsmas.com">Merry Ecsmas</a> project on Christmas Eve.  It was my first attempt at a canvas creation and it came together great.  I am still finding myself creating snowflakes there!  <img src='http://blog.jasonmooberry.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>All this canvas exposure and seeing how <a href="http://twitter.com/@darkgoyle">@darkgoyle</a> does his maths got me in a mood to experiment!  So I played around with implementing variations on a Fibonacci graph and many other different oddities involving timestamps and Phi.  The one I liked the most was pretty simple.  It is a rotation at 160 degrees with a 10px increment on the line length at each iteration.  Here&#8217;s what it produces:</p>
<div style="text-align:center"><a href="http://jasonmooberry.com/img/160d.png"><img src="http://jasonmooberry.com/img/160d_sm.png" /></a></div>
<p>I think it&#8217;s rad in a simple Trony sortof way.  Here&#8217;s the code to generate it:</p>
<pre>
// get the canvas
var canvas = document.getElementsByTagName('canvas')[0],
  c = canvas.getContext('2d'),
  center = { x: canvas.width/2, y: canvas.height/2 };

// setup starting state    
c.translate(center.x,center.y);

// base styles
c.lineCap = 'round';
c.lineWidth = 2;
c.strokeStyle = 'rgba(0,0,255,.7)';

var f = 1;
while (f < 500) {
  c.beginPath();
  c.moveTo(0,0);
  c.rotate(160*(Math.PI/180)); // convert degrees to radians
  c.lineTo(f,f);
  c.translate(f,f);
  c.stroke();
  f += 10;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2010/12/ecsmas-and-tron/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DumbledORM version 0.1 released!</title>
		<link>http://blog.jasonmooberry.com/2010/12/dumbledorm-version-0-1-released/</link>
		<comments>http://blog.jasonmooberry.com/2010/12/dumbledorm-version-0-1-released/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 09:32:22 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[dumbledorm]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[novelty orm]]></category>
		<category><![CDATA[php 5.3]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=204</guid>
		<description><![CDATA[I&#8217;m happy to announce the release of DumbledORM 0.1. It&#8217;s a major revamp from the initial release. It&#8217;s still the same ~200 loc, but now chocked full of comments and under the MIT license. A few noteworthy changes. PDO now throws exceptions by default. The standard default in PDO is to fail silently. This was [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce the release of DumbledORM 0.1.  It&#8217;s a major revamp from the initial release.  It&#8217;s still the same ~200 loc, but now chocked full of comments and under the MIT license.</p>
<p>A few noteworthy changes.</p>
<ol>
<li>PDO now throws exceptions by default.  The standard default in PDO is to fail silently.  This was unintended and thanks to <a href="http://twitter.com/#!/jimplush" target="_blank">@jimplush</a> for reporting it.  Be sure to try/catch your code appropriately.</li>
<li><code>Db::execute()</code> method added.  All of the Db methods are publicly accessible and this method is for executing sql that doesn&#8217;t require a fetch (inserts, updates, deletes, etc).  The requirement for this method became clear after turning on exceptions in PDO.</li>
<li>Better docs.  The docs in the README have been updated and reformatted.</li>
</ol>
<p>DumbledORM received a lot of great feedback and attention after it&#8217;s release.  Thank you for all the positive response to this little ORM.  I hope it continues to grow in use and remains small in size.  <img src='http://blog.jasonmooberry.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Download DumbledORM and get started here:<br />
<a href="https://github.com/jasonmoo/DumbledORM">https://github.com/jasonmoo/DumbledORM</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2010/12/dumbledorm-version-0-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MEMP: PHP 5.3 with FPM and nginx via MacPorts</title>
		<link>http://blog.jasonmooberry.com/2010/12/memp-php-5-3-with-fpm-and-nginx-via-macports/</link>
		<comments>http://blog.jasonmooberry.com/2010/12/memp-php-5-3-with-fpm-and-nginx-via-macports/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 01:16:38 +0000</pubDate>
		<dc:creator>Jason Mooberry</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MacPorts]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php 5.3]]></category>
		<category><![CDATA[php-fpm]]></category>

		<guid isPermaLink="false">http://blog.jasonmooberry.com/?p=158</guid>
		<description><![CDATA[I&#8217;ve been considering diving into nginx for a bit now. Rumors of it&#8217;s speed and Cyrillic error messages have intrigued me. With recent forays into node.js apps and their requirement for a free port, I wanted to find a nice solution that complimented the evented speed of node.js without exposing a port publicly for each [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been considering diving into <a href="http://nginx.org/">nginx</a> for a bit now.  Rumors of it&#8217;s speed and Cyrillic error messages have intrigued me.  With recent forays into <a href="http://nodejs.org/">node.js</a> apps and their requirement for a free port, I wanted to find a nice solution that complimented the evented speed of node.js without exposing a port publicly for each app.  As it turns out Nginx is suited quite nicely to this.  But that wasn&#8217;t where it ended.  I found nginx to have a much more interesting and dynamic config language.  And even beyond that it gave me a good excuse to learn more about running PHP as a FastCGI process and how <a href="http://php.net/manual/en/install.fpm.php">PHP-FPM (baked in as of 5.3.3)</a> fits into the picture.  Not sure if MEMP is the correct acronym, but since I&#8217;ve seen talk of <a href="http://library.linode.com/lemp-guides/">LEMP servers</a>, I&#8217;ll run with it.</p>
<p><a href="http://www.macports.org/">MacPorts</a>.  If you&#8217;re not already familiar with it, I recommend reading up before proceeding.</p>
<p>Since I already have MySQL set up and configured I won&#8217;t bother covering it here.  It&#8217;s pretty well documented around the webs.  The main focus here is going to be getting nginx installed and setting up PHP as a service to it with an emphasis on local development.  No need to tweak this for production on my Macbook Pro.</p>
<p>PHP 5.3.3 introduced PHP-FPM (FastCGI Process Manager) to the codebase.  Building it requires a few extra config flags and generates a php-fpm binary.  The binary will manage spawning cgi processes and handling the FastCGI passthru from nginx.  Currently MacPorts does not have an option to build PHP with PHP-FPM.  After some hacking on the current Portfile I arrived at a working solution.  It includes the correct flags, a dependency on libevent, and a startup item.</p>
<p>First things first.</p>
<pre class="brush: bash">
sudo port selfupdate

# recommended but probably not a requirement
sudo port upgrade outdated
sudo port uninstall inactive
</pre>
<p>(If you&#8217;ve already got the php5 package installed, uninstall it and it&#8217;s cohorts to ensure a clean install process going forward.)</p>
<p>This is a bit of a hack and there&#8217;s probably a better way, like submitting a proper patch to MacPorts, but this will get the job done for today.</p>
<pre class="brush: bash">
# replace this file with the Portfile from the gist below
/opt/local/var/macports/sources/rsync.macports.org/release/ports/lang/php5/Portfile
</pre>
<p><a href="https://gist.github.com/724449" target="_blank">https://gist.github.com/724449</a></p>
<p>Then run the regular port install.</p>
<pre class="brush: bash">
sudo port install nginx php5 +fastcgi php5-apc php5-mysql +mysqlnd
</pre>
<p>Next we&#8217;ll need to set up the configs.  There&#8217;s two basic configs that require attention.  First is the nginx config.  Since this is just for a local development env we can be pretty lean on what we need.</p>
<pre class="brush: bash">
# /opt/local/etc/nginx/nginx.conf

worker_processes  1;

error_log  /var/log/nginx/error.log;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile           on;
    keepalive_timeout  65;

    server {
      listen 80;
      server_name   ~^local\.(?<site>.+?)\.com$;
      root  /Users/jason/Sites/$site/web;
      index  index.php index.html;

      location = /favicon.ico {
        log_not_found off;
      }

      location ~ \.php$ {
         fastcgi_pass   unix:/tmp/php-fpm.sock;
         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
         include        fastcgi_params;
      }
    }
}
</pre>
<p>This is the config that I&#8217;m currently using as my generic site config.  It has a few nice features.  First the server name is matched against a regular expression.  So any site that matches <code>local.xxxx.com</code> will be parsed and use the <code>xxxx</code> as a sub-directory in my Sites folder.  This is nice.  So I only need to create a new directory and add my <code>local.xxxx.com</code> domain to <code>/etc/hosts</code> pointed at <code>127.0.0.1</code> and I can immediately begin developing.  Gone are the days of creating a new v-hosts file, enabling it, and restarting apache every time I want to play with a new site&#8217;s code.  The other nicety here is we&#8217;re using a unix socket for the fastcgi passthru.  This is unnoticeably faster on my Mac, but again frees up the need to be concerned with another open port on my system. </p>
<p>It&#8217;s worth noting that any <code>fastcgi_param</code> that you define in this config is available within PHP as a <code>$_SERVER</code> variable. </p>
<p>The second config is the FPM config.  Copy <code>/opt/local/etc/php-fpm.conf.default</code> to <code>/opt/local/etc/php-fpm.conf</code> and open it up. Here are the important ones to modify:</p>
<pre class="brush: plain">
pid = /opt/local/var/run/php-fpm.pid
error_log = /opt/local/var/log/php-fpm.log
listen = /tmp/php-fpm.sock
listen.owner = _www
listen.group = _www
pm.max_children = 1
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1
pm.max_requests = 500
slowlog = /opt/local/var/log/php-fpm.log.slow
</pre>
<p>It&#8217;s pretty straight-forward.  Lean cus we can. Save and continue.</p>
<p>At this point we&#8217;ve got all the pieces in place.  We just need a way to start/stop/restart nginx and FPM.  I looked for a cleaner way to accomplish this but in the end it came down to a handful of aliases.  Add these to your <code>~/.profile</code>. </p>
<pre class="brush: bash">
# nginx
alias nginx_start='sudo launchctl load /Library/LaunchDaemons/org.macports.nginx.plist' 
alias nginx_stop='sudo launchctl unload /Library/LaunchDaemons/org.macports.nginx.plist' 
alias nginx_restart='nginx_stop; nginx_start;' 

# php-fpm
alias fpm_start='sudo launchctl load /Library/LaunchDaemons/org.macports.php-fpm.plist'
alias fpm_stop='sudo launchctl unload /Library/LaunchDaemons/org.macports.php-fpm.plist'
alias fpm_restart='fpm_stop; fpm_start'
</pre>
<p>Reopen the Terminal window to enable the new aliases.  Start or restart nginx and FPM as the case may be.</p>
<p>At this point you should be able to create a site directory, add a domain to <code>/etc/hosts</code> and drop in an <code>index.php</code> with <code>phpinfo();</code> to verify that PHP is working.</p>
<p>Hopefully this will be of some use to other aspiring MEMP devs out there.  I found it intensely fun.  <img src='http://blog.jasonmooberry.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jasonmooberry.com/2010/12/memp-php-5-3-with-fpm-and-nginx-via-macports/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.159 seconds -->
<!-- Cached page served by WP-Cache -->
