<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://www.johnhawthorn.com/</id>
  <title>John Hawthorn</title>
  <updated>2012-03-11T08:00:00Z</updated>
  <link rel="alternate" href="http://www.johnhawthorn.com/"/>
  <link rel="self" href="http://www.johnhawthorn.com/atom.xml"/>
  <author>
    <name>John Hawthorn</name>
    <uri>http://www.johnhawthorn.com</uri>
  </author>
  <entry>
    <id>tag:www.johnhawthorn.com,2012-03-11:/2012/03/squeezing-performance-from-cuda/</id>
    <title type="html">Squeezing performance out of CUDA</title>
    <published>2012-03-11T08:00:00Z</published>
    <updated>2012-03-11T08:00:00Z</updated>
    <link rel="alternate" href="http://www.johnhawthorn.com/2012/03/squeezing-performance-from-cuda/"/>
    <content type="html">&lt;p&gt;GPU code is known for being capable of extremely fast computation, but such performance only comes with well crafted code.&lt;/p&gt;

&lt;p&gt;The following are the iterations I went through to squeeze performance out of a CUDA kernel for matrix multiplication in CSR format.
Testing was done on a Quadro FX 5800 with CUDA 3.2 and involved a matrix multiplication of a large 52000x52000 sparse matrix with about 1% non-zero entries.
All timings listed here are imprecise, and only meant to give an idea of relative performance.&lt;/p&gt;

&lt;h2&gt;Initial (naive) implementation&lt;/h2&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;__global__ &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; cuda_mat_mul_kernel(&lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *rows,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *cols,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *data,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *v,
                                    scalar_t *dest,
                                    &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; N){
  &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row = threadIdx.x + blockIdx.x * blockDim.x;
  &lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt;(row &amp;gt;= N)
     &lt;span style="color:#000;font-weight:bold"&gt;return&lt;/span&gt;;
  &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_start = rows[row];
  &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_end   = rows[row+&lt;span style=""&gt;1&lt;/span&gt;];
  &lt;span style="color:#074;font-weight:bold"&gt;float&lt;/span&gt; sum = &lt;span style="color:#099"&gt;0&lt;/span&gt;&lt;span style="color:#099"&gt;.0f&lt;/span&gt;;
  &lt;span style="color:#000;font-weight:bold"&gt;for&lt;/span&gt;(&lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; i = row_start; i &amp;lt; row_end; i++)
     sum += data[i] * v[cols[i]];
  dest[row] = sum;
}
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This is a pretty straightforward implementation, similar to what one would write as a serial CPU implementation.
It uses one thread per row, each of which simply computes the dot product and writes it back to global.
This kernel takes about 100 milliseconds to run, several times slower than the equivalent CPU code.&lt;/p&gt;

&lt;h2&gt;Memory coalescing&lt;/h2&gt;

&lt;p&gt;Perhaps the most important factor in optimizing CUDA performance is to allow memory coalescing when accessing global memory.
This is possible when sequential words of memory are accessed by sequential threads in a warp (thread 0 reads word 0, thread 1 reads word 1, etc.).
This implementation achieves this by having multiple threads per row, which access words at an offset equal to their thread number within the block.
The partial sum of each thread is then stored in per-block shared memory, which is then summed and stored as the final result.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
17
18
19
&lt;strong&gt;20&lt;/strong&gt;
21
22
23
24
25
26
27
28
29
&lt;strong&gt;30&lt;/strong&gt;
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span style="color:#579"&gt;#define&lt;/span&gt; THREADS_PER_BLOCK &lt;span style=""&gt;32&lt;/span&gt;
__global__ &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; cuda_mat_mul_kernel(&lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *rows,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *cols,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *data,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *v,
                                    scalar_t *dest,
                                    &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; N){

  __shared__ &lt;span style="color:#088;font-weight:bold"&gt;volatile&lt;/span&gt; scalar_t sums[THREADS_PER_BLOCK * &lt;span style=""&gt;2&lt;/span&gt;];
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_start = rows[blockIdx.x];
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_end   = rows[blockIdx.x+&lt;span style=""&gt;1&lt;/span&gt;];

  scalar_t sum = &lt;span style="color:#099"&gt;0&lt;/span&gt;&lt;span style="color:#099"&gt;.0f&lt;/span&gt;;
  &lt;span style="color:#000;font-weight:bold"&gt;for&lt;/span&gt;(&lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; i = row_start + threadIdx.x; i &amp;lt; row_end; i += THREADS_PER_BLOCK){
     sum += data[i] * v[cols[i]];
  }

  sums[threadIdx.x] = sum;
  __syncthreads();

  &lt;span style="color:#998;font-style:italic"&gt;/* hardcoded reduction for 32 threads */&lt;/span&gt;
  sums[threadIdx.x] += sums[threadIdx.x + &lt;span style=""&gt;16&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;8&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;4&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;2&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;1&lt;/span&gt;];

  &lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt;(threadIdx.x == &lt;span style=""&gt;0&lt;/span&gt;)
     dest[row] = sums[&lt;span style=""&gt;0&lt;/span&gt;];
}
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This kernel allows reads from the &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;cols&lt;/code&gt; vectors to be coalesced.
The reduction works without &lt;code&gt;__syncthreads()&lt;/code&gt; calls between each addition since the threads will be executing them simultaneously.
This is similar to the reduction example in the NVIDIA GPU Computing SDK.
This kernel improved perforamnce to about 5 milliseconds.&lt;/p&gt;

&lt;h2&gt;Texture Memory&lt;/h2&gt;

&lt;p&gt;Although reads to &lt;code&gt;data&lt;/code&gt; and &lt;code&gt;cols&lt;/code&gt; are not coalesced, accesses to the &lt;code&gt;v&lt;/code&gt; vector is still non-coalesced.
By caching &lt;code&gt;v&lt;/code&gt; in texture memory, the random reads will be faster.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
17
18
19
&lt;strong&gt;20&lt;/strong&gt;
21
22
23
24
25
26
27
28
29
&lt;strong&gt;30&lt;/strong&gt;
31
32
33
34
35
36
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;texture&amp;lt;scalar_t&amp;gt; texRef;
&lt;span style="color:#579"&gt;#define&lt;/span&gt; THREADS_PER_BLOCK &lt;span style=""&gt;32&lt;/span&gt;
__global__ &lt;span style="color:#088;font-weight:bold"&gt;void&lt;/span&gt; cuda_mat_mul_kernel(&lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *rows,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; *cols,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *data,
                                    &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; scalar_t *v,
                                    scalar_t *dest,
                                    &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; N){

  __shared__ &lt;span style="color:#088;font-weight:bold"&gt;volatile&lt;/span&gt; scalar_t sums[THREADS_PER_BLOCK * &lt;span style=""&gt;2&lt;/span&gt;];
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_start = rows[blockIdx.x];
  &lt;span style="color:#088;font-weight:bold"&gt;const&lt;/span&gt; &lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; row_end   = rows[blockIdx.x+&lt;span style=""&gt;1&lt;/span&gt;];

  scalar_t sum = &lt;span style="color:#099"&gt;0&lt;/span&gt;&lt;span style="color:#099"&gt;.0f&lt;/span&gt;;
  &lt;span style="color:#000;font-weight:bold"&gt;for&lt;/span&gt;(&lt;span style="color:#074;font-weight:bold"&gt;int&lt;/span&gt; i = row_start + threadIdx.x; i &amp;lt; row_end; i += THREADS_PER_BLOCK){
     &lt;span style="color:#998;font-style:italic"&gt;//sum += data[i] * v[cols[i]];&lt;/span&gt;
     sum += data[i] * tex1Dfetch(texRef, cols[i]);
  }

  sums[threadIdx.x] = sum;
  __syncthreads();

  &lt;span style="color:#998;font-style:italic"&gt;/* hardcoded reduction for 32 threads */&lt;/span&gt;
  sums[threadIdx.x] += sums[threadIdx.x + &lt;span style=""&gt;16&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;8&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;4&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;2&lt;/span&gt;];
  sums[threadIdx.x] += sums[threadIdx.x +  &lt;span style=""&gt;1&lt;/span&gt;];

  &lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt;(threadIdx.x == &lt;span style=""&gt;0&lt;/span&gt;)
     dest[row] = sums[&lt;span style=""&gt;0&lt;/span&gt;];
}

&lt;span style="color:#998;font-style:italic"&gt;/* on CPU */&lt;/span&gt;
size_t offset = size_t(-&lt;span style=""&gt;1&lt;/span&gt;);
cudaBindTexture(&amp;amp;offset, texRef, v);
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Using texture memory increases performance to about 3 milliseconds.&lt;/p&gt;

&lt;h2&gt;Other potential improvements&lt;/h2&gt;

&lt;p&gt;I implemented several other improvements which achieved small performance improvements.
Results may vary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summing more rows per block (more threads per row), ensuring that a high occupancy is met (profile with COMPUTE_PROFILE=1).&lt;/li&gt;
&lt;li&gt;Adjusting the number of blocks run.&lt;/li&gt;
&lt;li&gt;Aligning each row to a cache line achieves a small speedup, since the coalesced reads will be aligned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementing these further increased performance to about 2 milliseconds.&lt;/p&gt;

&lt;h2&gt;A final word&lt;/h2&gt;

&lt;p&gt;If you are in fact writing something similar, existing libraries like cuBLAS and cusparse are likely much faster than what one would create in a reasonable amount of time.
The &lt;a href="http://developer.nvidia.com/gpu-accelerated-libraries"&gt;NVIDIA GPU-Accelerated Libraries&lt;/a&gt; page is a good place to start.
The excellent &lt;a href="http://code.google.com/p/cusp-library/"&gt;CUSP C++ library&lt;/a&gt; also has a CSR kernel almost equivalent to this one, and is a very convenient library for most sparse matrix applications.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.johnhawthorn.com,2012-02-10:/2012/02/speeding-up-rails-statrtup/</id>
    <title type="html">Speed up your rails startup time</title>
    <published>2012-02-10T08:00:00Z</published>
    <updated>2012-02-10T08:00:00Z</updated>
    <link rel="alternate" href="http://www.johnhawthorn.com/2012/02/speeding-up-rails-statrtup/"/>
    <content type="html">&lt;p&gt;I&amp;#39;ve found when developing that the faster my rails app can start, the faster I can develop.
This is mostly because of the speed I can start test cases. But speed of starting a server or a console is also a big factor.
I&amp;#39;d like to present a summary of what others have shown to aid in this performance.&lt;/p&gt;

&lt;h2&gt;Eliminate unnecessary gems&lt;/h2&gt;

&lt;p&gt;First tip comes courtesy of tenderlove: (The number of gems installed on your system can impact rails boot time)[http://tenderlovemaking.com/2011/11/30/psa-the-number-of-gems-installed-on-your-system-can-impact-rails-boot-time/]
In short, the gemspecs on your system are all loaded as your app starts ()
even when using bundler.
Some &lt;a href="http://tenderlovemaking.com/2011/12/05/profiling-rails-startup-with-dtrace/"&gt;inconsiderate gemspecs&lt;/a&gt; can make this even worse by performing I/O as they&amp;#39;re loaded.
To remedy this use gemsets if you&amp;#39;re using rvm and eliminate unnecessary gems from your system.&lt;/p&gt;

&lt;p&gt;Helpful commands,&lt;/p&gt;

&lt;p&gt;uninstall outdated gems
   gem cleanup&lt;/p&gt;

&lt;p&gt;uninstall ALL THE gems
   gem list | cut -d&amp;quot; &amp;ldquo; -f1 | xargs gem uninstall -aIx&lt;/p&gt;

&lt;h2&gt;script/rails&lt;/h2&gt;

&lt;p&gt;Second, Jesse Storimer &lt;a href="http://jstorimer.com/2011/12/20/rails-and-exec.html"&gt;recommends running ./script/rails&lt;/a&gt; rather than rails itself. For example &lt;code&gt;rails c&lt;/code&gt; becomes &lt;code&gt;./script/rails c&lt;/code&gt;.
This results in a small but worthwhile performance improvement: ruby and gems are not only loaded once.
I&amp;#39;ve created a shell command (tested in bash and zsh) to run script/rails if it exists and rails otherwise (ex. rails new).&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;function rails {
   &lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt; [ -e &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;script/rails&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; ]; &lt;span style="color:#000;font-weight:bold"&gt;then&lt;/span&gt;
      ruby script/rails &lt;span style="color:teal;font-weight:bold"&gt;$@&lt;/span&gt;
   &lt;span style="color:#000;font-weight:bold"&gt;else&lt;/span&gt;
      &lt;span style="color:#D14"&gt;&lt;span style="color:#D14"&gt;`&lt;/span&gt;&lt;span style=""&gt;which rails&lt;/span&gt;&lt;span style="color:#D14"&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span style="color:teal;font-weight:bold"&gt;$@&lt;/span&gt;
   fi
}
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;h2&gt;Living dangerously&lt;/h2&gt;

&lt;p&gt;Another posibilty is using one of the patched ruby interpreters.
&lt;a href="https://gist.github.com/funny-falcon"&gt;funny-falcon&lt;/a&gt; maintains verious performance patches.
Patched interpreters are easily installed with rvm.&lt;/p&gt;

&lt;h2&gt;Upgrade yer rails&lt;/h2&gt;

&lt;p&gt;Finally, upgrade your rails apps to version 3.2 if you haven&amp;#39;t already. Startup time is significantly improved in this version.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.johnhawthorn.com,2011-07-16:/2011/07/work-work-zug-zug/</id>
    <title type="html">Work, work. Zug zug.</title>
    <published>2011-07-16T07:00:00Z</published>
    <updated>2011-07-16T07:00:00Z</updated>
    <link rel="alternate" href="http://www.johnhawthorn.com/2011/07/work-work-zug-zug/"/>
    <content type="html">&lt;p&gt;I wrote a little script to block websites which would destract me from work.
Inspired by &lt;a href="https://github.com/leftnode/get-shit-done"&gt;get-shit-done&lt;/a&gt; and the Orc voices from Warcraft 2.
The script can be called as either &lt;a href="/audio/workwork.wav"&gt;&lt;code&gt;workwork&lt;/code&gt;&lt;/a&gt; or &lt;a href="/audio/readytowork.wav"&gt;&lt;code&gt;readytowork&lt;/code&gt;&lt;/a&gt; to enable the block, and &lt;a href="/audio/workcomplete.wav"&gt;&lt;code&gt;workcomplete&lt;/code&gt;&lt;/a&gt; to unblock the websites. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warning: Contains a list of websites which will waste your time.&lt;/strong&gt;&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
17
18
19
&lt;strong&gt;20&lt;/strong&gt;
21
22
23
24
25
26
27
28
29
&lt;strong&gt;30&lt;/strong&gt;
31
32
33
34
35
36
37
38
39
&lt;strong&gt;40&lt;/strong&gt;
41
42
43
44
45
46
47
48
49
&lt;strong&gt;50&lt;/strong&gt;
51
52
53
54
55
56
57
58
59
&lt;strong&gt;60&lt;/strong&gt;
61
62
63
64
65
66
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span style="color:#34b"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span style="color:#A08;font-weight:bold"&gt;SiteList&lt;/span&gt; = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;%w{&lt;/span&gt;&lt;span style="color:#D14"&gt;
  reddit.com
  news.ycombinator.com
  twitter.com
  plus.google.com
  slashdot.org
  cracked.com
  vimeo.com
  youtube.com
  digg.com
&lt;/span&gt;&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;

&lt;span style="color:#A08;font-weight:bold"&gt;StartToken&lt;/span&gt; = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;## workwork&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#A08;font-weight:bold"&gt;EndToken&lt;/span&gt; = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;## zugzug&lt;/span&gt;&lt;span style="color:#D14"&gt;\n&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;

&lt;span style="color:#A08;font-weight:bold"&gt;HostsFile&lt;/span&gt; = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;/etc/hosts&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#A08;font-weight:bold"&gt;ConfigFile&lt;/span&gt; = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;~/.workwork&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;

&lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;disabled_sites&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#A08;font-weight:bold"&gt;File&lt;/span&gt;.exist?(&lt;span style="color:#A08;font-weight:bold"&gt;ConfigFile&lt;/span&gt;)
    open(&lt;span style="color:#A08;font-weight:bold"&gt;ConfigFile&lt;/span&gt;).read.split(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;\n&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
  &lt;span style="color:#000;font-weight:bold"&gt;else&lt;/span&gt;
    &lt;span style="color:#A08;font-weight:bold"&gt;SiteList&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

&lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;workwork&lt;/span&gt;
  lines = []
  lines &amp;lt;&amp;lt; &lt;span style="color:#A08;font-weight:bold"&gt;StartToken&lt;/span&gt;
  disabled_sites.each &lt;span style="color:#000;font-weight:bold"&gt;do&lt;/span&gt; |site|
    lines &amp;lt;&amp;lt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;127.0.0.1&lt;/span&gt;&lt;span style="color:#D14"&gt;\t&lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;site&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    lines &amp;lt;&amp;lt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;127.0.0.1&lt;/span&gt;&lt;span style="color:#D14"&gt;\t&lt;/span&gt;&lt;span style="color:#D14"&gt;www.&lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;site&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
  lines &amp;lt;&amp;lt; &lt;span style="color:#A08;font-weight:bold"&gt;EndToken&lt;/span&gt;

  open(&lt;span style="color:#A08;font-weight:bold"&gt;HostsFile&lt;/span&gt;, &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;a+&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span style="color:#000;font-weight:bold"&gt;do&lt;/span&gt; |file|
    file.write lines.join(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;\n&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

&lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;workcomplete&lt;/span&gt;
  open(&lt;span style="color:#A08;font-weight:bold"&gt;HostsFile&lt;/span&gt;, &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;r+&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;) &lt;span style="color:#000;font-weight:bold"&gt;do&lt;/span&gt; |file|
    string = file.read
    string.gsub!(&lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;&lt;span style="color:#A08;font-weight:bold"&gt;StartToken&lt;/span&gt;&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#808"&gt;.*&lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;&lt;span style="color:#A08;font-weight:bold"&gt;EndToken&lt;/span&gt;&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#C2C"&gt;m&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;)
    file.seek(&lt;span style=""&gt;0&lt;/span&gt;)
    file.truncate(&lt;span style=""&gt;0&lt;/span&gt;)
    file.write(string)
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

&lt;span style="color:#998;font-style:italic"&gt;# switch to root since we need to change /etc/hosts&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style=""&gt;ENV&lt;/span&gt;[&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;USER&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] != &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;root&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  exec(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;sudo &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;&lt;span style=""&gt;ENV&lt;/span&gt;[&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;_&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;]&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt; &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;&lt;span style=""&gt;ARGV&lt;/span&gt;.join(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt; &lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

&lt;span style="color:#000;font-weight:bold"&gt;case&lt;/span&gt; &lt;span style="color:#A08;font-weight:bold"&gt;File&lt;/span&gt;.basename(&lt;span style="color:teal;font-weight:bold"&gt;$0&lt;/span&gt;)
&lt;span style="color:#000;font-weight:bold"&gt;when&lt;/span&gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;workwork&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;then&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;when&lt;/span&gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;readytowork&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;then&lt;/span&gt;
  workwork
&lt;span style="color:#000;font-weight:bold"&gt;when&lt;/span&gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;workcomplete&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;then&lt;/span&gt;
  workcomplete
&lt;span style="color:#000;font-weight:bold"&gt;else&lt;/span&gt;
  puts &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#D14"&gt;Unknown command&lt;/span&gt;&lt;span style="color:#D14"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Now I just need a script to remove executable permissions from minecraft.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.johnhawthorn.com,2011-07-13:/2011/07/slow-log-on-rds/</id>
    <title type="html">Dealing with the MySQL slow log on Amazon RDS</title>
    <published>2011-07-13T07:00:00Z</published>
    <updated>2011-07-13T07:00:00Z</updated>
    <link rel="alternate" href="http://www.johnhawthorn.com/2011/07/slow-log-on-rds/"/>
    <content type="html">&lt;p&gt;&lt;a href="http://aws.amazon.com/rds/"&gt;Amazon RDS&lt;/a&gt; is a web service offered by amazon which provides users with MySQL databases in the cloud. It&amp;#39;s an attractive service due to its convenient backups and easy replication.&lt;/p&gt;

&lt;p&gt;Amazon doesn&amp;#39;t provide shell access to RDS instances. For this reason, the &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html"&gt;slow query log&lt;/a&gt;, which is an invaluable tool for anyone with a somewhat large or complex data set, is not available in the traditional way. Amazon, however, does provide a method for enabling and retrieving the log.&lt;/p&gt;

&lt;h2&gt;Setup&lt;/h2&gt;

&lt;p&gt;To enable the slow query log on RDS, you should create or modify a DB parameter group which can be done from the AWS management console (online interface) or through various other tools.
There are two attributes that should be changed, &lt;code&gt;slow_query_log&lt;/code&gt;, which should be set to &lt;code&gt;1&lt;/code&gt; to enable, and &lt;code&gt;long_query_time&lt;/code&gt;, which should be set to the shortest length to be considered a slow query.&lt;/p&gt;

&lt;p&gt;The slow query log is stored in the table &lt;code&gt;mysql.slow_log&lt;/code&gt;. Rotating the slow query log is done by calling the stored procedure &lt;code&gt;CALL rds_rotate_slow_log&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Accessing&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Update:&lt;/em&gt;
this script is now available as a gem: &lt;a href="https://rubygems.org/gems/rds_slow_log"&gt;rds_slow_log&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve written a little ruby script to print out the slow log in the usual format. From this it can be read, or analyzed with tools like &lt;a href="https://github.com/wvanbergen/request-log-analyzer"&gt;request-log-analyzer&lt;/a&gt;.&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
17
18
19
&lt;strong&gt;20&lt;/strong&gt;
21
22
23
24
25
26
27
28
29
&lt;strong&gt;30&lt;/strong&gt;
31
32
33
34
35
36
37
38
39
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;rubygems&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
require &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;active_record&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;

&lt;span style="color:#000;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#458;font-weight:bold"&gt;SlowLog&lt;/span&gt; &amp;lt; &lt;span style="color:#A08;font-weight:bold"&gt;ActiveRecord&lt;/span&gt;::&lt;span style="color:#A08;font-weight:bold"&gt;Base&lt;/span&gt;
  set_table_name &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;slow_log&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;

  &lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;query_time&lt;/span&gt;
    time_parse query_time_before_type_cast
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;lock_time&lt;/span&gt;
    time_parse lock_time_before_type_cast
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;to_s&lt;/span&gt;
      &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;lt;&amp;lt;EOS&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;
# Time: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;start_time.strftime(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;%y%m%d %H:%M:%S&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;
# User@Host: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;user_host&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;
# Query_time: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;query_time&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;  Lock_time: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;lock_time&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;  Rows_sent: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;rows_sent&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;  Rows_examined: &lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;rows_examined&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;
&lt;/span&gt;&lt;span style="color:black"&gt;&lt;span style="color:#D14"&gt;#{&lt;/span&gt;sql_text&lt;span style="color:#D14"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D14"&gt;;&lt;/span&gt;&lt;span style="color:#D14"&gt;
EOS&lt;/span&gt;&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

  &lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style=""&gt;self&lt;/span&gt;.&lt;span style="color:#900;font-weight:bold"&gt;print_all&lt;/span&gt;
    find(&lt;span style="color:#990073"&gt;:all&lt;/span&gt;, &lt;span style="color:#990073"&gt;:order&lt;/span&gt; =&amp;gt; &lt;span style="color:#990073"&gt;:start_time&lt;/span&gt;).each &lt;span style="color:#000;font-weight:bold"&gt;do&lt;/span&gt; |query|
      puts query
    &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

  private
  &lt;span style="color:#000;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#900;font-weight:bold"&gt;time_parse&lt;/span&gt; string
    hours, minutes, seconds = string.to_s.split(&lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#808"&gt;:&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt;)
    hours.to_i * &lt;span style=""&gt;60&lt;/span&gt; * &lt;span style=""&gt;60&lt;/span&gt; + minutes.to_i * &lt;span style=""&gt;60&lt;/span&gt; + seconds.to_i
  &lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;
&lt;span style="color:#000;font-weight:bold"&gt;end&lt;/span&gt;

&lt;span style="color:#A08;font-weight:bold"&gt;ActiveRecord&lt;/span&gt;::&lt;span style="color:#A08;font-weight:bold"&gt;Base&lt;/span&gt;.establish_connection &lt;span style="color:#990073"&gt;:adapter&lt;/span&gt;  =&amp;gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;mysql&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;,
                                        &lt;span style="color:#990073"&gt;:database&lt;/span&gt; =&amp;gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;mysql&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;,
                                        &lt;span style="color:#990073"&gt;:username&lt;/span&gt; =&amp;gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;username&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;,
                                        &lt;span style="color:#990073"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;password&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#A08;font-weight:bold"&gt;SlowLog&lt;/span&gt;.print_all
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This was written to be compatible with both activerecord 2.3 and 3.0. If compatability with 2.3 were to be dropped, the &lt;code&gt;time_parse&lt;/code&gt; hacks could be removed.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:www.johnhawthorn.com,2011-07-04:/2011/07/introducing-dkim-gem/</id>
    <title type="html">Introducing the dkim gem</title>
    <published>2011-07-04T07:00:00Z</published>
    <updated>2011-07-04T07:00:00Z</updated>
    <link rel="alternate" href="http://www.johnhawthorn.com/2011/07/introducing-dkim-gem/"/>
    <content type="html">&lt;p&gt;DKIM (defined in &lt;a href="http://tools.ietf.org/html/rfc4871"&gt;RFC 4871&lt;/a&gt;) is a way for email senders to claim responsibility for an email message.
It works by adding an extra header to every email sent which cryptographically signs the message&amp;#39;s headers and body.
By verifying the signature, the receiver of DKIM-signed email can be certain the emails content has been unaltered and comes from who is claimed.
By taking responsibility for these messages, the sender&amp;#39;s reputation can allow the message to be less scrutinized by spam/phishing filters on the receivers end.
For this reason, DKIM is desirable because is should increase deliverability.&lt;/p&gt;

&lt;p&gt;I had the need to send a large amount of email through &lt;a href="http://aws.amazon.com/ses/"&gt;Amazon SES&lt;/a&gt; from a rails application.
This was made very easy by the terrific &lt;a href="http://fog.io/"&gt;fog&lt;/a&gt; library for accessing cloud services (I would recommend version 0.8.2 or above, which includes a bug fix I submitted).
However I found no good way to DKIM sign email from ruby. There was a rubydkim gem, but it didn&amp;#39;t work correctly in my testing, and required an external C library.&lt;/p&gt;

&lt;p&gt;This prompted me to create the &lt;em&gt;&lt;a href="https://github.com/jhawthorn/dkim"&gt;dkim&lt;/a&gt;&lt;/em&gt; gem: a simple ruby library for DKIM signing email messages.
dkim depends only on ruby built with openssl support (or jruby-openssl if you&amp;#39;re using jruby).&lt;/p&gt;

&lt;p&gt;Most basic usage (which should be all that is necessary for most) is to configure the gem globally&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span style="color:#A08;font-weight:bold"&gt;Dkim&lt;/span&gt;::domain      = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;example.com&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#A08;font-weight:bold"&gt;Dkim&lt;/span&gt;::selector    = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;mail&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#A08;font-weight:bold"&gt;Dkim&lt;/span&gt;::private_key = open(&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;span style="color:#D14"&gt;private.pem&lt;/span&gt;&lt;span style="color:#D14"&gt;'&lt;/span&gt;&lt;/span&gt;).read
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;and then to sign any messages as needed&lt;/p&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1
2
3
4
5
6
7
8
9
&lt;strong&gt;10&lt;/strong&gt;
11
12
13
14
15
16
17
18
19
&lt;strong&gt;20&lt;/strong&gt;
&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;mail = &lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;&amp;lt;&amp;lt;eos&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#D20"&gt;&lt;span style="color:#D14"&gt;
To: someone@example.com
From: john@example.com
Subject: hi

Howdy&lt;/span&gt;&lt;span style="color:#D14"&gt;
eos&lt;/span&gt;&lt;/span&gt;

&lt;span style="color:#A08;font-weight:bold"&gt;Dkim&lt;/span&gt;.sign(mail)
&lt;span style="color:#998;font-style:italic"&gt;# =&amp;gt;&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# To: someone@example.com&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# From: john@example.com&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# Subject: hi&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; q=dns/txt; s=mail; t=1305917829;&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;#   bh=qZxwTnSM1ywsrq0Ag9UhQSOtVIG+sW5zDkB+hPbuX08=; h=from:subject:to;&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;#   b=0mKnNOkxFGiww63Zu4t46J7eZc3Uak3I9km3IH2Le3XcnSNtWJgxiwBX26IZ5yzcT&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;#   VwJzcCnPKCScIJMQ7yfbfXmNsKVIOV6eSUqu1YvJ1fgzlSAXuDEMNFTjoto5rrdA+&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;#   BgX849hEY/bWHDl1JJgNpiwtpl4t0Q7M4BVJUd7Lo=&lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# &lt;/span&gt;
&lt;span style="color:#998;font-style:italic"&gt;# Howdy&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;A more detailed explanation can be found in the project&amp;#39;s &lt;a href="https://github.com/jhawthorn/dkim/blob/master/README.md"&gt;README&lt;/a&gt; on github.&lt;/p&gt;

&lt;p&gt;I hope the library proves useful to others, and would love to hear from anyone using it.&lt;/p&gt;

&lt;h4&gt;links&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://github.com/jhawthorn/dkim"&gt;github project&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rubygems.org/gems/dkim"&gt;rubygems page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
</content>
  </entry>
</feed>

