<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns: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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Mike Perham</title>
	
	<link>http://www.mikeperham.com</link>
	<description>On Ruby, software and the Internet</description>
	<lastBuildDate>Sun, 06 May 2012 14:36:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mikeperham" /><feedburner:info uri="mikeperham" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Five Common Rails Mistakes</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/ti2Np0qTxcc/</link>
		<comments>http://www.mikeperham.com/2012/05/05/five-common-rails-mistakes/#comments</comments>
		<pubDate>Sun, 06 May 2012 03:01:16 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=833</guid>
		<description><![CDATA[I&#8217;ve worked with Rails for quite a while now and in that time I&#8217;ve seen a lot of Rails applications and both read and written a lot of bad Ruby code. Here&#8217;s five common mistakes that I see in almost every Rails codebase. 1. Migrations with no schema specifics Your data model is the core [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve worked with Rails for quite a while now and in that time I&#8217;ve seen a lot of Rails applications and both read and written a lot of bad Ruby code.  Here&#8217;s five common mistakes that I see in almost every Rails codebase.<br />
<span id="more-833"></span></p>
<p><strong>1. Migrations with no schema specifics</strong></p>
<p>Your data model is the core of your application.  Without schema constraints, your data will slowly corrode due to bugs in your codebase until you can&#8217;t depend on any fields being populated.  Here&#8217;s a Contact schema:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  create_table <span style="color:#996600;">&quot;contacts&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#CC0066; font-weight:bold;">integer</span>  <span style="color:#996600;">&quot;user_id&quot;</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;name&quot;</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;phone&quot;</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;email&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>What is required?  Presumably a Contact must belong_to a User and have a name &mdash; use database constraints to guarantee this.  By adding <code>:null => false</code>, we ensure that the model is always consistent even if we have bugs in our validation because the database will not allow a model to be saved if it fails those constraints.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  create_table <span style="color:#996600;">&quot;contacts&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#CC0066; font-weight:bold;">integer</span>  <span style="color:#996600;">&quot;user_id&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:null</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;name&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:null</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;phone&quot;</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;email&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>Bonus points</strong>: use <code>:limit => N</code> to size your string columns appropriately.  Strings default to 255 characters and phone probably doesn&#8217;t need to be that big, does it?</p>
<p><strong>2. Object-Oriented Programming</strong></p>
<p>Most Rails developers do not write object-oriented Ruby code.  They write MVC-oriented Ruby code by putting models and controllers in the expected locations.  Most will add utility modules with class-methods in lib/, but that&#8217;s it.  It takes 2-3 years before developers realize: &#8220;Rails is just Ruby.  I can create simple objects and compose them in ways that Rails does not explicitly endorse!&#8221;</p>
<p><strong>Bonus points</strong>: introduce facades for any 3rd-party services you call.  Provide a mock facade for use in your tests so that you don&#8217;t actually call the 3rd party service in your test suite.</p>
<p><strong>3. Concatenating HTML in helpers</strong></p>
<p>If you are creating helper methods, kudos, at least you trying to keep your view layer clean.  But developers often don&#8217;t know the basics of creating tags within helpers, leading to messy string concatenation or interpolation:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">str = <span style="color:#996600;">&quot;&lt;li class='vehicle_list'&gt; &quot;</span>
str <span style="color:#006600; font-weight:bold;">+</span>= link_to<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{vehicle.title.upcase} Sale&quot;</span>, show_all_styles_path<span style="color:#006600; font-weight:bold;">&#40;</span>vehicle.<span style="color:#9900CC;">id</span>, vehicle.<span style="color:#9900CC;">url_title</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
str <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#996600;">&quot; &lt;/li&gt;&quot;</span>
str.<span style="color:#9900CC;">html_safe</span></pre></div></div>

<p>Yikes, it&#8217;s ugly and can easily lead to XSS security holes!  <code>content_tag</code> is your friend.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">content_tag <span style="color:#ff3333; font-weight:bold;">:li</span>, <span style="color:#ff3333; font-weight:bold;">:class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'vehicle_list'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  link_to<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{vehicle.title.upcase} Sale&quot;</span>, show_all_styles_path<span style="color:#006600; font-weight:bold;">&#40;</span>vehicle.<span style="color:#9900CC;">id</span>, vehicle.<span style="color:#9900CC;">url_title</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>Bonus points</strong>: start introducing helper methods that take blocks.  Nested blocks are a natural fit when generating nested HTML.</p>
<p><strong>4. Giant queries loading everything into memory</strong></p>
<p>You need to fix some data so you&#8217;ll just iterate through it all and fix it, right?</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">has_purchased</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>customer<span style="color:#006600; font-weight:bold;">|</span>
  customer.<span style="color:#9900CC;">grant_role</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:customer</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You have an ecommerce site with a million customers.  Let&#8217;s say each User object takes 500 bytes.  This code will take 500MB of memory at runtime!  Better:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">User.<span style="color:#9900CC;">has_purchased</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">find_each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>customer<span style="color:#006600; font-weight:bold;">|</span>
  customer.<span style="color:#9900CC;">grant_role</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:customer</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><code>find_each</code> uses <code>find_in_batches</code> to pull in 1000 records at a time, dramatically lowering the runtime memory requirements.</p>
<p><strong>Bonus points</strong>: use update_all or raw SQL to perform the mass update.  SQL takes time to learn well but the benefits are even more tremendous: you&#8217;ll see a 100x improvement in the performance.</p>
<p><strong>5. Code review!</strong></p>
<p>I&#8217;m guessing you are using GitHub and I&#8217;m also guessing you aren&#8217;t using pull requests.  If you spend a day or two building a feature, do it on a branch and send a pull request.  Your team will be able to review your code, offer suggestions for improvement and possible edge cases that you didn&#8217;t consider.  I guarantee your code will be higher quality for it.  We&#8217;ve switched to using pull requests for 90% of our changes at <a href="http://www.theclymb.com/invite-from/mperham">TheClymb</a> and it&#8217;s been a 100% positive experience.</p>
<p><strong>Bonus points</strong>: Don&#8217;t merge pull requests without tests for at least the happy path.  Testing is invaluable to keep your application stable and your sleep peaceful.</p>
<p>Did I miss any common issues?  Leave a comment and let me know!</p>
<p>Update: use find_each rather than find_in_batches, thanks readers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/05/05/five-common-rails-mistakes/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/05/05/five-common-rails-mistakes/</feedburner:origLink></item>
		<item>
		<title>One Quarter of Sidekiq</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/77dTAIzh0EQ/</link>
		<comments>http://www.mikeperham.com/2012/05/01/one-quarter-of-sidekiq/#comments</comments>
		<pubDate>Wed, 02 May 2012 03:34:02 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=824</guid>
		<description><![CDATA[It&#8217;s been about three months since I released Sidekiq. Let&#8217;s get to the numbers: 668 GitHub watchers 171 issues, 11 open 7 commercial licenses purchased! 54 pull requests with 30+ different developers! 1 EngineYard podcast interview 1 RailsConf lightning talk by @jwo 1 South African Ruby group talk on Sidekiq! 1 new license (LGPL rather [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been about three months since I released <a href="https://github.com/mperham/sidekiq">Sidekiq</a>.  Let&#8217;s get to the numbers:</p>
<ul>
<li>668 GitHub watchers</li>
<li>171 issues, 11 open</li>
<li>7 commercial licenses purchased!</li>
<li>54 pull requests with 30+ different developers!</li>
<li>1 <a href="http://www.engineyard.com/podcast/sidekiq-the-clymb-motorcycles">EngineYard podcast interview</a></li>
<li>1 RailsConf lightning talk by @jwo</li>
<li>1 South African Ruby group talk on Sidekiq!</li>
<li>1 new license (LGPL rather than GPL)</li>
<li>0 locks in the multithreaded codebase</li>
</ul>
<p>I consider that a success; I&#8217;ve never had a project grow this fast with just my own promotion and community word of mouth.  <a href="https://www.theclymb.com/invite-from/mperham">TheClymb</a> switched to Sidekiq last week and our biggest problem so far has been that Sidekiq can be <strong>too parallel</strong> and crush servers with traffic; we&#8217;ve had to rewrite some jobs to be serial!</p>
<p>My goals remain the same:</p>
<ul>
<li>Provide the easiest and best supported queueing system for Ruby.</li>
<li>Be the first Rubygem people mention or consider when choosing a queueing system</li>
<li>Improve Ruby&#8217;s overall efficiency and perceived performance through multi-threading.</li>
<li>Evangelize multi-threaded infrastructure written with actor abstractions as relatively straightforward for knowledgable developers to build.  <a href="https://github.com/celluloid/celluloid">Celluloid</a> continues to be a huge asset to Sidekiq&#8217;s ease of development and stability.</li>
</ul>
<p>Thank you all for your support so far!  Thank you especially to EngineYard, Tony Arcieri and the early adopters that have made hacking on Sidekiq an exciting adventure rather than a lonely chore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/05/01/one-quarter-of-sidekiq/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/05/01/one-quarter-of-sidekiq/</feedburner:origLink></item>
		<item>
		<title>Don’t Mistake Meetings for Process</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/G2R3iX5AOoA/</link>
		<comments>http://www.mikeperham.com/2012/04/08/dont-mistake-meetings-for-process/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 19:02:26 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=810</guid>
		<description><![CDATA[I&#8217;ve joined several teams over the last few years, including one or two that effectively had no development process. Even with the smartest engineers in the world, the latter always show the same symptoms: You have no idea what your coworkers are working on right now. You don&#8217;t know what you will be working on [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve joined several teams over the last few years, including one or two that effectively had no development process.  Even with the smartest engineers in the world, the latter always show the same symptoms:</p>
<ul>
<li>You have no idea what your coworkers are working on right now.</li>
<li>You don&#8217;t know what you will be working on next week.</li>
</ul>
<p>Does this sound like your team?  The problem is almost always the same: <strong>lack of communication</strong>.  The point of development process is simple: <strong>ensure team communication</strong>.  The simplest effective development process for your team ensures that everyone is in sync about the present and near-future goals for the team.</p>
<p>Process gets a bad reputation because often meetings are used as a substitute for process.  Since lack of communication is the problem, we should just throw everyone in a room together to talk, right?  Good, high-bandwidth meetings can be very useful but just as important are tools which allow the team to communicate on their own schedule (think issue trackers, code review tools, group chat, a pinboard with index cards, etc).  Your process should be a mixture of synchronous, high-bandwidth meetings and asynchronous, low-bandwidth tools.  There&#8217;s no right mixture but your process must have two mandatory properties:</p>
<ol>
<li>Everyone must sign off on it as &#8220;the way&#8221;.</li>
<li>Everyone must actually follow it.</li>
</ol>
<p>I generally try for two team meetings per week: a Monday morning sync about upcoming work for this week and next week and Friday afternoon demo of work accomplished that week (the demo almost always finds bugs and issues to be fixed next week).  Monday morning kicks the work week into high gear and Friday afternoon winds down the work so everyone can enjoy their weekend.</p>
<p>Great, which process should you use?  Agile, XP, Scrum, Kanban?  I treat them like web frameworks: pick one, learn it well and modify it as necessary for your own needs.  The one booklet that I keep going back to year after year is this <a href="http://www.infoq.com/minibooks/scrum-xp-from-the-trenches">booklet on Scrum and XP practices offered by InfoQ</a>.  It&#8217;s a very practical, quick read and low tech enough that you can implement it in 2007 or 2017.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/04/08/dont-mistake-meetings-for-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/04/08/dont-mistake-meetings-for-process/</feedburner:origLink></item>
		<item>
		<title>Converting a MySQL database from Latin1 to UTF8</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/xpwLFr8mrmk/</link>
		<comments>http://www.mikeperham.com/2012/03/31/converting-a-mysql-database-from-latin1-to-utf8/#comments</comments>
		<pubDate>Sat, 31 Mar 2012 14:27:51 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=792</guid>
		<description><![CDATA[We had a problem at TheClymb: our database and tables were created with the default Latin1 encoding. Now all of the data in those tables is actually UTF8 because it was all imported via the web browser (which defaults to UTF8) and MySQL doesn&#8217;t actually validate or convert data encoding when inserting. A suggestion was [...]]]></description>
			<content:encoded><![CDATA[<p>We had a problem at <a href="http://www.theclymb.com/invite-from/mperham">TheClymb</a>: our database and tables were created with the default Latin1 encoding.  Now all of the data in those tables is actually UTF8 because it was all imported via the web browser (which defaults to UTF8) and MySQL doesn&#8217;t actually validate or convert data encoding when inserting.</p>
<p>A suggestion was to just set this in an initializer:<br />
<code><br />
Mysql2::Client::CHARSET_MAP['latin1'] = Encoding::UTF_8<br />
</code></p>
<p>This will solve your problems in Ruby but will not solve your problems in the database: MySQL will still sort and compare strings thinking they are latin1 and thus do so incorrectly.  Here&#8217;s an example:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> names_latin1 <span style="color: #66cc66;">&#40;</span>name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span> character <span style="color: #993333; font-weight: bold;">SET</span> latin1<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_latin1 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Strauße'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_latin1 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Straure'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_latin1 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Strausse'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_latin1 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Straute'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> names_utf8 <span style="color: #66cc66;">&#40;</span>name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span> character <span style="color: #993333; font-weight: bold;">SET</span> utf8<span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_utf8 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Strauße'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_utf8 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Straure'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_utf8 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Strausse'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> names_utf8 <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Martin Straute'</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>I&#8217;m not a linguist but to the best of my knowledge the German ß is essentially &#8220;ss&#8221;.  When we ask MySQL to sort our names, you can see that the UTF-8 results put the ß character between &#8220;r&#8221; and &#8220;ss&#8221; but the Latin1 results don&#8217;t.  If a German were to see this, they would be enraged due to your culturally insensitive code!<br />
<code><br />
> select * from names_latin1 order by name;<br />
+-----------------+<br />
| name            |<br />
+-----------------+<br />
| Martin Straure  |<br />
| Martin Strausse |<br />
| Martin Straute  |<br />
| Martin Strauße  |<br />
+-----------------+<br />
</code><br />
<code><br />
> select * from names_utf8 order by name;<br />
+-----------------+<br />
| name            |<br />
+-----------------+<br />
| Martin Straure  |<br />
| Martin Strauße  |<br />
| Martin Strausse |<br />
| Martin Straute  |<br />
+-----------------+<br />
</code></p>
<p>We need to update the CHARACTER SET without doing any conversion of the data.  This is simple to do: you convert the columns to a blob format and then convert them back to a string format with the proper encoding declared; MySQL will not do any conversion of raw binary data.  For example:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> categories CHARACTER <span style="color: #993333; font-weight: bold;">SET</span> utf8 COLLATE utf8_unicode_ci<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CHANGE</span> title title VARBINARY<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> categories <span style="color: #993333; font-weight: bold;">CHANGE</span> title title VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> CHARACTER <span style="color: #993333; font-weight: bold;">SET</span> utf8 COLLATE utf8_unicode_ci</pre></div></div>

<p>With this in mind, I wrote a rake task to convert our application&#8217;s database.  Here&#8217;s the full script in a <a href="https://gist.github.com/2045565">Github Gist</a>.  You&#8217;ll need to run it with a <code>DOIT</code> parameter to actually make the changes otherwise it will just print the SQL it will run to the terminal.  The script will take a long time for large databases since it has to ALTER TABLE, which means MySQL will write out the table to disk in full; the script does minimize the number of ALTER TABLEs it runs to two per table.<br />
<code><br />
rake convert_to_utf8 DOIT=1<br />
</code></p>
<p>So please think of the Germans and the rest of our international friends: converting the character set of your database to the proper value is important to get correct sorting of results.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/03/31/converting-a-mysql-database-from-latin1-to-utf8/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/03/31/converting-a-mysql-database-from-latin1-to-utf8/</feedburner:origLink></item>
		<item>
		<title>The Perils of “rescue Exception”</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/SWj5pDQ2Hec/</link>
		<comments>http://www.mikeperham.com/2012/03/03/the-perils-of-rescue-exception/#comments</comments>
		<pubDate>Sat, 03 Mar 2012 16:47:42 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=788</guid>
		<description><![CDATA[Ruby&#8217;s standard exception handling looks like this. begin do_something rescue =&#62; ex # do something with the error end This will catch all StandardErrors and its subclasses. A frequent issue I see in Ruby code is this: begin do_something rescue Exception =&#62; ex # Apparently I REALLY want to make sure this block # won't [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby&#8217;s standard exception handling looks like this.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">begin</span>
    do_something
  <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ex
    <span style="color:#008000; font-style:italic;"># do something with the error</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This will catch all StandardErrors and its subclasses.  A frequent issue I see in Ruby code is this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">begin</span>
    do_something
  <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ex
    <span style="color:#008000; font-style:italic;"># Apparently I REALLY want to make sure this block </span>
    <span style="color:#008000; font-style:italic;"># won't interfere will the outside code.</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This is a BAD, BAD idea, dear reader, and here&#8217;s why.  Ruby uses Exceptions for other things than your application code errors.  One example is the Interrupt class which is a SignalException.  Ruby sends this Exception to all threads so that when the process gets an INT/Ctrl-C signal, all the threads will unwind and the process will shutdown.  If you rescue Exception, you will potentially catch this exception and ignore it, making your thread and process an unkillable computing zombie.  Your only choice will be to pull out your kill -9 shotgun and aim for the head.</p>
<p>Here&#8217;s an example of a Ruby script you cannot shutdown gracefully.  Run it and you&#8217;ll see exactly the behavior I&#8217;ve described.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#9966CC; font-weight:bold;">begin</span>
    <span style="color:#CC0066; font-weight:bold;">sleep</span> <span style="color:#006666;">5</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'ping'</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ex
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Mmmmm, brains&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So remember, your application errors should be subclasses of StandardError and if you want to catch everything, just stick will plain old &#8220;rescue => ex&#8221;.  Your application will behave better for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/03/03/the-perils-of-rescue-exception/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/03/03/the-perils-of-rescue-exception/</feedburner:origLink></item>
		<item>
		<title>Deleting Duplicate Rows in MySQL</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/6_5IbN9TLXo/</link>
		<comments>http://www.mikeperham.com/2012/03/02/deleting-duplicate-rows-in-mysql/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 16:48:15 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=782</guid>
		<description><![CDATA[You have a table with duplicate rows &#8211; somehow a unique index didn&#8217;t get created and a bug has added duplicate records to your table. A pox upon that bug! Here&#8217;s two easy ways to clean out that table quickly. 1) Use ALTER IGNORE on MySQL 5.1+ MySQL will allow you to create a unique [...]]]></description>
			<content:encoded><![CDATA[<p>You have a table with duplicate rows &#8211; somehow a unique index didn&#8217;t get created and a bug has added duplicate records to your table.  A pox upon that bug!</p>
<p>Here&#8217;s two easy ways to clean out that table quickly.</p>
<p>1) Use ALTER IGNORE on MySQL 5.1+</p>
<p>MySQL will allow you to create a unique index on a table with duplicate records with its IGNORE SQL extension:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">IGNORE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">'SHIPMENTS'</span> <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">UNIQUE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> <span style="color: #66cc66;">&#40;</span>CART_ID<span style="color: #66cc66;">,</span> TRACKING_NUMBER<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Duplicates will be deleted.</p>
<p>2) Recreate the table with GROUP BY</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    execute <span style="color:#996600;">'CREATE TABLE shipments_deduped like shipments;'</span>
    execute <span style="color:#996600;">'INSERT shipments_deduped SELECT * FROM shipments GROUP BY cart_id, tracking_number;'</span>
    execute <span style="color:#996600;">'RENAME TABLE shipments TO shipments_with_dupes;'</span>
    execute <span style="color:#996600;">'RENAME TABLE shipments_deduped TO shipments;'</span>
    add_index <span style="color:#ff3333; font-weight:bold;">:shipments</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:cart_id</span>, <span style="color:#ff3333; font-weight:bold;">:tracking_number</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:unique</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
    execute <span style="color:#996600;">'DROP TABLE shipments_with_dupes;'</span></pre></div></div>

<p>Recreating the table is much, much faster than trying to delete the records in the existing table and doesn&#8217;t lock the existing table, making your application downtime minimal.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/03/02/deleting-duplicate-rows-in-mysql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/03/02/deleting-duplicate-rows-in-mysql/</feedburner:origLink></item>
		<item>
		<title>The State of Sidekiq – One Month Later</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/QeReaPpMvDw/</link>
		<comments>http://www.mikeperham.com/2012/03/02/the-state-of-sidekiq-one-month-later/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 16:13:50 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=778</guid>
		<description><![CDATA[I released Sidekiq about one month ago and the take up so far has been amazing. Some stats: 462 watchers 66 issues opened so far. Three contributors earned commit rights. One commercial license purchased! Approximately one pull request per day, far better than any of my previous projects. I&#8217;ve chatted with two different people running [...]]]></description>
			<content:encoded><![CDATA[<p>I released <a href="http://mperham.github.com/sidekiq">Sidekiq</a> about one month ago and the take up so far has been amazing.  Some stats:</p>
<ul>
<li>462 watchers</li>
<li>66 issues opened so far.</li>
<li>Three contributors earned commit rights.</li>
<li>One commercial license purchased!</li>
<li>Approximately one pull request per day, far better than any of my previous projects.</li>
</ul>
<p>I&#8217;ve chatted with two different people running Sidekiq in production and their experience has been the same:</p>
<ul>
<li>&#8220;I&#8217;m expecting to save $2000/month in worker boxes moving from delayed_job to Sidekiq.&#8221;</li>
<li>&#8220;I&#8217;ve gone from 160 worker dynos to 10 dynos, saving over $5000/month.&#8221;</li>
</ul>
<p>Astounding, all in the first month for a one man OSS project.  If you use Sidekiq in production, please email me (mperham AT gmail) and tell me your success story!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/03/02/the-state-of-sidekiq-one-month-later/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/03/02/the-state-of-sidekiq-one-month-later/</feedburner:origLink></item>
		<item>
		<title>Sidekiq – simple, efficient messaging for Rails</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/B-mU7tzCF-0/</link>
		<comments>http://www.mikeperham.com/2012/02/07/sidekiq-simple-efficient-messaging-for-rails/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 07:10:54 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=772</guid>
		<description><![CDATA[I introduced my latest project, Sidekiq, this morning. Sidekiq is the culmination of several years of research and development into message processing with Ruby. I first wrote a single-threaded mysql-backed queue called QBert for FiveRuns in 2008 before delayed_job was introduced. Next I wrote a single-threaded SQS-based processor called Jobber and then a Fiber-based, RabbitMQ-backed [...]]]></description>
			<content:encoded><![CDATA[<p>I introduced my latest project, <a href="http://mperham.github.com/sidekiq">Sidekiq</a>, this morning.  Sidekiq is the culmination of several years of research and development into message processing with Ruby.  I first wrote a single-threaded mysql-backed queue called QBert for FiveRuns in 2008 before delayed_job was introduced.  Next I wrote a single-threaded SQS-based processor called Jobber and then a Fiber-based, RabbitMQ-backed processor called Qanat for OneSpot.  Most recently I wrote <a href="http://mperham.github.com/girl_friday">girl_friday</a>, an Actor-based, redis-backed processor and a custom multi-threaded version of Resque for a Carbon Five client.</p>
<p>So yeah, messaging and I have a history but I think that&#8217;s because Ruby still doesn&#8217;t have a simple, scalable option for message processing.  Sidekiq is my attempt to solve that need.</p>
<p><strong>Simple</strong></p>
<p>Sidekiq integrates tightly with Rails 3 so your application&#8217;s worker code is nearby and easy for Sidekiq to find and load.  I&#8217;d like to support plain Ruby applications but I need a replacement for the nice integration Rails 3 gives me.</p>
<p><strong>Efficient</strong></p>
<p>Sidekiq uses multiple threads so you can process hundreds of messages in parallel if you desire without the overhead of hundreds of processes.  Internally Sidekiq uses the Celluloid actor library to make threading easier and safer to manage.</p>
<p><strong>Developer Friendly</strong></p>
<p>I&#8217;ve tried to make Sidekiq developer friendly in two ways:</p>
<ul>
<li>Resque-compatible &#8211; I love conventions, why reinvent the wheel when you can stick closely to what someone else has done and leverage that work?  I aim to make Sidekiq easy to integrate into an existing Resque project and monitorable via resque-ui.</li>
<li>Middleware &#8211; Sidekiq pulls in a middleware API similar to Rack for running code before/after/around a processed message and ships with middleware that helps with ActiveRecord and Airbrake.</li>
</ul>
<p><strong>Licensing</strong></p>
<p>Sidekiq is an experiment in one regard: licensing.  I&#8217;ve decided to license Sidekiq under the GPLv3 for free or a commercial license for a $50 pledge at <a href="http://pledgie.com/campaigns/16623">my Pledgie page</a>.  During my time as a Ruby consultant, $50 would get you less than 20 minutes of my time.  I hope you think this is a reasonable price.</p>
<p>Please let me know how you like Sidekiq &#8211; I love hearing stories about how people are using it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/02/07/sidekiq-simple-efficient-messaging-for-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/02/07/sidekiq-simple-efficient-messaging-for-rails/</feedburner:origLink></item>
		<item>
		<title>I’m back!</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/Rg2k0WSvQgI/</link>
		<comments>http://www.mikeperham.com/2012/02/04/im-back/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 05:40:33 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=767</guid>
		<description><![CDATA[I haven&#8217;t blogged much for the last year because most of my technical blogging went to the Carbon Five blog. Now that I&#8217;ve moved to Portland and have a new job at TheClymb I&#8217;ll be returning my attention to my own blog so expect new content regularly again!]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t blogged much for the last year because most of my technical blogging went to the <a href="http://blog.carbonfive.com">Carbon Five blog</a>.  Now that I&#8217;ve moved to Portland and have a new job at <a href="http://www.theclymb.com/invite-from/mperham">TheClymb</a> I&#8217;ll be returning my attention to my own blog so expect new content regularly again!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2012/02/04/im-back/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2012/02/04/im-back/</feedburner:origLink></item>
		<item>
		<title>Getting iChat to automatically reconnect</title>
		<link>http://feedproxy.google.com/~r/mikeperham/~3/fw6t-mAJHmo/</link>
		<comments>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 04:32:50 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.mikeperham.com/?p=757</guid>
		<description><![CDATA[I&#8217;ve noticed a problem with iChat for the last year or two: if your network drops, you stay Disconnected until you manually tell iChat to log back in. That&#8217;s pretty lame, my Comcast cable drops several times a day so I need something a little more robust than that. I found a workaround: use cron [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve noticed a problem with iChat for the last year or two: if your network drops, you stay Disconnected until you manually tell iChat to log back in.  That&#8217;s pretty lame, my Comcast cable drops several times a day so I need something a little more robust than that.  I found a workaround: use cron to do the work for you. Fire up a Terminal, run <code>crontab -e</code> and put this in it:</p>
<pre>
*/5 * * * * osascript -e 'tell application "System Events" to if (processes whose name is "iChat") exists then tell application "iChat" to log in'
</pre>
<p>This uses AppleScript to tell iChat to log in every 5 minutes.  Now if the network drops, you&#8217;ll only be disconnected a few minutes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.mikeperham.com/2011/12/30/getting-ichat-to-automatically-reconnect/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.580 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-09 18:29:27 -->

