<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>dickey.xxx</title>
  
  <link href="http://dickeyxxx.com/" />
  <id>http://dickeyxxx.com/</id>
  <updated>2013-04-14T00:00:00Z</updated>
  <author>
    <name>Jeff Dickey</name>
    <email>me@jeffdickey.info</email>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/jeffdickey" /><feedburner:info uri="jeffdickey" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>After coaching a Rails Girls, I can finally answer the question "Why do I love programming?"</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/B8D76P-_yIQ/why-do-i-love-programming" />
    <id>http://dickey.xxx/why-do-i-love-programming</id>
    <updated>2013-04-14T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;After coaching a Rails Girls, I can finally answer the question "Why do I love programming?"&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/52/image/railsgirlsfbpiccropped-3ab1978de3026732ce9189cc1ffedfca.jpeg' /&gt;&lt;p&gt;Yesterday I coached a &lt;a href="http://www.railsgirls.com/la"&gt;Rails Girls&lt;/a&gt; event in Santa Monica. For those that aren&amp;#39;t familiar, here is a description of the program in their own words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our aim is to give tools and a community for women to understand technology and to build their ideas. We do this by providing a great experience on building things and by making technology more approachable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I&amp;#39;ve done a few of these events such as &lt;a href="http://workshops.railsbridge.org/"&gt;RailsBridge&lt;/a&gt; and &lt;a href="http://calruby.eventbrite.com/"&gt;a group at UC Berkeley&lt;/a&gt; now and have really enjoyed the experience. When I moved to Santa Monica from San Francisco a couple months ago I was looking to get involved down here and found Rails Girls.&lt;/p&gt;

&lt;p&gt;What I haven&amp;#39;t really thought too much about is &lt;em&gt;why&lt;/em&gt; I enjoy doing these sort of events, or programming in general. When &lt;a href="https://twitter.com/jlsuttles"&gt;@jlsuttles&lt;/a&gt; was welcoming everyone to the event she told everyone that the coaches all loved programming and want other people to love programming too. She encouraged the participants to ask the coaches why they loved programming.&lt;/p&gt;

&lt;p&gt;She hit the nail on the head, that was exactly why I was there. But then I had to prepare for the question to be asked of me, &amp;quot;Why do you love programming?&amp;quot;&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been programming a very long time, writing basic code probably before I was even 10. As long as I could touch a computer I was fascinated with them. When I went to high school there was no question what I was going to do later in life. In college I was one of the lucky few that had a very clear idea of what I wanted my major to be (CS). It&amp;#39;s been with me so long, I can&amp;#39;t imagine a life doing anything else. That makes the question hard to answer.&lt;/p&gt;

&lt;p&gt;For me, it&amp;#39;s sort of like answering why you like music or bacon.&lt;/p&gt;

&lt;p&gt;It wasn&amp;#39;t a new question. I&amp;#39;ve had to answer this question before, mostly in interview contexts. I have a few hand-wavy answers like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I like solving puzzles&lt;/li&gt;
&lt;li&gt;I get to stretch my brain on a daily basis&lt;/li&gt;
&lt;li&gt;I like to build things&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not that those aren&amp;#39;t true, but they are not very satisfying answers for me or the person asking. So, &lt;strong&gt;Why do I love programming?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You know how you and your friends sit around, talk about a problem and say &amp;quot;There should be an app to do this&amp;quot;? I can &lt;strong&gt;literally&lt;/strong&gt; build that app. Given enough time, I can solve pretty much any problem that can be solved by a computer (and that&amp;#39;s a lot of damn problems). The power that comes with knowing that is completely intoxicating to me.&lt;/p&gt;

&lt;p&gt;And that&amp;#39;s what my life is. If I see a problem that looks interesting, I solve it. I get to go to work every day and find a way to build things that nobody has built before.&lt;/p&gt;

&lt;p&gt;There&amp;#39;s also a ton of gratification you get in my field. I&amp;#39;ve done only a small amount of open source work, but even I have received tweets and emails from strangers thanking me for my contributions. Inside the firms I&amp;#39;ve worked for, when I ship features, people get psyched.&lt;/p&gt;

&lt;p&gt;As an example, at a previous company I came up with a clever solution to ease data entry for this guy that was working with excel spreadsheets for years. I spent about a half a day on the feature and he told me I literally saved him an entire month of time for a year. He was so ecstatic he took me out to dinner that night on his own dime.&lt;/p&gt;

&lt;p&gt;I genuinely can&amp;#39;t believe I get paid to do what I would do for free.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/B8D76P-_yIQ" height="1" width="1"/&gt;</content>
    <summary>Yesterday I coached a Rails Girls event in Santa Monica. For those that aren&amp;#39;t familiar, here is a description of the program in their own words:</summary>
  <feedburner:origLink>http://dickey.xxx/why-do-i-love-programming</feedburner:origLink></entry>
  <entry>
    <title>Storytelling on your team</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/Nt_W738v02c/storytelling" />
    <id>http://dickey.xxx/storytelling</id>
    <updated>2013-01-30T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Storytelling on your team&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/51/image/n-4bae60d6e8b24bb2ea9d65f10ab348a3.jpg' /&gt;&lt;p&gt;Last week I gave a talk at the &lt;a href="http://www.meetup.com/SFRails/events/91576532/"&gt;SFRails meetup&lt;/a&gt;. It was by far the largest group I&amp;#39;ve spoken to and a truly enjoyable experience. I titled the talk &amp;quot;Leveling up Rails developers&amp;quot; and it was geared towards helping engineers build a team which fosters learning and advancement of skills.&lt;/p&gt;

&lt;h1&gt;Fostering a learning culture&lt;/h1&gt;

&lt;p&gt;One of the major issues in the bay I&amp;#39;ve been interested in lately has been getting more junior engineers into the industry. My article on &lt;a href="http://dickey.xxx/dev-bootcamp"&gt;Dev Bootcamp&lt;/a&gt; highlights some of these issues.&lt;/p&gt;

&lt;p&gt;Our industry changes so rapidly that a constant state of learning is necessary in any team. Learning the toolchain, syntax, business, industry, all of these topics and more. This is true just as much from a junior engineer as a senior engineer. Learning goes hand-in-hand with teaching. I personally value teaching ability over coding ability with any engineer. Learning a platform is also not necessarily a task performed by a manager, but by peers just as much. We should be in a constant state of learning and educating.&lt;/p&gt;

&lt;p&gt;Storytelling is one method of fostering this culture.&lt;/p&gt;

&lt;h1&gt;Storytelling is natural&lt;/h1&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Narrative"&gt;Narratives&lt;/a&gt; are a part of human culture. They cross every cultural boundary. If you go to a bar and look around, everyone is sitting around telling stories. It&amp;#39;s the most natural method of communication we have.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Evidence strongly suggests that humans in all cultures come to cast their own identity in some sort of narrative form. We are inveterate storytellers. - Owen Flanagan&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="http://redsquirrel.com/dave/"&gt;Dave Hoover&lt;/a&gt;, author of &lt;a href="http://ofps.oreilly.com/titles/9780596518387/"&gt;Apprenticeship Patterns&lt;/a&gt; told me that he studied various organizations to get ideas of how they bring those less experienced up to speed. He told us about an interesting &lt;a href="http://www.jstor.org/discover/10.2307/2393372?uid=3739560&amp;amp;uid=2&amp;amp;uid=4&amp;amp;uid=3739256&amp;amp;sid=21101597920483"&gt;article studying the collective dynamics of aircraft carriers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dave told us aircraft carriers were a great group to parallel since they had younger recruits fresh on the boat as well as senior crew that have been there for decades. The accident rate on aircraft carriers is exceptionally low. What they didn&amp;#39;t find was a heavy amount of documentation, rules or mandatory meetings for new recruits. They found that information passed from the seniors to juniors simply by sitting around tables and telling stories.&lt;/p&gt;

&lt;p&gt;I believe this is effective since it&amp;#39;s simply so natural. Nobody has to tell the senior crew to prepare stories to tell. The junior crew listen intently since the stories are simply interesting to them. These stories are probably funny, but also have a moral subtext. A moral that might be complicated, but deep and effective.&lt;/p&gt;

&lt;h1&gt;Get your team telling stories too!&lt;/h1&gt;

&lt;p&gt;Dave brought this onto his team at Obtiva (later sold to Groupon) through a weekly Geekfest. &lt;a href="http://www.meetup.com/Geekfest/"&gt;It&amp;#39;s still happening at Groupon today&lt;/a&gt;. Each week, a member from a different team gets up to give a prepared story to the group. He said it was one of the most valuable practices on his team.&lt;/p&gt;

&lt;p&gt;I wanted to take this a step further. I want to emphasize the natural ability of humans to give and receive narratives. On my team at Tapjoy, I started a similar practice called Alcotales. Every Friday we get together at 3:30, leave our laptops, grab a pint and gather around a table. I try and keep the conversation around stories of failure.&lt;/p&gt;

&lt;p&gt;Failure is a great place to start since it humanizes the senior engineers. It proves that they are not perfect. It also teaches valuable lessons to the new engineers and provides a natural &amp;quot;what would you have done differently&amp;quot; discussion. Failure stories are not often heard on a team, and usually really entertaining.&lt;/p&gt;

&lt;p&gt;We&amp;#39;ve only had 2 alcotales sessions, so it&amp;#39;s hard to say how effective it is. I can say that I (and the rest of my team) looks forward to it every week. Our junior engineers have found it a valuable source of information as well.&lt;/p&gt;

&lt;h1&gt;Explain your product as a narrative&lt;/h1&gt;

&lt;p&gt;Another way to leverage the power of narratives is by using it to explain the codebase. Admittedly, Tapjoy doesn&amp;#39;t have as easy to understand product as other companies might. This can make explaining the codebase a difficult task. One of our engineers mentioned that what helped him learn the product was to have a story to explain everything from.&lt;/p&gt;

&lt;p&gt;Often, as engineers, we think about the component of a system and how they relate to each other. When we&amp;#39;re learning, however, we need to think more holistically. We need to imagine what a user might be doing, and why certain code needs to be run.&lt;/p&gt;

&lt;p&gt;If we used &lt;a href="http://hipmunk.com"&gt;Hipmunk&lt;/a&gt; as an example, the story might be: &amp;quot;Molly is trying to book a plane on April 15th to Portland, Oregon.&amp;quot; We can keep referring back to this example to make it clear how the code relates to the business.&lt;/p&gt;

&lt;p&gt;Those are my two suggestions on how I plan on using narratives to increase the learning culture on my team. I&amp;#39;m curious if your team has any similar practices, definitely let me know.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/Nt_W738v02c" height="1" width="1"/&gt;</content>
    <summary>Last week I gave a talk at the SFRails meetup. It was by far the largest group I&amp;#39;ve spoken to and a truly enjoyable experience. I titled the talk &amp;quot;Leveling up Rails developers&amp;quot; and it was geared towards helping engineers build a team which fosters learning and advancement of skills.</summary>
  <feedburner:origLink>http://dickey.xxx/storytelling</feedburner:origLink></entry>
  <entry>
    <title>How to attend a hackathon</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/uKHGTrMgEWk/hackathons" />
    <id>http://dickey.xxx/hackathons</id>
    <updated>2012-12-09T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;How to attend a hackathon&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/46/image/n-1b1c2b2c154c7b67ec22e54aca14d960.jpeg' /&gt;&lt;p&gt;I think hackathons are really a great thing. They are a relatively new concept, so it is not surprising when I attend one I find myself hacking away with others that are new to the idea. I also think they are a little misunderstood. Even some organizers do not focus on where the real value is with hackathons.&lt;/p&gt;

&lt;h1&gt;My background with hackathons&lt;/h1&gt;

&lt;p&gt;I wouldn&amp;#39;t be involved in startups if I didn&amp;#39;t attend Startup Weekend in Seattle back when I was in college. The idea of taking the extra effort to build products with likeminded people immediately struck a chord with me. I haven&amp;#39;t looked back since.&lt;/p&gt;

&lt;p&gt;I also wouldn&amp;#39;t be in the bay. I attended another Startup Weekend in San Jose shortly after the one in Seattle that helped me network with people. From there, I was able to meet the people that got me my first job in the bay. More importantly, I&amp;#39;m still close friends with many of the people I met at hackathons. Even years later we meet regularly.&lt;/p&gt;

&lt;h1&gt;Different hackathon types&lt;/h1&gt;

&lt;p&gt;There are 3 general types of hackathons as I see it.&lt;/p&gt;

&lt;h2&gt;In-person (AngelHack, Startup Weekend, Disrupt)&lt;/h2&gt;

&lt;p&gt;Usually a large group of people that don&amp;#39;t know each other well. Usually a competition is involved with the winning receiving some sort of seed-funding or support to continue their project into a real company. These are the most &amp;#39;entrepreneurially&amp;#39; focused. These are the focus of my article.&lt;/p&gt;

&lt;h2&gt;Internal&lt;/h2&gt;

&lt;p&gt;A hackathon at work. We&amp;#39;ve done this at Tapjoy a couple times. The rule we have is, &amp;quot;you have to work on something you wouldn&amp;#39;t do on a normal work-day.&amp;quot; As I understand, it&amp;#39;s gone very well from all sides. I would encourage looking into doing something like this for your own team. We&amp;#39;ve had some variations in how we&amp;#39;ve done it (assigned/unassigned teams, in-office and off-site), but I can&amp;#39;t say what&amp;#39;s better/worse just yet.&lt;/p&gt;

&lt;h2&gt;Online (Rails Rumble, Node Knockout)&lt;/h2&gt;

&lt;p&gt;A hackathon that is conducted only online. These are the most engineer-focused. Typically the products will have a smaller scope and target more specific challenges. Usually there are prizes, but most people participate just to build something. There is usually little-to-no need for non-engineers and non-designers in these types.&lt;/p&gt;

&lt;h1&gt;Who can attend a hackathon&lt;/h1&gt;

&lt;p&gt;Pretty much anyone can attend so long as they are willing to participate. Even if you don&amp;#39;t code/design, you can work on building a business model, pitch deck, website copy, etc.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;re a student or new to coding don&amp;#39;t be worried. Hackathons are a great place to learn new things. If you&amp;#39;re looking for a job, they&amp;#39;re incredibly good for networking. Unlike most networking events, your contacts will actually be able to speak about your skill in a very intense environment. In fact, I would actually like to see universities get much more involved in hackathons.&lt;/p&gt;

&lt;h1&gt;Why attend a hackathon&lt;/h1&gt;

&lt;p&gt;The number one reason is to have a good time. Expect to laugh, socialize, learn a ton and spur some creativity. It is so powerful that I find after I attend a hackathon I have a much improved attitude and have a higher level of creativity.&lt;/p&gt;

&lt;p&gt;Expect to meet some new friends. Even if your team is with co-workers or current friends, you will find you&amp;#39;re much closer to them following the event.&lt;/p&gt;

&lt;p&gt;Hackathons are intense. I try and do very little the day before a hackathon starts (and I typically don&amp;#39;t even pull the all-nighters as some do).&lt;/p&gt;

&lt;p&gt;What shouldn&amp;#39;t you expect?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don&amp;#39;t expect to find a great idea; hackathons are about execution.&lt;/li&gt;
&lt;li&gt;Don&amp;#39;t expect to win; hackathons are an experience first and competition second.&lt;/li&gt;
&lt;li&gt;Don&amp;#39;t expect to launch a company; the way you execute in a hackathon context does not translate to the real world.&lt;/li&gt;
&lt;li&gt;Don&amp;#39;t work too hard; there&amp;#39;s a high probability that most of the work you do will never be seen by anyone outside your team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly though: try not to expect anything. Every hackathon involves a ton of chaos. That chaos is where the benefits lie.&lt;/p&gt;

&lt;p&gt;Regardless of the hackathon, they have a standard formula that takes place over 1-3 days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pitches and building teams&lt;/li&gt;
&lt;li&gt;Deciding what to build&lt;/li&gt;
&lt;li&gt;Building product&lt;/li&gt;
&lt;li&gt;Deciding what to demo and how to demo&lt;/li&gt;
&lt;li&gt;Demo/presenting/judging&lt;/li&gt;
&lt;li&gt;Heavy drinking&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;The pitches&lt;/h1&gt;

&lt;p&gt;I like how Startup Weekend does this part the best. They start everyone out on Friday night before the weekend. Everyone goes down to a big auditorium where they have soda + pizza, give some introductions, thank the sponsors, then have everyone line up that brought an idea to pitch it for about a minute.&lt;/p&gt;

&lt;p&gt;I haven&amp;#39;t actually given a pitch myself, but I am pretty analytical with regards to the pitches. Picking a team is a big deal, and most of my decision will be based on the pitch.&lt;/p&gt;

&lt;p&gt;Pitches contain the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A problem to solve&lt;/li&gt;
&lt;li&gt;A vague idea or 2 on possible solutions&lt;/li&gt;
&lt;li&gt;What roles are filled and need to be filled&lt;/li&gt;
&lt;li&gt;Roughly what the pitcher&amp;#39;s background is&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some are serious, some are less so, and some are not even real projects. At AngelHack there was a team that was going to spend the day flying a plane around in the parking lot. Another team wanted to film pornography.&lt;/p&gt;

&lt;p&gt;Personally, I am looking for the following in the pitch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I care about the problem?&lt;/li&gt;
&lt;li&gt;Does he/she understand the problem?&lt;/li&gt;
&lt;li&gt;Does he/she understand their own solution and it&amp;#39;s complexity?&lt;/li&gt;
&lt;li&gt;Is it something I think can get done in a weekend, with time to prep a demo?&lt;/li&gt;
&lt;li&gt;Will the solution actually demo well?&lt;/li&gt;
&lt;li&gt;What is their role? Is it someone I think I will like to work with? (Hard to answer this one)&lt;/li&gt;
&lt;li&gt;Will it be fun to work on?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might be incredibly disappointed after hearing the pitches. I was my first couple of times. The reality is that ideas really aren&amp;#39;t ever that great. It&amp;#39;s virtually impossible to tell what the winning team will be at pitch time. Remember though: this isn&amp;#39;t about winning, it&amp;#39;s about the experience.&lt;/p&gt;

&lt;p&gt;Another tip: Take notes. Write down the teams that sound interesting. Make sure to also note what the speaker looks like, what their name is and what they&amp;#39;re wearing so you can find them later.&lt;/p&gt;

&lt;h1&gt;Finding your team&lt;/h1&gt;

&lt;p&gt;After the pitches everyone breaks out and tries to find their team. It&amp;#39;s the most chaotic part of the weekend.&lt;/p&gt;

&lt;p&gt;People start swarming different presenters. You&amp;#39;ll find that some groups get a ton of people and some get very few. Your job is to talk to as many teams as you can to find the right one for you.&lt;/p&gt;

&lt;p&gt;This is also the point when you might get a little scared. You might think &amp;quot;well I didn&amp;#39;t really &lt;em&gt;love&lt;/em&gt; any of the ideas... maybe I should just go home and relax for the weekend&amp;quot;. Power through it. This happens to me as well. You&amp;#39;ll be glad you did.&lt;/p&gt;

&lt;p&gt;Find out what the roles are going to be exactly. Are you a PHP developer? Do they want to build the back-end in Django? You might want to break out of your comfort zone and try something new. In fact, hackathons are where I learned both Rails AND Django. If you could believe it, I wanted to build my first app in .NET. Still, be realistic. If you&amp;#39;re really not interested in learning what they want to build the app in then find a different team.&lt;/p&gt;

&lt;p&gt;Brainstorm the solution, you&amp;#39;ll quickly be able to decide if you want to work with that team.&lt;/p&gt;

&lt;p&gt;Don&amp;#39;t worry about big vs small teams. I&amp;#39;ve had a 8-person group that was great. We all had specific roles and executed well. Obviously, I met way more people as well. Large teams are also more likely to win (but again, that&amp;#39;s not your focus).&lt;/p&gt;

&lt;p&gt;I also have had 2-people groups that were great too. Definitely walked out after the weekend with someone I was happy to call a friend. I also got to have way more input in the solution and felt much closer to the product. More coding, less discussion.&lt;/p&gt;

&lt;p&gt;Really though: find the team that feels right. You&amp;#39;ll find one, I promise. One time I actually switched teams mid-hackathon because I found a better fit where people needed me more.&lt;/p&gt;

&lt;h1&gt;Refining the concept&lt;/h1&gt;

&lt;p&gt;Now that you&amp;#39;ve found your team, you&amp;#39;ll likely seamlessly transition into some planning. Brainstorm different ideas about solutions. The conversation will be a little crazy. You&amp;#39;ll jump all over the place. Only thing to keep in mind is to be optimistic and positive. This is no time to ruin creativity by shooting down ideas.&lt;/p&gt;

&lt;p&gt;Find a place to set up camp for the weekend. Grab a drink. Just let the conversation go wherever it goes for a little while.&lt;/p&gt;

&lt;p&gt;Once you have all these ideas out there, you&amp;#39;ll start nailing down exactly what the product should be. Then it&amp;#39;ll get even finer to &amp;#39;what you can demo in a weekend&amp;#39;. This all happens pretty naturally.&lt;/p&gt;

&lt;p&gt;When deciding your scope, keep it crazy small. Can&amp;#39;t/won&amp;#39;t demo it? Don&amp;#39;t build it. You can build apps anytime: hackathons are for doing this socially. If nobody sees your code in action, it might as well not exist.&lt;/p&gt;

&lt;h1&gt;Hacking&lt;/h1&gt;

&lt;p&gt;There is really not much to say here. This is the most natural part of the event. Don&amp;#39;t work too hard. Remember to meet people. Walk around and ask others what they&amp;#39;re working on at least once during the event.&lt;/p&gt;

&lt;p&gt;Oh, and caffeine is the hackathon wonder drug. You&amp;#39;ll hack harder, longer, and be more motivated. Keep the red bull + coffee handy for you and your team.&lt;/p&gt;

&lt;p&gt;Some hackers will go all night, I don&amp;#39;t suggest it. Get what sleep you can. It&amp;#39;ll be hard to sleep since the ideas will be swarming through your head. It&amp;#39;s likely the morning of day 2 will involve some dramatic shifts in the product, almost always for the better. Hacking through the night won&amp;#39;t encourage the healthy perspective after the drive home and a good night&amp;#39;s sleep.&lt;/p&gt;

&lt;p&gt;Start the day off with a solid re-analysis of the plan. Figure out what you can do for the demo.&lt;/p&gt;

&lt;p&gt;That demo is hugely important. Repeatedly stop coding and think about what you&amp;#39;re actually going to demo. It&amp;#39;s tempting to build out features that won&amp;#39;t be involved in the demo, but stop yourself.&lt;/p&gt;

&lt;p&gt;Get screenshots! The best demos I&amp;#39;ve done have only been screenshots. Screenshots also can&amp;#39;t fail like demos always seem to.&lt;/p&gt;

&lt;h1&gt;Demo time&lt;/h1&gt;

&lt;p&gt;It can be hard, but try and support your competitors. Winning is not important. Still, you&amp;#39;re going to want to put on a good demo for the judges.&lt;/p&gt;

&lt;p&gt;If you&amp;#39;re actually going to show off your real product, remember to have your screenshots handy just in case. Last time I gave a demo we had to use a powerpoint on an iPhone. Be prepared for every piece of technology to fail. They&amp;#39;re all likely to.&lt;/p&gt;

&lt;h1&gt;Post-hackathon&lt;/h1&gt;

&lt;p&gt;Go grab a beer with your team! If everyone is too tired, or not in the mood or whatever, set up a time during the following week to meet up. Even if you have to email them and meet individually: do it.&lt;/p&gt;

&lt;p&gt;When networking, if you have that second interaction, it really &amp;#39;seals&amp;#39; it somehow. You&amp;#39;ll also have a ton to talk about between the idea you hacked on, the execution of it, the teammates, the other teams, the judges, everything. It won&amp;#39;t be a boring conversation.&lt;/p&gt;

&lt;h1&gt;The number one thing hackathons do wrong&lt;/h1&gt;

&lt;p&gt;People disagree with me on this one, but the number one thing that virtually all hackathons do that I do not like is have a winner. I attended one hackathon (the Ballmer Peak-A-Thon) that did not have a winner. Everyone presented their projects and instead of critiquing everyone while thinking, &amp;quot;psh, mine is better&amp;quot; I was excited to see what each team built and felt a much better sense of community.&lt;/p&gt;

&lt;p&gt;I didn&amp;#39;t realize there was not going to be a winner until the pitches were already halfway through. At first I was disappointed thinking that our project could have won. I felt like I lost. That went away quickly. I noticed I appreciated the other projects SO much more.&lt;/p&gt;

&lt;p&gt;Don&amp;#39;t get me wrong: I love competition. I&amp;#39;m also sure that you reading this are probably thinking that without the without the competition the motivation would disappear. I disagree. People are naturally motivated to build things. The only thing having a winner provides is everyone to believe their project should win, and that every other project is worse.&lt;/p&gt;

&lt;p&gt;I would like to see more winner-less hackathons. It&amp;#39;s a much more pleasant environment.&lt;/p&gt;

&lt;h1&gt;Get out there and do it!&lt;/h1&gt;

&lt;p&gt;I try to attend a hackathon every couple of months. It&amp;#39;s a big time investment that makes my weekend completely disappear. Still, every hackathon I&amp;#39;ve walked away from feeling as if I really gained a life-changing experience. They are intense, but so worth it.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/uKHGTrMgEWk" height="1" width="1"/&gt;</content>
    <summary>I think hackathons are really a great thing. They are a relatively new concept, so it is not surprising when I attend one I find myself hacking away with others that are new to the idea. I also think they are a little misunderstood. Even some organizers do not focus on where the real value is with hackathons.</summary>
  <feedburner:origLink>http://dickey.xxx/hackathons</feedburner:origLink></entry>
  <entry>
    <title>Does Rails scale?</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/CHenh8mjlO4/ruby-rails-scale" />
    <id>http://dickey.xxx/ruby-rails-scale</id>
    <updated>2012-10-15T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Does Rails scale?&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/43/image/ShatteredRuby1-9c2632455f3683bbbdfe21a2a0452310.jpg' /&gt;&lt;p&gt;First, the short answer: &lt;strong&gt;Damn right it does.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Twitter had to quit using it because Ruby is so slow&lt;/h2&gt;

&lt;p&gt;It is well known that around 2008 Twitter moved their job backend from Rails to Scala. To me it seems they absolutely made the right choice. Twitter had way outgrown the version of Ruby it was on and they needed a different solution.&lt;/p&gt;

&lt;p&gt;Keep in mind that Ruby 1.9 came out a year later in 2009. The performance characteristics between 1.8 and 1.9 is huge. Just look at this graph from &lt;a href="http://www.zendesk.com/blog/upgrade-the-road-to-1-9"&gt;Zendesk&amp;#39;s report of moving from 1.8 to 1.9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://i.imgur.com/ORh5z.png" alt=""&gt;&lt;/p&gt;

&lt;p&gt;In addition, Rails had no support for asynchronous jobs at the time. Rails would not have done anything to help job processing, so moving to Scala probably made a lot of sense. Today, we have Resque and Sidekiq which make the process much cleaner on the code side.&lt;/p&gt;

&lt;h2&gt;But Ruby is slow even in 1.9&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s not a fast language. However, that rarely matters. The hard part about scaling an application is proper architecture, solid caching and CDNs, the right database for the job and so on. It&amp;#39;s more about external resources than the code in the app. The runtime of the language rarely becomes an issue. The goal is to leverage existing tools in order to do less work on the web stack.&lt;/p&gt;

&lt;p&gt;In most scenarios, you&amp;#39;re scaling concern will not be waiting on the speed of Ruby, but the I/O. When Ruby is really able to leverage its fibers (such as in &lt;a href="https://github.com/igrigorik/em-synchrony"&gt;em-synchrony&lt;/a&gt;), we&amp;#39;ll start to see node.js levels of performance.&lt;/p&gt;

&lt;h2&gt;None of this matters&lt;/h2&gt;

&lt;p&gt;I wouldn&amp;#39;t call Twitter unsuccessful. They did build their product and eventually found the right architecture for them. I doubt the engineers at Twitter think that going with Scala right off the bat would&amp;#39;ve been the right choice. Using Rails, they could build the product quickly. They could change it in order to build the product in a way that was successful. Rails empowers the developers to change direction without a lot of code change.&lt;/p&gt;

&lt;p&gt;Not only can developers alter features, but the same is true on the backend as well. I&amp;#39;ve worked on a system where we swapped database backends from MySQL to PostgreSQL with almost no code change. Another project where we included advanced caching layers without modifying existing models. In the same way that Ruby allows rapid product changes, the ability to rapidly alter architecture changes ensures scalability.&lt;/p&gt;

&lt;p&gt;These are all changes that would&amp;#39;ve been so prohibitively difficult in my .NET and Django days that we would&amp;#39;ve just greenfielded a new project.&lt;/p&gt;

&lt;h2&gt;Rails is not all roses&lt;/h2&gt;

&lt;p&gt;While Rails does a lot of things well, there is one part of scaling it does not do well. The human issue. Rails encourages the &amp;#39;monorail&amp;#39; architecture. Projects approach the size that become difficult to work on. No single engineer will understand the project from beginning to end. New engineers will be lost in the project and feel unproductive. Bugs might arise out of seemingly disconnected parts of the code-base.&lt;/p&gt;

&lt;p&gt;A more disconnected architecture has many pros in a large system. Engineers will feel more productive as they can really own their project. The knowledge needed to be productive will be much lower.&lt;/p&gt;

&lt;p&gt;Square, Groupon, YP, Tapjoy and others have all experienced these growing pains. They&amp;#39;ve also all moved to a service-oriented architecture (SOA) to solve these issues. One of the biggest issues Rails has is with easing that transition. Now that it&amp;#39;s been happening regularly, I think we&amp;#39;ll start to be able to identify patterns and enhance the framework to support it, however.&lt;/p&gt;

&lt;p&gt;That doesn&amp;#39;t mean you should go for SOA right off the bat though. I believe moving from a monorail and then breaking the system apart is the correct approach. With any platform, SOA is simply a more complicated architecture. You also won&amp;#39;t know what services there actually should be until you&amp;#39;ve got a large codebase.&lt;/p&gt;

&lt;h2&gt;So yes, it does scale&lt;/h2&gt;

&lt;p&gt;Even given the faults on the monorail problem, Rails scales beautifully. Between the speed of Ruby 1.9, the fact that most of our work is I/O heavy, and the ability to alter the stack: it certainly scales.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/CHenh8mjlO4" height="1" width="1"/&gt;</content>
    <summary>First, the short answer: Damn right it does.

Twitter had to quit using it because Ruby is so slow

It is well known that around 2008 Twitter moved their job backend from Rails to Scala. To me it seems they absolutely made the right choice. Twitter had way outgrown the version of Ruby it was on and they needed a different solution.</summary>
  <feedburner:origLink>http://dickey.xxx/ruby-rails-scale</feedburner:origLink></entry>
  <entry>
    <title>Rails Rumble: ARSS</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/hNCADS08PYE/arss" />
    <id>http://dickey.xxx/arss</id>
    <updated>2012-10-14T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Rails Rumble: ARSS&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/44/image/PM-14db3276db2f0c4b3c6f77ebe2663939.png' /&gt;&lt;p&gt;This weekend I have been participating in the &lt;a href="http://railsrumble.com/"&gt;2012 Rails Rumble&lt;/a&gt;. I worked with &lt;a href="https://twitter.com/amdtech"&gt;@amdtech&lt;/a&gt; and &lt;a href="https://twitter.com/childoftv"&gt;@childoftv&lt;/a&gt; to build &lt;strong&gt;ARSS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Check it out at &lt;a href="http://arss.io"&gt;http://arss.io&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;The idea&lt;/h2&gt;

&lt;p&gt;A few weeks before the event I started a group and asked both if they would like to join. About a week before the event we got together and chatted about a few product ideas. One stood above the rest, and that was a system to aggregate information around the internet in order to be consumed and redistributed to others.&lt;/p&gt;

&lt;p&gt;An example of what we were looking for would be to have the system pull in all the github commits on a project, and let a team lead aggregate them together to display them on a status board so an entire company can get a solid glimpse of what a team is working on.&lt;/p&gt;

&lt;h2&gt;The roles&lt;/h2&gt;

&lt;p&gt;Aaron is the lead ops engineer at Tapjoy so naturally we planned for his role was with the core of the system. Integrating various services, setting up production, setting up the databases, things like that.&lt;/p&gt;

&lt;p&gt;Ben is a front-end developer that specializes in UI development. He also has a solid understanding of UX and product. Ben&amp;#39;s role was css/js, copywriting and some design work.&lt;/p&gt;

&lt;p&gt;My role in the project was building the back-end functionality. I would be integrating the apis, building authentication and adding email receiving support.&lt;/p&gt;

&lt;h2&gt;The process&lt;/h2&gt;

&lt;p&gt;We started the project early Saturday morning. We used a whiteboard to communicate with each other what the architecture should look like.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://sphotos-a.xx.fbcdn.net/hphotos-ash3/547043_806968891131_1179526512_n.jpg" alt=""&gt;&lt;/p&gt;

&lt;p&gt;We decided to start out with the least work possible: a simple site that just shows incoming emails through pusher. Not even any authentication.&lt;/p&gt;

&lt;p&gt;We got there, it took about 4 hours. We used cloudmailin to grab the incoming emails, submit them to our rails app, stored the results in mongodb, then pushed that to the client. We then started working on building authentication and users accounts. That&amp;#39;s when trouble started.&lt;/p&gt;

&lt;h2&gt;The first roadblock&lt;/h2&gt;

&lt;p&gt;We ran into a pretty serious issue. Aaron read the rules a little closer and found that we couldn&amp;#39;t use any paid external services. We were currently using 2: cloudmailin and pusher. We first felt that we had almost built nothing since the most impressive parts we had built, we couldn&amp;#39;t use.&lt;/p&gt;

&lt;p&gt;We spoke about it a bit and realized we weren&amp;#39;t as bad as we originally thought. We could simply use &amp;#39;setTimeout&amp;#39; in javascript to replace pusher. We then needed to replace cloudmailin. That actually ended up not being a huge deal either. We had abstracted out the mail processing enough that Aaron was quickly able to replace the cloudmailin functionality with a job that pulled down gmail content using the &amp;#39;gmail&amp;#39; gem.&lt;/p&gt;

&lt;h2&gt;End of the first day&lt;/h2&gt;

&lt;p&gt;We started to get pretty tired around 10:00 at the end of the first day and took a moment to have a few beers. We realized that there was a little bit of confusion over what exactly we were building. Ben and I were picturing it as a way to show ALL updates from the sources in a combined feed, whereas Aaron thought of the output as a feed that was generated by hand.&lt;/p&gt;

&lt;p&gt;We were a little confused with why having a user go through and manually select updates to put on the feed would be helpful. He told us how he planned to use it at Tapjoy as a way to notify people of deploys or when we get reports of system instability. Simply getting the firehose of updates from airbrake, github or newrelic is simply too much for most people. There are people in Tapjoy that would like to get more information about the system, but not by automated means. Currently that means drafting a new email to send out to many aliases that are hard to keep track of. What would be better is if he could just post it to a secure site for people to check out if they were curious or seeing issues.&lt;/p&gt;

&lt;p&gt;After the discussion, Ben and I went home, but Aaron worked late into the night developing most of the core functionality.&lt;/p&gt;

&lt;h2&gt;Second day&lt;/h2&gt;

&lt;p&gt;Starting the second day around 10AM we felt pretty good. Even given that we had different plans for the product, it hadn&amp;#39;t made any of the work we had previously done useless. Ben and Aaron cleaned up the UI, I finalized the Github integration, Ben created some artwork and did the copywriting, we were working hard, but felt confident we would complete the project by the due time of 5:00pm.&lt;/p&gt;

&lt;h2&gt;The result&lt;/h2&gt;

&lt;p&gt;We were pretty happy with what we had built. We had 2 sources (email and github) and felt that it would be easy to start including others such as issue trackers, continuous integration or exception notifiers.&lt;/p&gt;

&lt;p&gt;We wanted to get more support for notifications going out of the system. We want people to consider ARSS the place where information is aggregated before going to external services. Email and an API are necessary to make that a reality.&lt;/p&gt;

&lt;p&gt;We plan to keep working on the service and hopefully using it professionally as well.&lt;/p&gt;

&lt;h2&gt;Want a demo?&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;d like to try out a demo of the service, login with these credentials at &lt;a href="http://arss.io"&gt;arss.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;user: &lt;a href="mailto:aaron@arss.io"&gt;aaron@arss.io&lt;/a&gt;&lt;br&gt;
pass: arss.io2012&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/hNCADS08PYE" height="1" width="1"/&gt;</content>
    <summary>This weekend I have been participating in the 2012 Rails Rumble. I worked with @amdtech and @childoftv to build ARSS.

Check it out at http://arss.io</summary>
  <feedburner:origLink>http://dickey.xxx/arss</feedburner:origLink></entry>
  <entry>
    <title>Dev Bootcamp is the future of our industry</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/1r4lwlCEtUA/dev-bootcamp" />
    <id>http://dickey.xxx/dev-bootcamp</id>
    <updated>2012-08-18T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Dev Bootcamp is the future of our industry&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/42/image/logogrey-9b8028a901ed375daf3d352839202db8.png' /&gt;&lt;p&gt;Yesterday, I attended the Dev Bootcamp Hiring Day for the class of Summer 2012. I was incredibly inspired by the people I met there.&lt;/p&gt;

&lt;h2&gt;Startup careers&lt;/h2&gt;

&lt;p&gt;I really enjoy my career. I&amp;#39;m always trying to sell the lifestyle to my friends that are either already developers or just looking at a career change in general. With this economy, the ability to grab a 6 figure salary with kick-ass perks is absolutely incredible. Also, engineering is naturally satisfying and fun.&lt;/p&gt;

&lt;p&gt;The way to get into the industry is seriously backwards though. Up until very recently, it basically required a Computer Science degree from a university. These degrees are a very difficult degree to attain, accessible only by those that get into computing at a young age.&lt;/p&gt;

&lt;h2&gt;My career&lt;/h2&gt;

&lt;p&gt;I have a CS degree myself. I remember my very first day of CS160 at Oregon State in 2004. There was probably ~300 people in the that room. After the first day, only about 200 people remained. After the first week: 150. At the end of the term there were less than 100 that had actually finished the full 10 weeks.&lt;/p&gt;

&lt;p&gt;I would not be surprised if there isn&amp;#39;t a major more switched out of at Oregon State than Computer Science. It&amp;#39;s really tough to stick it out if you&amp;#39;re not deeply in love with core CS fundamentals.&lt;/p&gt;

&lt;p&gt;For me, classes like algorithms and compilers were really hard because I just didn&amp;#39;t care. Luckily, I had great friends that pushed me along. I also got involved in startups during my last couple years which drove me to power through and get the degree out of the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I am interested in building products, not pointless optimization.&lt;/strong&gt; I don&amp;#39;t think there is anything wrong with that. There is a whole market of engineers out there with a similar mindset. They&amp;#39;re interested in hacking products together, but not in getting an expensive 4-year degree only partially related to what they want to do.&lt;/p&gt;

&lt;h2&gt;Enter Dev Bootcamp&lt;/h2&gt;

&lt;p&gt;I heard of Dev Bootcamp a few months ago when TechCrunch ran the article &lt;a href="http://techcrunch.com/2012/05/10/dev-boot-camp-is-a-ruby-success/"&gt;Startups Court Dev Bootcamp’s Ruby Grads: 88% Have Offers At Average Of $79K&lt;/a&gt;. This was a huge story to me. I was really happy to see something like that pop up.&lt;/p&gt;

&lt;p&gt;They teach exactly what you need to know for a career in modern web development. Most of the program isn&amp;#39;t even touched upon in a university. They teach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rails development - a truly modern framework with very portable knowledge.&lt;/li&gt;
&lt;li&gt;Test driven development - the best way to code, and something I wish I had more in my core than I do.&lt;/li&gt;
&lt;li&gt;Agile methodologies - how most companies operate.&lt;/li&gt;
&lt;li&gt;Git - the best source control solution as it&amp;#39;s better than any other with collaboration, code reviewing and working on multiple features at once.&lt;/li&gt;
&lt;li&gt;Soft skills - interviewing, pair-programming, code reviews.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;My experience&lt;/h2&gt;

&lt;p&gt;I attended the event on behalf of my company in order to see if we might want to bring any of the guys in. I&amp;#39;ll admit that I&amp;#39;m generally see a more optimistic view of people in interviews, and they were short ~5 minute conversations. Still, &lt;strong&gt;I was blown away by pretty much every student. I totally would have brought each of them in for a full interview.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was told that they only spent a bit of time on the soft skills portion, but I am pretty sure they told each and every one of them how to interview for Jeff Dickey.&lt;/p&gt;

&lt;h2&gt;The full-stack mindset&lt;/h2&gt;

&lt;p&gt;I asked most students what part of the stack they wanted to work on. (front-end, back-end, ops, etc). Literally every student answered in a similar way. They wanted to work on the full stack. They wanted to learn as much as they could about general development and be able to work at a company willing to facilitate that.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s absolutely the best answer to that question, but the answer I rarely get.&lt;/p&gt;

&lt;h2&gt;Willingness to branch out to unfamiliar territory&lt;/h2&gt;

&lt;p&gt;When they described the applications they built, they would mention different techniques they used. Doing ajax with straight javascript is an example of just one of these conversations I had with a student. I asked him if he had heard of alternate techniques (such as backbone.js or ember.js). He responded by saying he had researched them, that the tools looked awesome and (genuinely) would love the opportunity to try them out.&lt;/p&gt;

&lt;p&gt;Engineers have a tendency to vote for the tools they know best. These students have this early direction of wanting to investigate as much as they can will take them far. It was very refreshing to see.&lt;/p&gt;

&lt;h2&gt;Excitement for hacking&lt;/h2&gt;

&lt;p&gt;They all came from vastly different backgrounds as well. One was 19, a couple came from law backgrounds, another biotech, they were all over the map. However, their level of enthusiasm for building applications and learning tech was very similar.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m convinced that excitement doesn&amp;#39;t come from a CS degree. There are people all over the place that want to build cool shit.&lt;/p&gt;

&lt;h2&gt;I absolutely loved it&lt;/h2&gt;

&lt;p&gt;I was incredibly inspired after the event. The only thing I&amp;#39;m disappointed about is that this isn&amp;#39;t everywhere. There are certainly other groups like &lt;a href="http://workshops.railsbridge.org/"&gt;Railsbridge&lt;/a&gt; and &lt;a href="http://www.codeschool.com/"&gt;Code School&lt;/a&gt; that are also doing great things for our community, but I want to see more!&lt;/p&gt;

&lt;p&gt;I don&amp;#39;t think the traditional 4-year computer science path is a only way to get into this industry (or even a good one). Computer Science is only related to software engineering.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/1r4lwlCEtUA" height="1" width="1"/&gt;</content>
    <summary>Yesterday, I attended the Dev Bootcamp Hiring Day for the class of Summer 2012. I was incredibly inspired by the people I met there.</summary>
  <feedburner:origLink>http://dickey.xxx/dev-bootcamp</feedburner:origLink></entry>
  <entry>
    <title>Imported lager is the uncanny valley of beer</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/tQOZJZPq88k/imported-lager-is-the-uncanny-valley-of-beer" />
    <id>http://dickey.xxx/imported-lager-is-the-uncanny-valley-of-beer</id>
    <updated>2012-07-07T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Imported lager is the uncanny valley of beer&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/41/image/2-3b95ea5cc047712fbf07add2a1ed9ba1.jpg' /&gt;&lt;p&gt;Recently at Tapjoy I became the official Kegmeister. My reign lasted for maybe 24 hours before a coup.&lt;/p&gt;

&lt;p&gt;Upon given the honor, I quickly drafted 3 executive orders:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We shall have a third can of co2 at all times to ensure the beer never stops flowing.&lt;/li&gt;
&lt;li&gt;We shall have a third keg not inside a kegerator on hand in case of emergency.&lt;/li&gt;
&lt;li&gt;That third keg (to replace our beer pong beer) shall be of the Great Domestic Lager: Bud Light. The sure sign of a good time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I imagine you can assume why I was ousted. Bud Light does not attract fans in the bay area. Not by a long shot. I was quick (but unsuccessful) defending my decisions.&lt;/p&gt;

&lt;p&gt;My defense is that beer need not always be flavorful. There is a place for the refreshing taste of a simple domestic lager. It&amp;#39;s not worse, just different. Since this was intended to be our drinkable, light, beer pong beer. I felt Bud Light fit the bill perfectly.&lt;/p&gt;

&lt;p&gt;I love beer! Being a native Northwesterner, it is unsurprising that I am attracted to the hoppiest of IPAs. I prefer them unbalanced and bitter to the point of ripping paint of walls. I want them to have ABV equivalent to some wines. Some of my other favorites include: the amber, the belgian trippel, and the RIS. On occasion, I will have a porter, pilsner, wheat beer, or really any style. The only style that I am not really a fan of is Framboise. I participated in the Heart of the Valley Homebrewers association back in Oregon. Some of my friends are very into making beer, and while homebrewing isn&amp;#39;t my thing, I love to talk about it! (And taste the results!)&lt;/p&gt;

&lt;p&gt;But still, I love myself a nice domestic lager. Bud Light, Coors Light, or even better: Shiner Bock and Yuengling! It is a different type of satisfaction, however. What I look for in domestic lager is high carbonation, cold temperature, light flavor, light mouthfeel, simple aroma, consistency and overall refreshing nature.&lt;/p&gt;

&lt;p&gt;This brings me to my point. I think that craft and European lager misses the point. They fit somewhere between a nice, flavorful beer and a refreshing, simple lager. These lagers confuse me. I don&amp;#39;t know what I&amp;#39;m looking for. They&amp;#39;re too &amp;#39;good&amp;#39; to be lager, but not &amp;#39;good&amp;#39; enough to be an ale.&lt;/p&gt;

&lt;p&gt;They simply fall into the &lt;a href="http://en.wikipedia.org/wiki/Uncanny_valley"&gt;uncanny valley&lt;/a&gt; of beer.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/tQOZJZPq88k" height="1" width="1"/&gt;</content>
    <summary>Recently at Tapjoy I became the official Kegmeister. My reign lasted for maybe 24 hours before a coup.

Upon given the honor, I quickly drafted 3 executive orders:</summary>
  <feedburner:origLink>http://dickey.xxx/imported-lager-is-the-uncanny-valley-of-beer</feedburner:origLink></entry>
  <entry>
    <title>MySQL is done. It's the Postgres Age.</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/Tmfpe-wMnWA/mysql-is-done-it-s-the-postgres-age" />
    <id>http://dickey.xxx/mysql-is-done-it-s-the-postgres-age</id>
    <updated>2012-05-23T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;MySQL is done. It's the Postgres Age.&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/38/image/elephant1-1e267931c40f2a6c71e014f9433b71d8.jpeg' /&gt;&lt;p&gt;Postgres is a relational(-ish) database that&amp;#39;s really starting to become the one-size-fits-all of databases. I think this is very interesting since I wouldn&amp;#39;t have predicted this direction a year ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://schneems.com/post/19298469372/you-got-nosql-in-my-postgres-using-hstore-in-rails"&gt;Schema-less data&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/9.1/static/arrays.html"&gt;array columns&lt;/a&gt;, &lt;a href="https://github.com/ryandotsmith/queue_classic"&gt;queueing&lt;/a&gt;, &lt;a href="https://github.com/Casecommons/pg_search"&gt;full-text searching&lt;/a&gt;, geo-spatial indexing, it&amp;#39;s insane what Postgres can do.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had a conversation yesterday with &lt;a href="http://linkedin.com/in/samstokesuk"&gt;Sam Stokes&lt;/a&gt; of &lt;a href="http://rapportive.com/"&gt;Rapportive&lt;/a&gt;. I wanted to know about their experience using Postgres. They run a pretty massive Postgres system. Sam mentioned that it&amp;#39;s gone very well and, if he were to do it again from scratch, he would absolutely use Postgres.&lt;/p&gt;

&lt;p&gt;Sam&amp;#39;s not the only one, I&amp;#39;ve heard some great comments about people using Postgres for just about their entire data back-end. Even the data guys I know love Postgres.&lt;/p&gt;

&lt;p&gt;I would say that Postgres is by far the top tool being raved about in web dev.&lt;/p&gt;

&lt;h2&gt;Has nosql failed?&lt;/h2&gt;

&lt;p&gt;A couple years ago, I thought the nosql tools would be the future. It was really all about &amp;quot;using the right tool for the job&amp;quot;. I thought this was an awesome new way of thinking. RDBs shouldn&amp;#39;t be the go-to, but a combination of tools. Tools catered to solve the right problem.&lt;/p&gt;

&lt;p&gt;Postgres has taken the features out of all of these tools and integrate it right inside the platform. Now you don&amp;#39;t need to spin up a mongo cluster for non-rel data, rabbitmq cluster for queueing, solr box for searching. You can just have a single postgres server. That saves a huge ops headache since each of those clusters/boxes have to be durable, replicated, and scalable.&lt;/p&gt;

&lt;h2&gt;The bad part of using Postgres for everything&lt;/h2&gt;

&lt;p&gt;Now obviously, there&amp;#39;s a glaring downside with this approach: you get one box. Maybe a read slave or something, but really, you can&amp;#39;t scale it. I don&amp;#39;t want to get into pre-optimization here, but one Postgres box is probably fine no matter what you&amp;#39;re doing. If a part starts to underperform, pull it out.&lt;/p&gt;

&lt;p&gt;Making a giant distributed data system is a lot of work though. Pre-optimizing here could certainly compromise your project.&lt;/p&gt;

&lt;p&gt;Backup is also a huge issue with a distributed system. When you have one box, you can go back into any point in time without any issues. Having even one more data system makes backup really hard. In fact, I&amp;#39;m not even sure how you&amp;#39;d do it.&lt;/p&gt;

&lt;p&gt;MySQL has the same problem of having one box, but obviously supports none of these features.&lt;/p&gt;

&lt;h2&gt;More awesome Postgres shit&lt;/h2&gt;

&lt;p&gt;Want more? Schema changes in Postgres can work in a transaction. Rails will use this by default.&lt;/p&gt;

&lt;p&gt;That means that if you make a schema change and it fails, the entire thing aborts. If that happens in MySQL? You&amp;#39;d better have a backup handy.&lt;/p&gt;

&lt;p&gt;Concurrent indexing. With a simple &amp;#39;concurrent&amp;#39; flag in Postgres, you can make adding a column happen without locking the table. It takes a long time but it works.&lt;/p&gt;

&lt;p&gt;Window functions are a feature that lets you create some awesome queries that are impossible in MySQL. It&amp;#39;s a concept that would warrant its own article, &lt;a href="http://postgresguide.com/tips/window.html"&gt;so here&amp;#39;s one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also want to comment that Postgres is now breaking nearly all the database rules I was taught in college. Not BCNF, not 3NF, not 2NF, not even 1NF! (Arrays break 1NF I believe). I always thought those were stupid impractical rules anyways.&lt;/p&gt;

&lt;h2&gt;What about MySQL?&lt;/h2&gt;

&lt;p&gt;Now to address my link-bait:&lt;/p&gt;

&lt;p&gt;MySQL is done. There is no reason to use it anymore. The current state of Postgres blows MySQL out of the water. I don&amp;#39;t see the MySQL community catching up either. Postgres has been solidly improving.&lt;/p&gt;

&lt;p&gt;Performance-wise, it seems to be a wash.&lt;/p&gt;

&lt;p&gt;I seriously want someone to tell me just ONE feature that MySQL has over Postgres. I ask everybody this question, and I haven&amp;#39;t heard a single thing. Yes, Google and Facebook use it, but I don&amp;#39;t really care.&lt;/p&gt;

&lt;h2&gt;I want to use it!&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;re on Rails, you&amp;#39;re in luck. Ryan Bates just posted a &lt;a href="http://railscasts.com/episodes/342-migrating-to-postgresql"&gt;Railscast&lt;/a&gt; on the topic.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/Tmfpe-wMnWA" height="1" width="1"/&gt;</content>
    <summary>Postgres is a relational(-ish) database that&amp;#39;s really starting to become the one-size-fits-all of databases. I think this is very interesting since I wouldn&amp;#39;t have predicted this direction a year ago.</summary>
  <feedburner:origLink>http://dickey.xxx/mysql-is-done-it-s-the-postgres-age</feedburner:origLink></entry>
  <entry>
    <title>Convergence in web development</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/pijKEhNoL9I/convergence-in-web-development" />
    <id>http://dickey.xxx/convergence-in-web-development</id>
    <updated>2012-05-21T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Convergence in web development&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/37/image/000014777263XSmall-82a6ca6a985da672a45f5a7a6ba9fd65.jpg' /&gt;&lt;p&gt;I want to talk about architecture. Specifically, products backed by a server with a thick front-end. The new hot shit. I&amp;#39;m also very Rails focused. Not that you shouldn&amp;#39;t be on something else, but if you are, your life will be less fun attempting this.&lt;/p&gt;

&lt;h2&gt;A little history&lt;/h2&gt;

&lt;p&gt;Right now, the big thing (at least in web dev) is the convergence of the front-end to the back-end. We&amp;#39;ve been here before. First, we had monolithic computers that barely did anything. Then we broke them out into mainframes and thin clients. The mainframes did all the work, and the thin clients were a dumb interface. Personal computing then came next in the 80&amp;#39;s and away from the distributed system. The internet came again in the late 90&amp;#39;s with servers that crunched web pages and computers that browsed them. Again, a dummy interface. Now browsers are fucking awesome. Tools like v8 have empowered javascript to do a ton of awesome things.&lt;/p&gt;

&lt;p&gt;This is nothing new, I just like how computing moves like a pendulum from distributed to non-distributed. I don&amp;#39;t believe one is better than the other.&lt;/p&gt;

&lt;p&gt;Anyways, that&amp;#39;s not my point, what I want to talk about is: &lt;strong&gt;What if you&amp;#39;re making a system today?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Making a convergent system&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m going to make a few assumptions about your product here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need a server. Probably in order to allow users to interact with each other, or give them information not available locally.&lt;/li&gt;
&lt;li&gt;You want to use badass HTML5 stuff on an immersive experience in a single page application.&lt;/li&gt;
&lt;li&gt;You want to be able to fall-back to make everything work sans-js.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now on the server-side, we&amp;#39;ve figured out how to make awesome server side platforms that are very product-focused and scale very well.&lt;/p&gt;

&lt;p&gt;On the front-end, you&amp;#39;ve got jquery to make life easier, as well as some up and coming frameworks like backbone, ember and a million others. It&amp;#39;s new stuff, but there are some solid frameworks.&lt;/p&gt;

&lt;p&gt;The problem? &lt;strong&gt;Getting them to work with each other.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My experience with this problem.&lt;/p&gt;

&lt;p&gt;The biggest experience I had was building an iPad app for Vixely that basically worked like an advanced CMS with many content types users could interact with in limited ways. (voting, saving, etc) I really wanted to find the &lt;em&gt;best&lt;/em&gt; way to make the platforms, and I tried out a few different methods before I settled on a final one.&lt;/p&gt;

&lt;p&gt;I ended up using backbone + rails. I would quantify my experience as a 6/10.&lt;/p&gt;

&lt;h2&gt;Things that went well with backbone + rails&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Asset pipeline. Being able to keep the code together, run the js templates through erb to add in things like image links was invaluable. Making coffeescript, sass and everything work in dev + prod was fantastic. I loved it.&lt;/li&gt;
&lt;li&gt;ActiveAdmin. It&amp;#39;s an admin interface for rails that the editors were in love with. Some came from larger companies and found it very easy to use. I wanted to make sure that it was flexible and easy to use. It was, and I&amp;#39;m so happy I didn&amp;#39;t try to homebrew all that admin stuff.&lt;/li&gt;
&lt;li&gt;Coffeescript. I hate javascript. This made me tolerate the syntax.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are more, but things that go well aren&amp;#39;t as obvious as things that didn&amp;#39;t.&lt;/p&gt;

&lt;h2&gt;Templates make no sense&lt;/h2&gt;

&lt;p&gt;If you know Rails, you know that HTML-ish files are stored in app/views/*. Backbone also has a similar structure to its templates. Problem is, they are different. One has ruby as the underlying language, one has coffee/javascript. One is generated by the server, one is generated on the client. I duplicated a lot of code here, and it was pretty ugly. I&amp;#39;m not going to lie.&lt;/p&gt;

&lt;h2&gt;Scaffolding is insane&lt;/h2&gt;

&lt;p&gt;This is similar to the template problem, but takes place all over. If I have a full server-generated project that you want to add a feature to, it&amp;#39;s common in Rails to add a migration to add the table to the db, a model to interface that table to the code, a controller to view/modify the model, and views to display it. The power in knowing where to put things is huge.&lt;/p&gt;

&lt;p&gt;Backbone works similarly, but the problem is making them work together. If I wanted a new feature, I had to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add migration to db for table&lt;/li&gt;
&lt;li&gt;Add rails model to interface to from controller + view&lt;/li&gt;
&lt;li&gt;Controller to provide json + html endpoints to browse/edit content&lt;/li&gt;
&lt;li&gt;Model serializer &lt;/li&gt;
&lt;li&gt;Views on the server for non-js clients&lt;/li&gt;
&lt;li&gt;Model in backbone to interface with the Rails server&lt;/li&gt;
&lt;li&gt;Backbone route + controller to actual hit the content&lt;/li&gt;
&lt;li&gt;Backbone view controller (Rails has no concept of this) to manage interactions&lt;/li&gt;
&lt;li&gt;Backbone template to render html&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It sucked and felt so dirty.&lt;/p&gt;

&lt;h2&gt;Testing didn&amp;#39;t work&lt;/h2&gt;

&lt;p&gt;Just so we&amp;#39;re on the same page: This is 2012. Don&amp;#39;t skip this if you think you don&amp;#39;t need tests: you do need tests.&lt;/p&gt;

&lt;p&gt;Javascript testing frameworks are nowhere near where Ruby is, no question. There are some around, and they work okay, but it requires a lot more effort. (Well worth it though!) I would bet that the number of JS engineers that test their code vs Ruby is vastly different.&lt;/p&gt;

&lt;p&gt;Once again, making it all work together was really painful. I feel like asset pipeline should offer some support here.&lt;/p&gt;

&lt;h2&gt;Serialization in Rails is broken&lt;/h2&gt;

&lt;p&gt;At Railsconf, Katz spoke a bit about adding serializers to Rails to make Javascript interoperate with server-side code. He proposed making an app/serializers folder with special serializers that define how models should be serialized. I like where he is headed with it, but I think it&amp;#39;s a little too front + center for a Rails project. I doubt that it will end up being in the full framework for mostly that reason.&lt;/p&gt;

&lt;p&gt;I say this without any proposal to make it better. It&amp;#39;s something that needs to be easy, and I don&amp;#39;t think Katz&amp;#39;s method is easy enough. It needs to be laughably easy like most Rails stuff.&lt;/p&gt;

&lt;h2&gt;What to do?&lt;/h2&gt;

&lt;p&gt;That&amp;#39;s the problem, there is no answer right now. A ton of frameworks are claiming to solve it, so evaluate as many as you can reasonably evaluate. Don&amp;#39;t expect too much though. The problem with shitty frameworks is rarely lack of a feature, but just being painful to work with.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/pijKEhNoL9I" height="1" width="1"/&gt;</content>
    <summary>I want to talk about architecture. Specifically, products backed by a server with a thick front-end. The new hot shit. I&amp;#39;m also very Rails focused. Not that you shouldn&amp;#39;t be on something else, but if you are, your life will be less fun attempting this.</summary>
  <feedburner:origLink>http://dickey.xxx/convergence-in-web-development</feedburner:origLink></entry>
  <entry>
    <title>Negativity on Rails</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/j-XO2YGmTVk/negativity-on-rails" />
    <id>http://dickey.xxx/negativity-on-rails</id>
    <updated>2012-04-25T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Negativity on Rails&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/35/image/000016203165XSmall-a4d87df2871c908f23d1ab1ad598b2d9.jpg' /&gt;&lt;p&gt;In attending my first Railsconf, one thing I noticed that I did not expect was a theme of negativity around Rails itself.&lt;/p&gt;

&lt;p&gt;It appears a common message that I seem to get from the various speakers is a negative perception about Rails. Whether it is that there are parts of the code base that are buggy, badly designed code, lack of documentation, disagreements on what/how to improve, the level of issues, the performance of the codebase, it is clear nobody is content with Rails the way it is now.&lt;/p&gt;

&lt;p&gt;To be fair, if you were to ask anyone directly if they thought about Rails, you would get a positive response I bet. Rails vs PHP, or if they thought that Rails was a &amp;#39;good&amp;#39; framework that the answer wouldn&amp;#39;t be surprising. People would be very much pro-Rails. However, that&amp;#39;s not what people are talking about.&lt;/p&gt;

&lt;p&gt;Aaron Patterson&amp;#39;s keynote was specifically about this. He spoke about how using a queueing system with Rails was not straight forward or maintainable as there was no direct interface to manage queues. He also mentioned there was a queueing system inside of Rails called ActiveQueue, that nobody has heard of, let alone implemented. He called for the community to standardize itself and work together to solve that problem.&lt;/p&gt;

&lt;p&gt;I agree with Aaron to a point, but I also feel that having different approaches to queueing provides a sort of Darwinist-software evolution.&lt;/p&gt;

&lt;p&gt;DHH&amp;#39;s keynote was about how Rails will cause bugs and pain for people migrating to newer versions, and how that was unlikely to change moving forward. He said it was necessary in order to keep Rails an amazing framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I think this negativity is fantastic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I think this shows that the community isn&amp;#39;t resting on its laurels. It is self-aware of the problems facing it. Nobody is talking about what they&amp;#39;ve done well, only about how to proceed. This negativity has probably been the driving force improving the framework.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/j-XO2YGmTVk" height="1" width="1"/&gt;</content>
    <summary>In attending my first Railsconf, one thing I noticed that I did not expect was a theme of negativity around Rails itself.</summary>
  <feedburner:origLink>http://dickey.xxx/negativity-on-rails</feedburner:origLink></entry>
  <entry>
    <title>Open source tools</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/sjij0ivoXgo/open-source-tools" />
    <id>http://dickey.xxx/open-source-tools</id>
    <updated>2012-04-19T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Open source tools&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/33/image/wilson-345bcf2a8ee02186a0de2f93819ddbb0.jpeg' /&gt;&lt;p&gt;The octocat above is a rendition of Github&amp;#39;s logo, created by &lt;a href="https://github.com/cameronmcefee"&gt;cameronmcefee&lt;/a&gt; and relevant not only because they exemplify open source, but also since I went to an awesome Giants game last night!&lt;/p&gt;

&lt;p&gt;I&amp;#39;m about to head down to my first Railsconf down in Austin tomorrow, and I&amp;#39;m really giddy about it. I&amp;#39;m a huge fan of Ruby. I sometimes hear people ask what it is that I think is better about Ruby vs other languages. I always like to reply that it&amp;#39;s not the language, it&amp;#39;s the open source community that makes Ruby special.&lt;/p&gt;

&lt;p&gt;The Ruby community is heavily influenced by companies like 37signals (I mean, they did make Rails). Which are really transforming the way business is conducted. If you haven&amp;#39;t read one of their &lt;a href="http://37signals.com/rework/"&gt;books&lt;/a&gt;, I highly recommend it.&lt;/p&gt;

&lt;p&gt;The effect this has on the how Ruby does OSS has shifted more from a technological perspective, and onto a product perspective.&lt;/p&gt;

&lt;h2&gt;Enterprise tools vs open source tools&lt;/h2&gt;

&lt;p&gt;Now, I think that in rapid web application development, there is two different schools of thought in a way. On the one end, you have commercial firms developing tools (e.g. Sencha, ASP.NET), and on the other, open source tools which may or may not be developed by a commercial firm (e.g. Rails, Django).&lt;/p&gt;

&lt;p&gt;The enterprisey type typically involves IDEs, auto-generated code, designers, things that typically sound freaking awesome in some marketing pages, but fall short in practice. They also have a tendency to try and pull you away from the code a bit.&lt;/p&gt;

&lt;p&gt;The open-sourcey type typically involves focuses on text editors as opposed to IDEs, no designers, no stupid graphics, just text and code that works well. It&amp;#39;s developer friendly even if it doesn&amp;#39;t look as sexy. They also drop you straight into the code, leaving little in the way. When it is in the way (as in the case of sass, jquery or activerecord) it&amp;#39;s helpful yet flexible. This is accomplished by having active communities that shape the frameworks as real products get made.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m unabashedly biased here. I think the era of people selling developer tools has ended long ago. It&amp;#39;s often times difficult for me to argue against the enterprise systems since they do market well for sure, but in my experience, they are hell to actually work with.&lt;/p&gt;

&lt;h2&gt;On open source as a whole&lt;/h2&gt;

&lt;p&gt;The best open source projects are by commercial firms that sell their by-products. Some are incredibly well known for it (37signals, ThoughtBot, GitHub). You know what&amp;#39;s crazy about these by-products? They are usually insanely good. The best code I&amp;#39;ve ever seen is virtually come from someone making a paycheck at a respected company and releasing it to the community.&lt;/p&gt;

&lt;p&gt;You can bet that if I am suggesting a gem to my colleagues, and I mention that 37signals created it, their trust in it will increase dramatically.&lt;/p&gt;

&lt;h2&gt;Github&lt;/h2&gt;

&lt;p&gt;Github is the medium that open source is accomplished. It dovetails so well with Ruby&amp;#39;s Bundler dependency manager that I can take an existing project, add a feature to it, and use my version of it in minutes. I can then submit a pull request to the original author to request that my feature get added in. This wasn&amp;#39;t possibly even just a few years ago, and it&amp;#39;s even becoming standard practice with a lot of firms.&lt;/p&gt;

&lt;h2&gt;On Ruby&lt;/h2&gt;

&lt;p&gt;Ruby executed all of this so well. They didn&amp;#39;t invent it, but the focus from making something very tech-oriented (like Linux) to product-oriented has resulted in this amazing era of commercial products with free open source tools to make them.&lt;/p&gt;

&lt;p&gt;For example, there are tools coming out now such as &lt;a href="http://activeadmin.info/"&gt;ActiveAdmin&lt;/a&gt;, or &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; that, while not for everyone, are insanely innovative and easy to use.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been eyeballing Railsconf&amp;#39;s schedule, and I&amp;#39;m disappointed that there are only so many sessions I&amp;#39;m going to. Some of the ones I&amp;#39;m interested in?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practical Machine Learning and Rails&lt;/li&gt;
&lt;li&gt;Ruby on Rails on a Roomba (probably not going to shape the future of the internet too much, although nerds love arduinos)&lt;/li&gt;
&lt;li&gt;Patella: It&amp;#39;s Memoization into Memcached calculated in the background with Resque.&lt;/li&gt;
&lt;li&gt;Basecamp next: Code spelunking&lt;/li&gt;
&lt;li&gt;Katz&amp;#39;s presentation on where Rails should be in the next 5 years!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;A final note&lt;/h2&gt;

&lt;p&gt;I said open source &lt;em&gt;tools&lt;/em&gt; are the future. Not products. Even Github itself is absolutely not an open source product, and shouldn&amp;#39;t be. If you want to actually license Github to run it on your own server? &lt;a href="https://enterprise.github.com/pricing"&gt;$5,000/year&lt;/a&gt;. Even Github itself recognizes that some things work well as open source, and some don&amp;#39;t.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/sjij0ivoXgo" height="1" width="1"/&gt;</content>
    <summary>The octocat above is a rendition of Github&amp;#39;s logo, created by cameronmcefee and relevant not only because they exemplify open source, but also since I went to an awesome Giants game last night!</summary>
  <feedburner:origLink>http://dickey.xxx/open-source-tools</feedburner:origLink></entry>
  <entry>
    <title>The element NoSQL is missing</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/elQtEiL_WZ0/the-element-nosql-is-missing" />
    <id>http://dickey.xxx/the-element-nosql-is-missing</id>
    <updated>2012-01-18T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;The element NoSQL is missing&lt;/h1&gt;&lt;img src='' /&gt;&lt;p&gt;I&amp;#39;m a big fan of NoSQL products. MongoDB, Redis, CouchDB&amp;ndash; it&amp;#39;s really awesome stuff. However, I almost always just use a relational database. I feel much more comfortable with RDBs actually.&lt;/p&gt;

&lt;p&gt;My favorite DB design is when you have a relational database for businessy things (users, money, content) and a fast, scalable store for relationships, transient data and whatever other application logic would benefit best from NoSQL.&lt;/p&gt;

&lt;p&gt;NoSQL is all about the right tool for the job. My assumption is that this implies a system could use several stores.&lt;/p&gt;

&lt;p&gt;I know how to make a system like that work, what the pro&amp;#39;s and con&amp;#39;s of using various db&amp;#39;s are, but there&amp;#39;s one element I am not sure how to handle: &lt;strong&gt;Backup&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I write this article as a question to you: how do you backup two systems? When I have architected this type of design, I have to have one of the following be true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don&amp;#39;t care about backup as one of the stores isn&amp;#39;t critical&lt;/li&gt;
&lt;li&gt;The data in one of the stores can be regenerated&lt;/li&gt;
&lt;li&gt;Concurrency between stores isn&amp;#39;t important&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a reasonably complex system, I doubt any of these would be true. Is there a good, general way to snapshot a whole system across multiple DB&amp;#39;s?&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/elQtEiL_WZ0" height="1" width="1"/&gt;</content>
    <summary>I&amp;#39;m a big fan of NoSQL products. MongoDB, Redis, CouchDB&amp;ndash; it&amp;#39;s really awesome stuff. However, I almost always just use a relational database. I feel much more comfortable with RDBs actually.</summary>
  <feedburner:origLink>http://dickey.xxx/the-element-nosql-is-missing</feedburner:origLink></entry>
  <entry>
    <title>Send email from your domain? Make sure your SPF headers are set.</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/6Y2Kd-QXMMY/email-spf" />
    <id>http://dickey.xxx/email-spf</id>
    <updated>2011-12-16T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Send email from your domain? Make sure your SPF headers are set.&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/31/image/XS-d5ffb5edaf1b87647740c68dca40a3cf.jpg' /&gt;&lt;p&gt;Here&amp;#39;s a quick thing you can do to make sure your email doesn&amp;#39;t end up in spam folders. I&amp;#39;ll keep this simple for people that don&amp;#39;t know much about how email works.&lt;/p&gt;

&lt;p&gt;First of all, go here: &lt;a href="http://www.mxtoolbox.com/spf.aspx"&gt;http://www.mxtoolbox.com/spf.aspx&lt;/a&gt; and check your domain to see if anything shows up for your SPF records.&lt;/p&gt;

&lt;p&gt;You should see something like &amp;#39;v=spf1 include:_spf.google.com ~all&amp;#39; for Google mail. If you don&amp;#39;t see that, follow the rest of this article.&lt;/p&gt;

&lt;h2&gt;The crazy thing about email&lt;/h2&gt;

&lt;p&gt;Most people have no idea that the &amp;#39;from&amp;#39; part of an email has NO built-in security in it whatsoever. I can easily send email pretending to be from any email address I want. I can be &lt;a href="mailto:bill@microsoft.com"&gt;bill@microsoft.com&lt;/a&gt;, &lt;a href="mailto:obama@whitehouse.gov"&gt;obama@whitehouse.gov&lt;/a&gt;, whoever I want.&lt;/p&gt;

&lt;p&gt;As spam became a problem, it was clear that we needed at least some protection against this.&lt;/p&gt;

&lt;p&gt;So one thing that was invented was SPF (sender policy framework) records.&lt;/p&gt;

&lt;h2&gt;What are SPF records?&lt;/h2&gt;

&lt;p&gt;When you get an email, traditionally the incoming server had no way to check to see if the server that sent it was legit.&lt;/p&gt;

&lt;p&gt;As an example, I own a domain through namecheap. I send my email through google. Technically, anyone could setup any server, anywhere to send email through my domain. However, I know that the only legit email server able to send email is google.&lt;/p&gt;

&lt;p&gt;SPF records let me tell anyone that gets my email &amp;quot;If an email gets sent with an @jeffdickey.info account and DIDN&amp;#39;T come from Google, it&amp;#39;s probably not me&amp;quot;.&lt;/p&gt;

&lt;h2&gt;Why fix them?&lt;/h2&gt;

&lt;p&gt;Not having an spf record in place is a huge red flag to incoming email and will result in it ending up in spam folders.&lt;/p&gt;

&lt;p&gt;It also provides security since if anyone sends email through your domain, the spam algorithms will know to flag it as invalid.&lt;/p&gt;

&lt;p&gt;So spend 5 minutes and fix this. Here is instructions for those on Google Apps: &lt;a href="http://support.google.com/a/bin/answer.py?hl=en&amp;amp;answer=33786"&gt;http://support.google.com/a/bin/answer.py?hl=en&amp;amp;answer=33786&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;DKIM&lt;/h2&gt;

&lt;p&gt;When you get done with that, set up DKIM for many of the same reasons: &lt;a href="http://support.google.com/a/bin/answer.py?hl=en&amp;amp;answer=174124"&gt;http://support.google.com/a/bin/answer.py?hl=en&amp;amp;answer=174124&lt;/a&gt;&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/6Y2Kd-QXMMY" height="1" width="1"/&gt;</content>
    <summary>Here&amp;#39;s a quick thing you can do to make sure your email doesn&amp;#39;t end up in spam folders. I&amp;#39;ll keep this simple for people that don&amp;#39;t know much about how email works.</summary>
  <feedburner:origLink>http://dickey.xxx/email-spf</feedburner:origLink></entry>
  <entry>
    <title>Python vs Ruby: Maintainability</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/TF6tvDsCfSc/python-vs-ruby-maintainability" />
    <id>http://dickey.xxx/python-vs-ruby-maintainability</id>
    <updated>2011-12-15T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Python vs Ruby: Maintainability&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/30/image/python-vs-ruby-e945fd82f8790be32911b2fac479eb91-29b5252b373ac3874eb3091dd2c216d7.png' /&gt;&lt;p&gt;One of my favorite subjects is comparing and contrasting tools and frameworks available today. Python and Ruby are probably the big 2 languages right now in web development.&lt;/p&gt;

&lt;p&gt;Now, a language is less important than the framework. However, the language sets the stage for framework&amp;#39;s philosophies. Obviously all frameworks are different, but Django acts like Python and Rails acts like Ruby.&lt;/p&gt;

&lt;p&gt;Writing a full article would be way too much. I&amp;#39;ve used both tools extensively for years. I am totally biased, I much prefer Rails to Django. Django does have its place though, and there are some things that the Python community simply does better.&lt;/p&gt;

&lt;p&gt;Consider this the first in a series of articles comparing the two. This one, will be on the topic of maintainability. Maintainability is how easy it is to change/fix a product after it has been released.&lt;/p&gt;

&lt;h2&gt;Python culture&lt;/h2&gt;

&lt;p&gt;The Python culture is very idealistic. You get a total sense that there is a Right and a Wrong way to do something. Often times they will not have shortcuts you find in other languages, because the culture is very against having multiple ways of doing things.&lt;/p&gt;

&lt;p&gt;The reason for this is readability. Something that Python excels at. I think it&amp;#39;s probably the biggest goal of the Python community: to force readable code. It&amp;#39;s actually difficult to make unreadable Python code.&lt;/p&gt;

&lt;p&gt;It certainly isn&amp;#39;t always concise (compared to Ruby, but very concise to Java/C++). Still, concise and readable are not the same thing.&lt;/p&gt;

&lt;p&gt;Python also has this concept of &amp;#39;Pythonic&amp;#39;, which really means the Right way of doing something. They also have a king: Guido van Rossum. If you&amp;#39;re in a debate with someone about Python, and you can find Guido saying something on the topic, Guido is always right.&lt;/p&gt;

&lt;p&gt;This all moves towards this goal of simplicity and readability. For this reason, Python is without a doubt the easiest language to read. If I had to work on a project with developers I &lt;em&gt;knew&lt;/em&gt; were going to suck, I would push hard for Python.&lt;/p&gt;

&lt;h2&gt;Ruby culture&lt;/h2&gt;

&lt;p&gt;Ruby has an incredible culture. It is similar to Python in some ways, open source is very much encouraged, it&amp;#39;s practical, not run by a corporation, and it&amp;#39;s just flat out an awesome language.&lt;/p&gt;

&lt;p&gt;Backwards compatibility and readability though, definitely are not the main focus of Ruby. It&amp;#39;s important, sure, but it takes the back-seat to productivity.&lt;/p&gt;

&lt;p&gt;Ruby is very, very productive. There may be multiple ways to do things. As an example, with Django, authentication is built into the framework, there is one Right way to do it. Ruby has no built in authentication, and you can either do it yourself, use Warden, Devise, Sorcery or many other options. Each themselves has good and bad things about it, but they all work well.&lt;/p&gt;

&lt;p&gt;You can absolutely get things done faster with Ruby. Especially when it comes to things like caching, nosql, workers. I know Python better than Ruby, but I still work much faster with Ruby.&lt;/p&gt;

&lt;p&gt;Ruby has no king, it has a creator (Matz) but to be honest, I don&amp;#39;t know much about him. I just know he works for Heroku. I&amp;#39;m sure he has a large influence on the community, but not like Guido.&lt;/p&gt;

&lt;p&gt;Maintainability is also mitigated through other means. Rather than focusing on readability, it&amp;#39;s taken care of simply by having less and better code. Also, the heavy focus on test-driven development absolutely reduces the amount of bugs, and can almost remove the chance of regressions.&lt;/p&gt;

&lt;p&gt;I would also argue the gem system is much better than Python&amp;#39;s packages, resulting in making it easier to share code between projects/companies/people. Python has always done this well, but things like Ruby&amp;#39;s Bundler are just way better than anything Python has.&lt;/p&gt;

&lt;p&gt;So in some ways, Ruby just doesn&amp;#39;t need to be as readable to stay maintainable.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;Still, Python wins in maintainability. This is both because the code is readable, and has a heavy emphasis on backwards compatibility.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;maintainability is not everything&lt;/strong&gt;. In fact, I think most developers focus TOO hard on it. Getting the product out the door is absolutely more important.&lt;/p&gt;

&lt;p&gt;Also, while the language helps with maintainability, it&amp;#39;s up to the developer. You can have super maintainable C code, and totally unmaintainable Python code. The language helps, but it is really nothing compared to the engineer.&lt;/p&gt;

&lt;p&gt;My good friend Max Kanat-Alexander said this so well:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python is the easiest language to read, Ruby is the most fun to write.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I could never have said it better myself.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/TF6tvDsCfSc" height="1" width="1"/&gt;</content>
    <summary>One of my favorite subjects is comparing and contrasting tools and frameworks available today. Python and Ruby are probably the big 2 languages right now in web development.</summary>
  <feedburner:origLink>http://dickey.xxx/python-vs-ruby-maintainability</feedburner:origLink></entry>
  <entry>
    <title>Pixelmator rocks</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/VgJU_JPeX7c/pixelmator-rocks" />
    <id>http://dickey.xxx/pixelmator-rocks</id>
    <updated>2011-12-13T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Pixelmator rocks&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/29/image/PixelmatorAppLogo-567a40392e67ae57e793e72c85634f5b.png' /&gt;&lt;p&gt;I love pixelmator. It&amp;#39;s one of the best applications that I own, and I would buy a mac just to use it.&lt;/p&gt;

&lt;p&gt;Pixelmator is an image-editing tool VERY similar to Photoshop. It&amp;#39;s available only on OSX for $30. Photoshop right now is running for $700.&lt;/p&gt;

&lt;p&gt;Don&amp;#39;t let that fool you into thinking you have less value. I would probably STILL use Pixelmator over Photoshop even if you flipped the prices.&lt;/p&gt;

&lt;p&gt;Pixelmator starts way faster, doesn&amp;#39;t use as much memory, it&amp;#39;s easier to use, has a much better UI. It&amp;#39;s better in every way I can see.&lt;/p&gt;

&lt;p&gt;Now, obviously, I am a developer, so my needs are different than a graphic designer&amp;#39;s. However, I still have &lt;strong&gt;needs&lt;/strong&gt; for an image-editing tool. Most of my work is around cropping, resizing, background removal, simple text graphics, and just generic basic editing of existing images. For this, Pixelmator is faster and easier to use.&lt;/p&gt;

&lt;p&gt;I can also open, splice and save my designer&amp;#39;s Photoshop PSD files.&lt;/p&gt;

&lt;p&gt;I hear from people that Pixelmator is not as capable of Photoshop. Since Pixelmator 2.0 came out, there&amp;#39;s nothing I haven&amp;#39;t been able to do that I&amp;#39;ve needed to. As I get more into graphic design, I find that Pixelmator is offering me much better tutorials and guides as well. I think people say that because they&amp;#39;re heartbroken over how much they&amp;#39;ve paid Adobe.&lt;/p&gt;

&lt;p&gt;I don&amp;#39;t care if it&amp;#39;s not what the industry uses, it&amp;#39;s a better tool as far as I&amp;#39;ve ever seen. Don&amp;#39;t let the price-point fool you; we don&amp;#39;t need to be paying hundreds for photo editors.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/VgJU_JPeX7c" height="1" width="1"/&gt;</content>
    <summary>I love pixelmator. It&amp;#39;s one of the best applications that I own, and I would buy a mac just to use it.

Pixelmator is an image-editing tool VERY similar to Photoshop. It&amp;#39;s available only on OSX for $30. Photoshop right now is running for $700.</summary>
  <feedburner:origLink>http://dickey.xxx/pixelmator-rocks</feedburner:origLink></entry>
  <entry>
    <title>Can we fix HTML/CSS/JS syntax?</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/hvt5NFa6gtI/can-we-fix-html-css-js-syntax" />
    <id>http://dickey.xxx/can-we-fix-html-css-js-syntax</id>
    <updated>2011-12-12T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Can we fix HTML/CSS/JS syntax?&lt;/h1&gt;&lt;img src='' /&gt;&lt;p&gt;As in my last post on how we need to stop abstracting, I wanted to talk about the syntax itself of the big 3 web languages, HTML/CSS/JS.&lt;/p&gt;

&lt;p&gt;I use HAML, SASS and CoffeeScript. It might seem like I&amp;#39;m going against my own advice in my last article about abstraction since these are all layers on top of the big 3, but let me explain a bit.&lt;/p&gt;

&lt;p&gt;As I said, abstraction is a tool, that can be helpful and might not be. Syntax alone, I think the big 3 have terrible syntax. HTML is hard to read and verbose, writing straight JS always results in me lining up curly braces and why the hell does CSS have no concept of nesting?&lt;/p&gt;

&lt;p&gt;These issues are easily fixed with HAML, SASS and CoffeeScript. You get beautiful syntax, but they&amp;#39;re still only lightweight abstractions that create code that is very easy to read. I can debug CoffeeScript generated javascript, for example.&lt;/p&gt;

&lt;p&gt;These tools feel like shims to me. As if all the syntaxes could take away some of the ideas (especially css) and use them. Will these syntaxes ever be improved? Will these &amp;#39;shims&amp;#39; become standard practice? They almost are in the Rails community.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/hvt5NFa6gtI" height="1" width="1"/&gt;</content>
    <summary>As in my last post on how we need to stop abstracting, I wanted to talk about the syntax itself of the big 3 web languages, HTML/CSS/JS.</summary>
  <feedburner:origLink>http://dickey.xxx/can-we-fix-html-css-js-syntax</feedburner:origLink></entry>
  <entry>
    <title>We need to stop abstracting</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/P-UiWwS5W00/we-need-to-stop-abstracting" />
    <id>http://dickey.xxx/we-need-to-stop-abstracting</id>
    <updated>2011-12-11T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;We need to stop abstracting&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/27/image/XS-538703004a8cc0ef49df5af278066aa5.jpg' /&gt;&lt;p&gt;Abstraction has been essential to make computing what it is today. Without it, we would all be writing assembly code. Abstraction allows us to think at a higher level and be comfortable the lower level is working well. It promotes reuse of code. It&amp;#39;s a cornerstone of object-oriented programming.&lt;/p&gt;

&lt;p&gt;However, it is a tool like any other. My truck is a tool, and if I want to go to Los Angeles, it&amp;#39;s going to be much more efficient to use it rather than just walking. If I need to go to the kitchen though, it may not prove to be so helpful.&lt;/p&gt;

&lt;h2&gt;Maintainability problem&lt;/h2&gt;

&lt;p&gt;Abstracted code is more difficult to understand than direct code.&lt;/p&gt;

&lt;p&gt;For example, say I have a Python web server. Part of this server needs to turn objects into XML in a fairly standard fashion. Part of the XML contains bits of double formatting that can have a variable number of decimal points and padded zero&amp;#39;s. So you make a function like convert_double_to_xml_format. It takes in various arguments to handle these different options.&lt;/p&gt;

&lt;p&gt;This is abstraction. You&amp;#39;re taking the act of performing string manipulation and putting it into a separate call. You will greatly simplify the character count inside of the XML generation as well.&lt;/p&gt;

&lt;p&gt;However, say a new engineer comes along. If you hadn&amp;#39;t abstracted and simply did the formatting in-line, he would have no trouble understanding exactly what the code is doing. Now that you&amp;#39;ve abstracted, he has to find the file containing the abstraction, figure out it&amp;#39;s intent, and decide how it&amp;#39;s being used at each point.&lt;/p&gt;

&lt;h2&gt;Code duplication&lt;/h2&gt;

&lt;p&gt;The enemy to the modern software engineer: Code duplication. The act of even assuming I might copy and paste some logic to use it somewhere else is a sin.&lt;/p&gt;

&lt;p&gt;I do it every day. I do it more than I even abstract.&lt;/p&gt;

&lt;p&gt;Often times, the 2 code paths will diverge and come completely different things through refactoring anyways, so abstracting would never have worked. Other times, the code is just more readable. While you can argue that this is prone to bugs and complicates change, the fact that anyone can pick it up and understand it immediately is a totally valid trade-off.&lt;/p&gt;

&lt;p&gt;We generally don&amp;#39;t acknowledge the cost of having logic in 2 separate files. Python helps with the imports at the top of a file, but most languages offer little help here. Readability is always more important than abstraction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstraction is only helpful if you understand how the abstraction itself works.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;1% of the problems take 90% of the time&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ve heard this many times. It is absolutely not true. Engineers working with dinosaur frameworks will say this, and for them it is true. Abstraction is the reason for this.&lt;/p&gt;

&lt;p&gt;If a framework is abstracting something out for you, then it needs to account for your business problem before you do. In exactly the same way. Obviously in the enterprise, this is more common than someone like me in consumer web, but I refuse to believe that any framework can solve even simple business problems with entirely pre-built solutions.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s why that 1% takes so long.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/P-UiWwS5W00" height="1" width="1"/&gt;</content>
    <summary>Abstraction has been essential to make computing what it is today. Without it, we would all be writing assembly code. Abstraction allows us to think at a higher level and be comfortable the lower level is working well. It promotes reuse of code. It&amp;#39;s a cornerstone of object-oriented programming.</summary>
  <feedburner:origLink>http://dickey.xxx/we-need-to-stop-abstracting</feedburner:origLink></entry>
  <entry>
    <title>Keep your project running locally</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/V_Jmc-XrCXk/keep-your-project-running-locally" />
    <id>http://dickey.xxx/keep-your-project-running-locally</id>
    <updated>2011-12-07T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Keep your project running locally&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/26/image/XS-ae2ebbdeb09c741c2ef068d3b11a1031.jpg' /&gt;&lt;p&gt;Every web project starts out with the best intentions, running locally, unit testing, easy deployments, provisioning of servers. As a project moves on, some of these niceties drop by the wayside, specifically: The ability to run locally.&lt;/p&gt;

&lt;p&gt;Never let this happen to a project. You cannot afford the cost of it.&lt;/p&gt;

&lt;p&gt;It happens to all projects for the same reason. You have some bug you need to fix, or are working on some feature that NEEDS to get out and you decide to just fire up vim on staging/production, fix it and make the change later.&lt;/p&gt;

&lt;p&gt;Eventually, (and it doesn&amp;#39;t take long) this creates an environment that cannot be run on a local machine. It&amp;#39;s even more likely to happen if you&amp;#39;re on Windows.&lt;/p&gt;

&lt;p&gt;There may be other things to consider though. Servers are almost always a different operating system and have different dependencies. They probably aren&amp;#39;t capable of provisioning themselves automatically. The dev environments also might need to run a separate process (like a worker thread, or solr or something)&lt;/p&gt;

&lt;p&gt;Keeping the project running on the dev&amp;#39;s boxes is no easy task.&lt;/p&gt;

&lt;h2&gt;Why is a project running locally so important?&lt;/h2&gt;

&lt;p&gt;When a project can only be run on a server, you have to do a few things you wouldn&amp;#39;t have to do on a local box.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Generally) you can&amp;#39;t have your own text editor setup, especially if the text editor of choice isn&amp;#39;t a console one&lt;/li&gt;
&lt;li&gt;You&amp;#39;re probably not using automated tests&lt;/li&gt;
&lt;li&gt;Someone else deploys to that server, all your work is gone&lt;/li&gt;
&lt;li&gt;You have to SSH in&lt;/li&gt;
&lt;li&gt;Somehow you have to transfer files back and forth. Most devs will use their own memory or copy-paste, better devs will use rsync, but even rsync sucks here&lt;/li&gt;
&lt;li&gt;Restart the server after a change (or enable code-reloading)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, everything takes more time. When I code like this, I&amp;#39;m probably less than half as efficient as I could be. Not so much the extra steps, this is the sort of thing that &lt;strong&gt;makes an engineer&amp;#39;s life miserable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most companies I&amp;#39;ve worked at have had this problem, and it&amp;#39;s one of the things that ultimately made me quit working for them. Perks and money are nice, but having to go through this everyday is something that I personally cannot deal with for very long. It tears apart my sanity.&lt;/p&gt;

&lt;p&gt;This will immensely help with onboarding. Since new engineers won&amp;#39;t have to be brought up to speed with as much. They can also be comfortable messing around in their own environment.&lt;/p&gt;

&lt;h2&gt;How can you avoid this problem?&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ll be honest, it&amp;#39;s not easy to avoid this problem. It takes serious dedication and willpower. Again though, it&amp;#39;s not worth it to give up on.&lt;/p&gt;

&lt;p&gt;Here&amp;#39;s what you need to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be able to create a new dev environment very easy&lt;/li&gt;
&lt;li&gt;Be able to provision new servers easily&lt;/li&gt;
&lt;li&gt;Make production as close to the development environment as possible&lt;/li&gt;
&lt;li&gt;Use code-reloading on the development environment&lt;/li&gt;
&lt;li&gt;Use git&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There&amp;#39;s some tools out there to help with this. The ones I&amp;#39;m going to mention are all ruby-focused, but I know many python and php developers that use them and they work great.&lt;/p&gt;

&lt;h2&gt;Vagrant&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt; is sort of a command-line wrapper around virtualbox. Sounds totally boring and useless, but it&amp;#39;s designed &lt;em&gt;specifically&lt;/em&gt; to tack most of the problems I just mentioned. It can not only start up a vanilla linux distro in 2 commands, but it can provision them as well!&lt;/p&gt;

&lt;p&gt;So if you have a Vagrantfile in the root of your project, a new developer only has to type &amp;#39;vagrant up&amp;#39; into the command line, and they&amp;#39;ll have the ability to run a fully provisioned, ready to go production-like environment.&lt;/p&gt;

&lt;p&gt;It will also link the local project directory to one at /vagrant on the box, so any changes made locally take immediate effect on the box. It also sets up port forwarding so you can just hit 127.0.0.1:3000 and you&amp;#39;ll be hitting the vm.&lt;/p&gt;

&lt;p&gt;It can use either a bash script, or chef or puppet (or a combination) for the provisioning.&lt;/p&gt;

&lt;p&gt;I don&amp;#39;t use it on every project, it does take time to setup. Most of my projects will run just fine over osx. However, if you&amp;#39;re on Windows, you NEED this.&lt;/p&gt;

&lt;p&gt;You can also mess around with crazy things like updating all your gems, trying out the next version of django, whatever you want. &lt;strong&gt;You feel comfortable knowing you can destroy the whole environment and regenerate it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another bonus: Whether you use chef, puppet or a straight file, you&amp;#39;ve got the ability to provision a production machine as well. Load up a new ec2 install, run the provisioner against it and you&amp;#39;ve got a production ready machine that works just like the dev environment.&lt;/p&gt;

&lt;h2&gt;Chef + Puppet&lt;/h2&gt;

&lt;p&gt;Chef and Puppet are the new big deals in the unix community. They provision servers. I&amp;#39;ve used both, and hated both. They&amp;#39;re difficult to learn in my opinion. I have used both enough to get by, but it&amp;#39;s not an enjoyable experience like I feel like it should be.&lt;/p&gt;

&lt;p&gt;I probably just need to learn them better.&lt;/p&gt;

&lt;p&gt;Still, they&amp;#39;re the best out there I know of for you&amp;#39;re provisioning servers.&lt;/p&gt;

&lt;h2&gt;Capistrano + Fabric&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/capistrano/capistrano/wiki/"&gt;Capistrano&lt;/a&gt; and &lt;a href="http://docs.fabfile.org/en/1.3.3/index.html"&gt;Fabric&lt;/a&gt; are deployment tools. When your server has been provisioned, run these to deploy/start/stop/migrate dbs, whatever you might need. Use one of them.&lt;/p&gt;

&lt;h2&gt;Foreman&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ddollar/foreman"&gt;Foreman&lt;/a&gt; is VERY simple. All it does is let you have a file like this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;web:    bundle exec thin start -p $PORT
worker: bundle exec rake resque:work QUEUE=*
clock:  bundle exec rake resque:scheduler
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if you run &amp;#39;foreman start&amp;#39; at the command line, it&amp;#39;ll run like this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://f.cl.ly/items/0U0X0T0C1e212Z3d290e/png.png" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image from &lt;a href="http://blog.daviddollar.org/2011/05/06/introducing-foreman.html"&gt;David Dollar&amp;#39;s Introducing Foreman&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Easy way to ensure that the server is being started the same way by everyone, and all the dependencies get started as well. This is so you don&amp;#39;t have to have an extra command window open for your worker server.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;As many people know I am a big fan of Heroku. One of my favorite things about Heroku is you &lt;em&gt;cannot&lt;/em&gt; access the server. I know a lot of engineers that would see this as a drawback, but I see it as prevention against me shooting myself in my foot.&lt;/p&gt;

&lt;p&gt;So there is some tips on the worst thing a project can do to an engineer. Like I said, these are not easy problems to solve, which is why I only told you what the tools you need are and where to find more information on them.&lt;/p&gt;

&lt;p&gt;Spend the time to use them and learn them, it&amp;#39;s worth it.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/V_Jmc-XrCXk" height="1" width="1"/&gt;</content>
    <summary>Every web project starts out with the best intentions, running locally, unit testing, easy deployments, provisioning of servers. As a project moves on, some of these niceties drop by the wayside, specifically: The ability to run locally.</summary>
  <feedburner:origLink>http://dickey.xxx/keep-your-project-running-locally</feedburner:origLink></entry>
  <entry>
    <title>Cache correctly: stop invalidating</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/xF0UglH__SM/cache-correctly-stop-invalidating" />
    <id>http://dickey.xxx/cache-correctly-stop-invalidating</id>
    <updated>2011-12-04T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Cache correctly: stop invalidating&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/24/image/XS-6214ee4af9255791b37bf91102ab7516.jpg' /&gt;&lt;blockquote&gt;
&lt;p&gt;There are only two hard problems in Computer Science: cache invalidation and naming things. - Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One of my favorite things about Rails is that when I read the docs, sometimes I find little gems that just jump out and make me cheer with happiness.&lt;/p&gt;

&lt;p&gt;ActiveModel&amp;#39;s cache_key method is one of these things.&lt;/p&gt;

&lt;h2&gt;Let me explain&lt;/h2&gt;

&lt;p&gt;On my blog, I write the body in markdown. I have a method on the model (not a helper, like it probably should be) called body_html that takes the blog&amp;#39;s body and converts the markdown into html. In a given view, I call this a couple times, once for the body, but also for the description meta tags.&lt;/p&gt;

&lt;p&gt;It would be nice to only have to perform this computationally intensive operation once, then cache it for later use.&lt;/p&gt;

&lt;p&gt;In Django, which is where I was before Rails, I&amp;#39;ve had to implement caching on some serious systems. Django has much less syntax sugar around caching. If I had to implement this in Django, I would&amp;#39;ve done the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class="python"&gt;def body_html(self):
    body_html = cache.get(&amp;#39;article:&amp;#39; + self.id + &amp;#39;:body_html&amp;#39;)
    if not body_html:
        body_html = markdown(self.body)
        cache.set(&amp;#39;article:&amp;#39; + self.id + &amp;#39;:body_html&amp;#39;, body_html)
    return body_html
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What this does is attempts to get the cache for the key &amp;#39;article:[id]:body_html&amp;#39;. If it can&amp;#39;t find it, it converts the body into markdown, then saves it into memcache for later use.&lt;/p&gt;

&lt;p&gt;This works great, until you change the text.&lt;/p&gt;

&lt;p&gt;Now Django will be pulling in the stale html out of memcache instead of updating itself.&lt;/p&gt;

&lt;p&gt;So what do you do?&lt;/p&gt;

&lt;p&gt;You could set an expiration time of say, 10 minutes, but this is somewhat inefficient since it&amp;#39;ll update when it doesn&amp;#39;t need to, and you can&amp;#39;t see your changes right away.&lt;/p&gt;

&lt;p&gt;You could use a signal on the model to reset the cache at that html. (But as anyone that&amp;#39;s used Django intensively can tell you, signals are flaky at best). You&amp;#39;d also need to be super careful you&amp;#39;re never bypassing the signals or anything.&lt;/p&gt;

&lt;p&gt;Like the quote at the top, cache invalidation is very hard. Not hard to do, you just call cache.delete. Hard because it&amp;#39;s not obvious WHERE to invalidate the cache.&lt;/p&gt;

&lt;p&gt;So what genius does Rails provide here? The &lt;a href="http://apidock.com/rails/ActiveRecord/Base/cache_key"&gt;cache_key&lt;/a&gt;. The cache_key, unlike my lame cache key I would&amp;#39;ve used with Django &amp;#39;article:[id]&amp;#39; includes the timestamp of the last updated time of the model, so something like: &amp;#39;article/5-20071224150000&amp;#39; instead.&lt;/p&gt;

&lt;p&gt;This makes it so if the model is updated, the cache_key will never get hit again!&lt;/p&gt;

&lt;p&gt;You would use it, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;def body_html
  Rails.cache.fetch &amp;quot;#{cache_key}/body_html&amp;quot; do
    markdown(body)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: you have to have an updated_at column on the db table for this to work, but rails will add one to all table migrations by default.&lt;/p&gt;

&lt;p&gt;My first reaction was, &amp;#39;well, how would I invalidate it if I can never reference it again?&amp;#39; but you don&amp;#39;t need to.&lt;/p&gt;

&lt;p&gt;Memcache is an LRU cache (probably don&amp;#39;t want to use this pattern on a cache backend that isn&amp;#39;t). So if the cache fills up, it&amp;#39;ll just dump things that haven&amp;#39;t been accessed in a long time.&lt;/p&gt;

&lt;p&gt;Obviously this isn&amp;#39;t limited to Rails, but I never thought to use the timestamp before. Maybe this is something everyone knows (it seems obvious). But I really wish I would&amp;#39;ve learned this trick earlier.&lt;/p&gt;

&lt;p&gt;I would argue the best form of cache invalidation is this. Don&amp;#39;t invalidate if you can help it, just alter the cache key.&lt;/p&gt;

&lt;p&gt;Won&amp;#39;t work for all cases, but it&amp;#39;s a nice pattern for most.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/xF0UglH__SM" height="1" width="1"/&gt;</content>
    <summary>
There are only two hard problems in Computer Science: cache invalidation and naming things. - Phil Karlton


One of my favorite things about Rails is that when I read the docs, sometimes I find little gems that just jump out and make me cheer with happiness.</summary>
  <feedburner:origLink>http://dickey.xxx/cache-correctly-stop-invalidating</feedburner:origLink></entry>
  <entry>
    <title>Commenting systems: Disqus vs Livefyre</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/4izt6Az4sNs/disqus-vs-livefyre" />
    <id>http://dickey.xxx/disqus-vs-livefyre</id>
    <updated>2011-12-03T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Commenting systems: Disqus vs Livefyre&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/23/image/XS-3951ae9b6bb1f59a351d0dd35bdac958.jpg' /&gt;&lt;p&gt;Commenting systems are the big thing nowadays. I think pretty much all sites should use something rather than rolling their own.&lt;/p&gt;

&lt;p&gt;I chose to look at 2 that I&amp;#39;ve had experience with. There is also another one I have not yet used called &lt;a href="http://intensedebate.com/home"&gt;Intense Debate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So here it is, my review of the 2 site plugins with the worst names in existence.&lt;/p&gt;

&lt;h2&gt;Why are these tools better than having your own commenting system?&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Low barrier of entry for readers to comment&lt;/li&gt;
&lt;li&gt;Users may already have an account with the service&lt;/li&gt;
&lt;li&gt;Spam and moderation is much easier to manage&lt;/li&gt;
&lt;li&gt;Offloads work from the server&lt;/li&gt;
&lt;li&gt;Very easy to install&lt;/li&gt;
&lt;li&gt;Can show feedback that is happening on social networks&lt;/li&gt;
&lt;li&gt;Sorts comments by popularity and importance rather than recency&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Disqus&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m somewhat familiar with Disqus for other reasons. &lt;a href="http://justcramer.com/"&gt;David Cramer&lt;/a&gt; is active in the Python/Django community and has built some awesome open source tools. So when the time came to integrate comments on my site, Disqus was the first thing I thought of.&lt;/p&gt;

&lt;p&gt;Disqus is also very popular. You see it everywhere. This means it&amp;#39;s likely users will already have an account and be more likely to comment.&lt;/p&gt;

&lt;p&gt;The setup process was easy. I did a bit of work afterwards to setup some things like enabling local support, linking to the article rather than the url, and highlighting my own name on the comments so the readers can easily see my replies.&lt;/p&gt;

&lt;p&gt;I love the design, and it is really easy to customize. The moderation tools are top-notch as well.&lt;/p&gt;

&lt;p&gt;It went well. I really only have 2 complaints about Disqus.&lt;/p&gt;

&lt;p&gt;First, since I use slugs for my articles, sometimes I change the names of them while I&amp;#39;m still writing them. When I do this, it messes up disqus a bit. The comments are still there, but users will get an email to the article at an old slug. This is really annoying and causes me to have to manually update the urls in their system (which requires uploading a csv for updates). It&amp;#39;s really annoying.&lt;/p&gt;

&lt;p&gt;I could remove the hard link via the article id&amp;#39;s, but if I did that, the comments wouldn&amp;#39;t show on my local box, and if I ever wanted to change a name after people started commenting, it would be lost.&lt;/p&gt;

&lt;p&gt;My other issue with Disqus is that it&amp;#39;s slow. Most of my site&amp;#39;s total loading time of pages is with Disqus. The CSS stylesheet they use very inefficient. There may be more problems with their speed, but &lt;a href="http://f.cl.ly/items/2J2T2S1n2e3F3H1K090k/disqus-css-fail.html"&gt;this&lt;/a&gt; is most likely a huge cause of the slow performance.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s not so bad since it&amp;#39;s on the bottom of my page. However, I like having an all-around fast site, and Disqus makes that impossible.&lt;/p&gt;

&lt;h2&gt;Livefyre&lt;/h2&gt;

&lt;p&gt;I tried out Livefyre today. They have a few more features that Disqus does not. The biggest difference between the two is that they really focus on heavy social functionality. I hear it works well and has good results in creating a lively community.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tagging of people on AND off the site. This can bring people into the site directly in the comments&lt;/li&gt;
&lt;li&gt;Captures conversations on twitter and facebook to bring all the conversation into the site&lt;/li&gt;
&lt;li&gt;LinkedIn integration, this is important for my audience&lt;/li&gt;
&lt;li&gt;Search engine crawlable, this is pretty cool too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don&amp;#39;t think it is wrong to argue that Livefyre has more features than Disqus.&lt;/p&gt;

&lt;p&gt;So I decided to integrate livefyre on my blog to test it out.&lt;/p&gt;

&lt;p&gt;The setup process was really easy. A little too easy though, let me explain. It&amp;#39;s a 2 step process, put in your url, paste a simple code. You can get it running very quickly. Problem is, it doesn&amp;#39;t tell you how to customize it. On Disqus, it was easy to define the article id and name, but with Livefyre they gave no indication on how to do either of these things. In fact, I&amp;#39;m still not sure if I can define the article name. They probably use the site title, but I would rather not use that since I always append &amp;#39;by Jeff Dickey&amp;#39; on my site title.&lt;/p&gt;

&lt;p&gt;I looked through the support on their site and found nothing. They have no documentation. Maybe they figure they don&amp;#39;t need documentation because they&amp;#39;re so easy to use?&lt;/p&gt;

&lt;p&gt;Well, they&amp;#39;re wrong, they definitely do need &lt;em&gt;some&lt;/em&gt; docs. Preferably a link to them after the setup process. For getting the site to link to the article id&amp;#39;s rather than the URL, I eventually guessed how to do it and got right. I sent in the key &amp;#39;article_id&amp;#39; in the initializer, but that was a lucky freaking guess.&lt;/p&gt;

&lt;p&gt;It also dumps a ton of console.log statements into the console. That might be okay if I wanted to debug Livefyre, or just didn&amp;#39;t care, but if I had a javascript heavy app, that would be truly annoying.&lt;/p&gt;

&lt;p&gt;It has no support for running the commenting system locally either. Disqus does this and clearly describes how to do it. I had to push it up to production and &amp;#39;hope&amp;#39; it didn&amp;#39;t break. (Oh and get this, it DID break)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is definitely up there with the least developer friendly tool I&amp;#39;ve ever integrated on a site.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How developer-friendly a product is does not make or break a company, but you can bet after my experience how I would feel about suggesting a tool like this to a client.&lt;/p&gt;

&lt;p&gt;The design in their internal site is odd too. Parts of it are pretty good, but then they had shit like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://f.cl.ly/items/053q0I31200b25110C1L/Screen%20Shot%202011-12-01%20at%207.51.51%20PM.png"&gt;&lt;img src="http://f.cl.ly/items/053q0I31200b25110C1L/Screen%20Shot%202011-12-01%20at%207.51.51%20PM.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More inability to line up things:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://f.cl.ly/items/0W2J2d1y2B3Z2F1l3e2U/Screen%20Shot%202011-12-01%20at%208.01.50%20PM.png"&gt;&lt;img src="http://f.cl.ly/items/0W2J2d1y2B3Z2F1l3e2U/Screen%20Shot%202011-12-01%20at%208.01.50%20PM.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, while browsing around on their site and clicking the Log In button, I got this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://f.cl.ly/items/0x2K3i462M2B182S211w/Screen%20Shot%202011-12-01%20at%207.56.59%20PM.png"&gt;&lt;img src="http://f.cl.ly/items/0x2K3i462M2B182S211w/Screen%20Shot%202011-12-01%20at%207.56.59%20PM.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calling me a &amp;#39;punk&amp;#39; for clicking your login button? You do have a &amp;#39;dumb site&amp;#39;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;404 is the wrong error code from that description anyways. It should be 401 or 403. For someone that has worked on a lot of web sites, this is actually a clue into their system. 404&amp;#39;s should be handled very differently than access denied codes. No matter what framework or platform they are on, this is telling me that they&amp;#39;re totally reinventing the wheel with authentication, and that wheel is looking pretty square.&lt;/p&gt;

&lt;p&gt;Obviously, I&amp;#39;m only drawing conclusions based on very small bits of what I&amp;#39;ve seen, but I would put money on Livefyre&amp;#39;s code-base being just as flaky as their design. Disqus, on the other hand, I have seen their code (gargoyle and sentry), used it in production systems, and it&amp;#39;s excellent.&lt;/p&gt;

&lt;p&gt;The entire system feels unfinished. Maybe some of those design details seem small, but as a whole it feels really chintzy. Running into a bug when I click login did not help my stance on that.&lt;/p&gt;

&lt;p&gt;The UX is terrible. To get to my site&amp;#39;s moderation takes a ton of hunting. Like I said, I also never found a way to configure the code.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s safe to say that I did not like the process of integrating Livefyre. Not at all. Disqus was good, not perfect, but good. I&amp;#39;ve yet to use Livefyre to actually moderate, but based on what I&amp;#39;ve seen so far, I&amp;#39;m not terribly excited about moderating.&lt;/p&gt;

&lt;p&gt;I love the direction they are going. They seem to be ahead of the market as far as the product vision goes. It&amp;#39;s a shame the product is in the state that it is in.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;So I&amp;#39;ve yet to use Livefyre in-depth, but so far I feel like Disqus is the better option. Even though it&amp;#39;s slow and has a bug that bothers me. It has a larger user base, I like the onboarding more, the design is much better. As an engineer, it genuinely &lt;em&gt;feels&lt;/em&gt; more solid and reliable.&lt;/p&gt;

&lt;p&gt;I could be swayed depending on how this social interaction that Livefyre has works out. If I find that people seem to chat much more with Livefyre, it may be the better option.&lt;/p&gt;

&lt;p&gt;So I&amp;#39;m A/B testing them both, you&amp;#39;ll see some articles with disqus, and some with livefyre. I&amp;#39;m just going to see what works out better!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; And would you look at that, I try and actually use Livefyre on my site, and it thinks it&amp;#39;s running locally, actually, it&amp;#39;s not even the right article! It thinks it&amp;#39;s the Redis article. I have no idea how that even happened. The ID for this article was always correct. (Post a comment and see the url that it thinks the site is at). This is similar to the problem I had with Disqus, except that with Livefyre I have no clue how to fix it. I don&amp;#39;t even think it is fixable. That was probably my last straw for that pathetic commenting system.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/4izt6Az4sNs" height="1" width="1"/&gt;</content>
    <summary>Commenting systems are the big thing nowadays. I think pretty much all sites should use something rather than rolling their own.</summary>
  <feedburner:origLink>http://dickey.xxx/disqus-vs-livefyre</feedburner:origLink></entry>
  <entry>
    <title>CloudFront vs CloudFlare: We have a winner.</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/9EcRqJxE8f0/cloudfront-vs-cloudflare" />
    <id>http://dickey.xxx/cloudfront-vs-cloudflare</id>
    <updated>2011-12-02T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;CloudFront vs CloudFlare: We have a winner.&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/22/image/cloudflare-main-41ed9f6663e1f8bac02337d4e2d70e81.png' /&gt;&lt;p&gt;&lt;em&gt;This a follow-up to &lt;a href="http://jeffdickey.info/cloudflare-review-not-snake-oil-but-it-feels-like-it"&gt;my first post&lt;/a&gt; on CloudFlare. This will make more sense if you read that one first.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;John from CloudFlare was kind enough to invite me (well, technically I kind of invited myself) down to the CloudFlare offices. Conveniently located just a few blocks from where I&amp;#39;m working! Gotta love San Francisco&amp;#39;s SOMA district. We talked about my earlier post.&lt;/p&gt;

&lt;p&gt;I gotta say, everything from configuring CloudFlare on my system, to writing up the first article, to visiting their office has been incredibly fun. I&amp;#39;ve really enjoyed it.&lt;/p&gt;

&lt;h2&gt;On the snake oil&lt;/h2&gt;

&lt;p&gt;As you remember from my first post, I had a big issue with CloudFlare. I couldn&amp;#39;t quite put my finger on it, but it sort of just felt like marketing spam. &lt;a href="http://amix.dk/blog/post/19627"&gt;I&amp;#39;m also not the only one.&lt;/a&gt; The odd thing was, I couldn&amp;#39;t find anything they were actually doing wrong. Now, I think I&amp;#39;ve decided what my problem was:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They&amp;#39;re just too damn cheap.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I worked with a client once that was paying thousands/month on their CDN through EdgeCast. I found it incredibly hard to believe that CloudFlare would be willing to provide a similar service for absolutely nothing. Yet, there they are.&lt;/p&gt;

&lt;p&gt;Most of my conversation was trying to find some loophole where you would have to start paying more if you were really hammering their system. John mentioned they have several high profile sites (such as 4chan, youm7, the 6th largest site in Egypt, nerdlist, and laughingsquid) that are on their system. They have &amp;gt;100,000 sites, which makes them much bigger than I imagined. He said that some of the high-end clients to pay a bit more, but that&amp;#39;s for an SLA, not bandwidth.&lt;/p&gt;

&lt;p&gt;He said a few times the pro package was working well for them. Even at 20 bucks/month. No matter how big you are.&lt;/p&gt;

&lt;p&gt;I had some concerns that CloudFlare might increase it&amp;#39;s rate and remove it&amp;#39;s free plans. John assured me they will be adding more pricing tiers, but they will not be removing, or taking away functionality from the free plan. Still though, even if they did dramatically increase their rates, there is no vendor lock-in. It would be trivial to switch over to another CDN.&lt;/p&gt;

&lt;p&gt;I still don&amp;#39;t understand how a company could have a 2k/month EdgeCast bill, and CloudFlare would be willing to let them on for free with the basic features. If this is working for them, either the other CDNs are totally overcharging, or CloudFlare is just running so efficiently internally that it&amp;#39;s not necessary to charge more than they are.&lt;/p&gt;

&lt;h2&gt;On stability&lt;/h2&gt;

&lt;p&gt;Now, Andrew Lippert has a great &lt;a href="http://jeffdickey.info/cloudflare-review-not-snake-oil-but-it-feels-like-it#comment-376081653"&gt;comment&lt;/a&gt; on the original post. John mentioned that he knew Andrew quite well, and that Andrew has been very active in the community for CloudFlare. &lt;a href="http://jeffdickey.info/cloudflare-review-not-snake-oil-but-it-feels-like-it#comment-376193862"&gt;John replied to Andrew directly on the same post.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I won&amp;#39;t reiterate what they said on there. I also cannot comment on the stability of CloudFlare as I have not had any downtime myself. &lt;em&gt;Their&lt;/em&gt; site did have a lot of slow responses and timeouts while I was using yesterday, but mine has been fine. It&amp;#39;s only been 24 hours though, so who knows. John did mention that they&amp;#39;re working hard to make sure the platform is incredibly stable.&lt;/p&gt;

&lt;h2&gt;On the security&lt;/h2&gt;

&lt;p&gt;One of the interesting problems CloudFlare has is they can&amp;#39;t quite find their core value. Are they a CDN? Are they a security company? Something else? It&amp;#39;s hard to tell, they do all these things.&lt;/p&gt;

&lt;p&gt;I didn&amp;#39;t mention the security much in my last article. This is really only because on my blog I don&amp;#39;t really care.&lt;/p&gt;

&lt;p&gt;What I do find odd though, is that according to them 21% of the traffic to my site is &amp;#39;threats by attackers&amp;#39;. From reading my logs... I find this hard to believe. I&amp;#39;m wondering how much of that is false positives.&lt;/p&gt;

&lt;p&gt;One neat feature he mentioned is it actually is looking at sql injection and xss attacks that might be coming across. As you&amp;#39;ll see in my &lt;a href="http://jeffdickey.info/what-would-a-web-engineer-certification-look-like"&gt;security article&lt;/a&gt;, I&amp;#39;m a big fan of another layer of prevention for this.&lt;/p&gt;

&lt;h2&gt;Now the big comparison: CloudFront vs CloudFlare&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s hard to not choose CloudFlare here. Here&amp;#39;s what CloudFlare has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Much better interface&lt;/li&gt;
&lt;li&gt;Much easier to setup&lt;/li&gt;
&lt;li&gt;Can optimize many things not related to just static assets&lt;/li&gt;
&lt;li&gt;Security preventions (CloudFront, being solely a CDN has none of this)&lt;/li&gt;
&lt;li&gt;Analytics to measure how well the CDN is helping your server&lt;/li&gt;
&lt;li&gt;It&amp;#39;s freaking free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What about CloudFront? I can&amp;#39;t think of much, I would appreciate thoughts in the comments.&lt;/p&gt;

&lt;p&gt;The only thing I can think of is that CloudFront has much more control. If you need to invalidate cache on an individual asset, for example, CloudFlare can&amp;#39;t do this (but John specifically mentioned this is coming). I imagine there might be similar issues such as this, but I can&amp;#39;t think of any else to be honest.&lt;/p&gt;

&lt;p&gt;There is a Client API for CloudFlare I did not know about in the previous article: &lt;a href="http://www.cloudflare.com/wiki/Client_Interface_API"&gt;http://www.cloudflare.com/wiki/Client_Interface_API&lt;/a&gt; I wouldn&amp;#39;t call it extensive, but it&amp;#39;s nice they&amp;#39;ve got something to potentially build out. There is some neat things in there though, like querying for search terms hitting the site.&lt;/p&gt;

&lt;p&gt;The lack of control is intentional on CloudFlare&amp;#39;s side though, they don&amp;#39;t want you to have to think about things like that.&lt;/p&gt;

&lt;h2&gt;In summary&lt;/h2&gt;

&lt;p&gt;John asked me if there would be any reason I wouldn&amp;#39;t go with their system in the future. To be honest, I couldn&amp;#39;t think of one. CloudFlare is providing an excellent service for nothing (or next to nothing). It&amp;#39;s also packed with a million times more features than any other CDN.&lt;/p&gt;

&lt;p&gt;Bye CloudFront, I&amp;#39;m going the free route. &lt;a href="https://github.com/dickeytk/blog/commit/1f2d8eb96d3321a6b8aa13c47a5678b883c8aaed"&gt;Here&amp;#39;s the proof.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Bonus: S3 and CloudFlare how-to&lt;/h2&gt;

&lt;p&gt;I hate to turn this into a how-to, but I did get my question on how to get S3 working with CloudFlare working. It&amp;#39;s so easy it doesn&amp;#39;t warrant it&amp;#39;s own how-to:&lt;/p&gt;

&lt;p&gt;Just make your s3 bucket the full host you want. For example, for me it was &amp;#39;content.jeffdickey.info&amp;#39;. Then set your DNS CNAME in CloudFlare to &amp;#39;content.jeffdickey.info.s3.amazonaws.com&amp;#39; (obviously replacing my bucket name with yours). Then you&amp;#39;ll be good to go.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/9EcRqJxE8f0" height="1" width="1"/&gt;</content>
    <summary>This a follow-up to my first post on CloudFlare. This will make more sense if you read that one first.

John from CloudFlare was kind enough to invite me (well, technically I kind of invited myself) down to the CloudFlare offices. Conveniently located just a few blocks from where I&amp;#39;m working! Gotta love San Francisco&amp;#39;s SOMA district. We talked about my earlier post.</summary>
  <feedburner:origLink>http://dickey.xxx/cloudfront-vs-cloudflare</feedburner:origLink></entry>
  <entry>
    <title>What would a web engineer certification look like?</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/nmfSVEtmjG4/what-would-a-web-engineer-certification-look-like" />
    <id>http://dickey.xxx/what-would-a-web-engineer-certification-look-like</id>
    <updated>2011-12-01T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;What would a web engineer certification look like?&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/21/image/png-991a834946e896eb3f91f2c2b2482fd6.png' /&gt;&lt;p&gt;&lt;em&gt;&lt;a href="http://xkcd.com/327/"&gt;Image credit to Randall Munroe&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I did a couple of Google searches for this, but surprisingly came up short. Someone must&amp;#39;ve came up with something, so if you know of a similar write-up, please leave it in the comments. I would love to see it!&lt;/p&gt;

&lt;p&gt;On the other hand, looking at the issue with sort of fresh eyes might not be a bad thing.&lt;/p&gt;

&lt;h2&gt;Security is not my favorite topic&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s painfully boring. A lot of it is dealing with rare edge cases. Most of security preventions are preventing highly unlikely scenarios that never happen. As well they should. I ensure that my apps have a solid amount of security in place. It&amp;#39;s not difficult, but it&amp;#39;s a rare time in programming where experience really &lt;strong&gt;does&lt;/strong&gt; matter.&lt;/p&gt;

&lt;p&gt;You can code for years and not have a clue what a sql injection, xss, or rainbow table attack is.&lt;/p&gt;

&lt;h2&gt;So if you aren&amp;#39;t into security, why are you writing about it?&lt;/h2&gt;

&lt;p&gt;There are terrible engineers out there. At &lt;a href="http://www.joystiq.com/2011/05/02/sony-hit-with-second-attack-loses-12-700-credit-card-nu/"&gt;Some&lt;/a&gt; &lt;a href="http://www.pcgamer.com/2011/11/10/steam-database-hacked-encrypted-credit-card-information-and-passwords-compromised/"&gt;Major&lt;/a&gt; &lt;a href="http://thenextweb.com/media/2010/12/13/gawker-hackers-release-file-with-ftp-author-reader-usernamespasswords/"&gt;Companies&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each of these attacks could have been avoided completely by the simple suggestions in this article.&lt;/p&gt;

&lt;h2&gt;So what are you suggesting?&lt;/h2&gt;

&lt;p&gt;I&amp;#39;m not so much suggesting there should &lt;em&gt;actually&lt;/em&gt; be a certification to be a web engineer. I&amp;#39;m not a huge fan of that sort of thing in general. However, all other engineers in other fields need to be certified in their trade. Mostly because they can kill people. I can&amp;#39;t write bad code that can kill someone (I hope). However, I can write code that can ruin someone&amp;#39;s life.&lt;/p&gt;

&lt;p&gt;If there was a certification though, these are the big 3 security things that every single web engineer should know (**especially** the novices). If you are an engineer, and you don&amp;#39;t take the time to learn and follow these, you are absolute scum. Ignorance is no excuse with these. These are unavoidable.&lt;/p&gt;

&lt;h2&gt;Password hashing&lt;/h2&gt;

&lt;p&gt;This is the most important security prevention. Unfortunately, there are some cases where this will not work. (Often where you are storing credentials used to login on behalf of a user.) But OAUTH is mitigating the need to avoid these rules.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s really simple too. Imagine you have a database with usernames and passwords. When a user logs in on a website, the website looks up the username, checks to see if the password matches, and logs them in.&lt;/p&gt;

&lt;p&gt;Works great, but what happens if a hacker sees the DB? Or what happens if someone with legitimate access to the database just wants to start stealing those passwords? Bad stuff happens. This is how almost all serious attacks with the big companies happen.&lt;/p&gt;

&lt;p&gt;So what can you do? You could encrypt the password. Then have a decryption key stored somewhere &amp;#39;safe&amp;#39; that can decrypt it and compare it to what the user typed in. Now the database would just have what looks like garbage to an attacker.&lt;/p&gt;

&lt;p&gt;You&amp;#39;ve added an extra step, but the engineers with access to that &amp;#39;safe&amp;#39; key can still get in and get all the passwords. And a hacker could potentially get the key as well. So, you haven&amp;#39;t really solved anything.&lt;/p&gt;

&lt;p&gt;Okay, but here&amp;#39;s the thing, say the user&amp;#39;s password is &amp;#39;hunter2&amp;#39;.&lt;/p&gt;

&lt;p&gt;In the database, it might store that encrypted as &amp;#39;3ksk2b&amp;#39;.&lt;/p&gt;

&lt;p&gt;So when the user logs in, it takes the db password, decrypts it to &amp;#39;hunter2&amp;#39;, then compares it to what the user typed in.&lt;/p&gt;

&lt;p&gt;We don&amp;#39;t have to do that though, we can compare the encrypted version rather than the original. We can just encrypt what the user typed in, then compare it to &amp;#39;3ksk2b&amp;#39; since if they typed in the right password, it will match! Now we never have to decrypt the password.&lt;/p&gt;

&lt;p&gt;There are algorithms that help with this. They take an input, munge it up, and can never be decrypted by anyone. They&amp;#39;re called &lt;a href="http://en.wikipedia.org/wiki/Hash_function"&gt;hashing algorithms&lt;/a&gt;. Most well known of which is MD5 and SHA1.&lt;/p&gt;

&lt;p&gt;So that&amp;#39;s how you do it! Just never store the password, and ensure the application has no ability to decrypt the password and no hacker will be able to either. &lt;strong&gt;Do this. Always.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hashing (in this way) is still susceptible to an attack called rainbow tables. &lt;a href="http://www.codinghorror.com/blog/2007/09/rainbow-hash-cracking.html"&gt;Jeff Atwood wrote an excellent article on this.&lt;/a&gt; I won&amp;#39;t get into it here as it&amp;#39;s fairly technical, but you should watch out for it if your site can host personal info. Rainbow table attacks can not produce the original password (in general), so they are not as severe as plain-text password thefts.&lt;/p&gt;

&lt;p&gt;One final note on passwords: If you are logging the GET and POST url parameters, make sure you remove passwords from log files. Rails, for example, will do this with its filtered log params automatically.&lt;/p&gt;

&lt;h2&gt;SQL Injection&lt;/h2&gt;

&lt;p&gt;In order to understand SQL injection, you need to know a bit of SQL. Imagine you were running a php sql command like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="php"&gt;// This query is ignoring my previous section, but it&amp;#39;s just an example

// Assume a request like /login?username=dickeytk&amp;amp;password=hunter2

// Get the user out of the database that matches the given username and password
$username = $_GET[&amp;quot;username&amp;quot;];
$password = $_GET[&amp;quot;password&amp;quot;];
$query  = &amp;quot;select * from users where user_name = &amp;#39;$username&amp;#39; and password = &amp;#39;$password&amp;#39;;&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks great right! Sure does. It&amp;#39;s going to run this query:&lt;/p&gt;

&lt;pre&gt;&lt;code class="sql"&gt;select * from users where user_name = &amp;#39;dickeytk&amp;#39; and password = &amp;#39;hunter2&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Alright so that&amp;#39;s going to lookup the user&amp;#39;s name, and the password in the database. All is well. Now, what if I wanted to be malicious and instead of &amp;#39;hunter2&amp;#39; for the password, I typed &amp;#39;hunter2&amp;#39; OR true; //&amp;#39;.&lt;/p&gt;

&lt;p&gt;Hmm. I think the SQL query would instead look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="sql"&gt;select * from users where user_name = &amp;#39;dickeytk&amp;#39; and password = &amp;#39;hunter2&amp;#39; OR true; \\&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it doesn&amp;#39;t matter what the user typed in for their password since the logic will hit &amp;#39;or true&amp;#39; and login any user. So even if the user&amp;#39;s password is something totally different, they login just fine.&lt;/p&gt;

&lt;p&gt;This is my favorite attack. It&amp;#39;s just sort of fun.&lt;/p&gt;

&lt;p&gt;So how can it be avoided? One way is escaping the quotes. Making it so you can&amp;#39;t get out of a string inside a variable. In php, just wrap the variable in the mysql_real_escape_string function.&lt;/p&gt;

&lt;p&gt;In modern frameworks, you can use parameterized queries. They work like this:&lt;/p&gt;

&lt;p&gt;Bad ruby&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Article.where(&amp;quot;name = &amp;#39;security&amp;#39;&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Good ruby&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Article.where(&amp;quot;name = ?&amp;quot;, &amp;#39;security&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looks very similar, but is very different since the second one will not only escape the variable, but also execute it so that the query is ran with placeholders, that are filled in with another command.&lt;/p&gt;

&lt;p&gt;You don&amp;#39;t have to think and a SQL injection can never happen.&lt;/p&gt;

&lt;h2&gt;Cross-site scripting or XSS&lt;/h2&gt;

&lt;p&gt;XSS can also be fun. It is similar to SQL injection, but works with HTML instead of SQL.&lt;/p&gt;

&lt;p&gt;If you allow users to input things that might be used on a page, they could potentially insert javascript, giving them basically total control over a page.&lt;/p&gt;

&lt;p&gt;For example, if Facebook had a XSS vector in status updates, I might add a status update like this:&lt;/p&gt;

&lt;p&gt;&amp;#39;I am creating an xss attack &amp;lt;script&amp;gt;alert(&amp;#39;woo dickey is 1337&amp;#39;);&amp;lt;/script&amp;gt;&amp;#39;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Funny note: when I wrote this article I actually XSS&amp;#39;ed myself. I had a js alert popup saying &amp;#39;woo dickey is 1337!&amp;#39;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now all my friends getting my status update will have a javascript alert show up. You can get much more malicious though, by farming for password input fields and things.&lt;/p&gt;

&lt;p&gt;It is the hardest of these to prevent. All the big sites have XSS attacks all the time. You need to ensure that user input is encoded into html when it is displayed, basically.&lt;/p&gt;

&lt;p&gt;So when you take an input like a status update, and it&amp;#39;s displayed on the page, you should escape &amp;lt;&amp;#39;s into &amp;amp;lt; along with the other HTML you need to escape. Every programming language has a shorthand for this. Rails will do it automatically, unless you add &amp;#39;html_safe&amp;#39; or &amp;#39;raw&amp;#39; in your view.&lt;/p&gt;

&lt;p&gt;So don&amp;#39;t use those if it&amp;#39;s straight user input you are displaying. Unless you REALLY trust your users. (but you don&amp;#39;t, do you?)&lt;/p&gt;

&lt;h2&gt;On frameworks&lt;/h2&gt;

&lt;p&gt;Every web framework has tools built in to avoid these problems. It&amp;#39;s a double edged sword. If you use Rails, for example, you will pretty much never run into these problems since the framework avoids many of them in its design. However, you will probably never learn about them either.&lt;/p&gt;

&lt;p&gt;Using straight PHP and these are incredibly important and you need to be aware all the time. It means you need to watch out and always be thinking about them.&lt;/p&gt;

&lt;p&gt;Obviously frameworks are better for this, but you still have to be aware fo these things.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/nmfSVEtmjG4" height="1" width="1"/&gt;</content>
    <summary>Image credit to Randall Munroe

I did a couple of Google searches for this, but surprisingly came up short. Someone must&amp;#39;ve came up with something, so if you know of a similar write-up, please leave it in the comments. I would love to see it!</summary>
  <feedburner:origLink>http://dickey.xxx/what-would-a-web-engineer-certification-look-like</feedburner:origLink></entry>
  <entry>
    <title>CloudFlare review: not snake oil, but it feels like it</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/vW_kqstxv8U/cloudflare-review-not-snake-oil-but-it-feels-like-it" />
    <id>http://dickey.xxx/cloudflare-review-not-snake-oil-but-it-feels-like-it</id>
    <updated>2011-11-30T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;CloudFlare review: not snake oil, but it feels like it&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/20/image/cloudflare-main-42c89e83b093299e159dd932cc45af04.png' /&gt;&lt;p&gt;&lt;em&gt;I had the opportunity to meet with John from CloudFlare in his office after writing this article. Read the &lt;a href="http://jeffdickey.info/cloudfront-vs-cloudflare"&gt;follow-up&lt;/a&gt; after reading this.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I switched my blog over to use &lt;a href="http://cloudflare.com"&gt;CloudFlare&lt;/a&gt; today. I&amp;#39;ll be honest, most of the reason for trying it out was curiosity into what it was exactly. My site handled the load from being on the top of ycombinator on a single heroku dyno without wincing, so to be honest, CloudFlare couldn&amp;#39;t have offered me much. It was a total curiosity decision, not a business one.&lt;/p&gt;

&lt;h2&gt;What is a CDN?&lt;/h2&gt;

&lt;p&gt;Skip this section if you already know.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m going to use the word &amp;#39;CDN&amp;#39; a lot in this post. If you don&amp;#39;t know what a CDN is, it&amp;#39;s a caching service. Say you have a file on your site, like I have my css for this site right here: &lt;a href="http://jeffdickey.info/assets/application.css"&gt;http://jeffdickey.info/assets/application.css&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you access my CDN (assets.jeffdickey.info) you download it through the CDN instead of my server: &lt;a href="http://assets.jeffdickey.info/assets/application.css"&gt;http://assets.jeffdickey.info/assets/application.css&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same file, it&amp;#39;s just going through the CDN, the CDN gets the file from my server, then the CDN delivers that to you. If a lot of people are requesting the file at the same time, it just hangs onto it so my server doesn&amp;#39;t get pinged.&lt;/p&gt;

&lt;p&gt;And the CDN is a zillion times faster than my web server.&lt;/p&gt;

&lt;p&gt;So it offloads the work of my server, scales limitlessly (practically speaking), and makes the site super fast. It&amp;#39;s a win for everyone.&lt;/p&gt;

&lt;p&gt;That&amp;#39;s with Amazon&amp;#39;s CloudFront (way too similar of a name) which is a much more traditional CDN, CloudFlare is different. So, onto my CloudFlare experience:&lt;/p&gt;

&lt;h2&gt;Now I recklessly reconfigured everything&lt;/h2&gt;

&lt;p&gt;What is CloudFlare? This was my big question. I watched their 5 minute intro video, and didn&amp;#39;t learn a damn thing. It was pretty (I liked the evil devil dude!) but honestly, I didn&amp;#39;t learn a thing. There was mention about the server going offline and the site staying live, spam prevention, SEO enhancement and other things, but I felt like they were offering all these great things without anything to back it up.&lt;/p&gt;

&lt;p&gt;So then I had 2 options, either read some copy, or say &amp;quot;fuck it, we&amp;#39;ll do it live&amp;quot;. You can safely assume what I did next.&lt;/p&gt;

&lt;p&gt;I had no clue what I was doing. It became clear to me though, that all CloudFlare really does is replace your DNS server. Then magic.&lt;/p&gt;

&lt;p&gt;The setup process is insanely good. Easy signup form, you point CloudFlare to your current host, it finds all your DNS info, you just look through it, make sure it looks good, then you mark which ones you want &amp;#39;CloudFlare optimized&amp;#39; (whatever that is) and change your nameservers over. It&amp;#39;s so well done, anyone could do it.&lt;/p&gt;

&lt;p&gt;I&amp;#39;m not sure I&amp;#39;ve ever had so much fun with setting up an architecture component in my life.&lt;/p&gt;

&lt;h2&gt;Alright, so hopefully I learned something&lt;/h2&gt;

&lt;p&gt;I got an email a few minutes later letting me know my nameservers had switched over. I reset my DNS, checked out my site, it was still running, and immediately was wondering what the hell I did.&lt;/p&gt;

&lt;p&gt;My first worry was that it was going to cache all my html, resulting in outdated content. Would it cache my blog index for several days? What if I needed to edit an article? I wanted to know how the invalidation worked. I still don&amp;#39;t know how invalidation works (if at all), but CloudFlare is different than most CDNs since it only cached some files (css, javascript and images). &lt;strong&gt;It does not cache your HTML.&lt;/strong&gt; It can also process the css and js to minify them.&lt;/p&gt;

&lt;p&gt;I think this is really where it differentiates itself from other CDNs. All the CDNs I know of you have to setup a different server, you can CNAME it so it&amp;#39;s like assets.yourdomain.com, but you can&amp;#39;t have the CDN and the content both running on the same host. The benefit here is that it&amp;#39;s super easy to setup. You don&amp;#39;t even have to think about it at all. The minification on top of that is huge. I remember I spent quite a bit of time working on the minification part of a build process for a major CMS. It kills me that kids these days can click a button to minify their shit.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://thenextweb.com/insider/2011/06/07/cloudflare-a-website-security-product-accidentally-makes-sites-60-faster/"&gt;After I did a bit of research, this whole thing was a freaking accident.&lt;/a&gt; That&amp;#39;s hilarious.&lt;/p&gt;

&lt;p&gt;There is a few other cool features, I really like how it shows me how much the CDN is actually saving me in bandwidth and things as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://i.imgur.com/hNM08.jpg"&gt;I think the best way to get an idea of the features is just linking my whole settings page.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of the cool ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can munge the email addresses on a site so that email scrapers can&amp;#39;t find them&lt;/li&gt;
&lt;li&gt;Purty analytics showing how well the site and CloudFlare is doing&lt;/li&gt;
&lt;li&gt;Can cache with or without querystring params (I don&amp;#39;t think any other CDN does that)&lt;/li&gt;
&lt;li&gt;Asynchronous javascript loading&lt;/li&gt;
&lt;li&gt;Preloader can preload 200 of your most accessed content (requires paid account)&lt;/li&gt;
&lt;li&gt;IP geolocation in the HTTP headers&lt;/li&gt;
&lt;li&gt;Can warn you if google analytics isn&amp;#39;t working correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another big plus, there is 0 vendor lock-in here. You can easily migrate to any other CDN. Nothing I have done I feel like has been permanent to my project.&lt;/p&gt;

&lt;h2&gt;Downsides&lt;/h2&gt;

&lt;p&gt;CloudFlare won&amp;#39;t help many sites with scaling issues. It helps with static files and front-end performance, but can&amp;#39;t do anything to scale your application tier. That&amp;#39;s okay, it&amp;#39;s impossible for them to do that reliably anyways. If you&amp;#39;re on a CDN and you&amp;#39;re having scaling issues, CloudFlare will not help you.&lt;/p&gt;

&lt;p&gt;I also feel super uncomfortable with this whole thing. There just feels like way too much magic for me. Everything about it just screams snake oil to me. It appears to not be snake oil, but something is off. It might be the loss of control, it might be the copy, it might be just that CloudFlare does so much for free. I&amp;#39;m not sure.&lt;/p&gt;

&lt;p&gt;How does CloudFlare handle caching? I have the hash of my static content embedded in the filename, so invalidation isn&amp;#39;t a problem for me, but what if I didn&amp;#39;t? How and how long does it take to get a new version of a cached file? What exactly happens if my server goes down? I clicked a checkbox that will keep it up, but what the hell does that actually do? If the server 500&amp;#39;s it shows an old version?&lt;/p&gt;

&lt;p&gt;Will it work with S3? Maybe that&amp;#39;s a specific question, but I&amp;#39;m still using CloudFront for my S3 assets.&lt;/p&gt;

&lt;h2&gt;Is it fast?&lt;/h2&gt;

&lt;p&gt;Too hard to tell. My site is already pretty freaking fast, and I was already using a CDN. CloudFlare is a good first CDN, because it&amp;#39;s easy to configure. If you&amp;#39;re on another one, I see no reason to come over to CloudFlare.&lt;/p&gt;

&lt;p&gt;Looking at others tests, this seems to agree with what I said. Those that weren&amp;#39;t on a CDN were amazed at how fast it made their site (well, duh) and those that were on a different CDN were disappointed at CloudFlare.&lt;/p&gt;

&lt;h2&gt;Who the hell are these &amp;#39;big guys&amp;#39; and what &amp;#39;tools&amp;#39; do they have?&lt;/h2&gt;

&lt;p&gt;This sort of bothers me, on CloudFlare&amp;#39;s twitter, they state:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CloudFlare brings the performance and security tools previously reserved for the Internet giants to the rest of the web for free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;But what?&lt;/strong&gt; I have no clue what performance and security tools they&amp;#39;re even talking about here. I don&amp;#39;t have much else to add to that, it just confuses me.&lt;/p&gt;

&lt;h2&gt;In short&lt;/h2&gt;

&lt;p&gt;CloudFlare works. I was really apprehensive about it at first. Although I think that I am not the target market, I think webmasters with less of a technical background would only be more apprehensive. It almost seems too good to be true. They say on their site though:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On average, a website on CloudFlare&lt;br&gt;
- loads twice as fast&lt;br&gt;
- uses 60% less bandwidth&lt;br&gt;
- has 65% fewer requests&lt;br&gt;
- is way more secure&lt;br&gt;
All for free!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It&amp;#39;s not snake oil. I bet you could even get better numbers than that on a popular site. We all know CDNs are great. I rarely setup any site where I don&amp;#39;t use one. CloudFlare just found a way to let essentially anyone set one up. Then they throw on a couple more awesome features on top of that. There are some drawbacks, but the fact that it&amp;#39;s... you know... free... and has absolutely no vendor lock-in, there is no reason I can think of you &lt;em&gt;shouldn&amp;#39;t&lt;/em&gt; use it.&lt;/p&gt;

&lt;p&gt;To CloudFlare: Please put more of the &amp;#39;how&amp;#39; in your copy. Could just be a link or something, but if you&amp;#39;re going to say something is faster, or safer, or better, I&amp;#39;m never going to believe you until you can prove it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; In editing this article, CloudFlare&amp;#39;s site actually went down for me. Doesn&amp;#39;t add a ton of reassurance for me, but my site is fine. They do claim 5 nines of availability. (99.999%)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I had the opportunity to meet with John from CloudFlare after this article. He cleared up a lot of questions for me. Here is a follow-up article to this one: &lt;a href="http://jeffdickey.info/cloudfront-vs-cloudflare"&gt;http://jeffdickey.info/cloudfront-vs-cloudflare&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/vW_kqstxv8U" height="1" width="1"/&gt;</content>
    <summary>I had the opportunity to meet with John from CloudFlare in his office after writing this article. Read the follow-up after reading this.</summary>
  <feedburner:origLink>http://dickey.xxx/cloudflare-review-not-snake-oil-but-it-feels-like-it</feedburner:origLink></entry>
  <entry>
    <title>Why I love making CMS's</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/nq7gWpn64ag/why-i-love-making-cms-s" />
    <id>http://dickey.xxx/why-i-love-making-cms-s</id>
    <updated>2011-11-29T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Why I love making CMS's&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/17/image/f0a0ab49-21e2-4cbe-a890-831159cbeab9-5e6c01be2ee787cfccca0ad9cab72252.jpeg' /&gt;&lt;p&gt;The most common application that I have built has been the good old fashioned content management system. This includes more than blogs though, I would argue that &lt;strong&gt;anything where a user can edit content without changing a codebase is a CMS.&lt;/strong&gt; However, just off the top of my head, &lt;a href="https://github.com/mojombo/jekyll"&gt;Jekyll&lt;/a&gt; is absolutely a CMS but still doesn&amp;#39;t fit into that already generous bucket. &lt;/p&gt;

&lt;p&gt;Let&amp;#39;s focus on blogs for a bit though,&lt;/p&gt;

&lt;h2&gt;Blogs especially are fun to make&lt;/h2&gt;

&lt;p&gt;I like to get the most amount done with the least amount of work. I am a lazy developer. Writing a blog is obvious. If a client needs a blog I immediately know what I need to do, many things they might not even know about. Including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin interface&lt;/li&gt;
&lt;li&gt;Templating engine&lt;/li&gt;
&lt;li&gt;Social plugins/interaction&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Tagging&lt;/li&gt;
&lt;li&gt;Related articles&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Archive sections&lt;/li&gt;
&lt;li&gt;RSS/ATOM feeds&lt;/li&gt;
&lt;li&gt;Sitemap.xml&lt;/li&gt;
&lt;li&gt;Slug generation&lt;/li&gt;
&lt;li&gt;Drafting method&lt;/li&gt;
&lt;li&gt;Author functionality&lt;/li&gt;
&lt;li&gt;Workflow&lt;/li&gt;
&lt;li&gt;Commenting&lt;/li&gt;
&lt;li&gt;SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scale? Performance? Psh. That&amp;#39;s easy mode software when it&amp;#39;s a CMS.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve architected the whole damn database by the time they said &amp;#39;article&amp;#39;. Even though they might not even know what caching or a sitemap is, I&amp;#39;ve solved their problems without having to even encountered them or mentioned them.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s a beautiful, rare time in architecture where you immediately know what to do.&lt;/p&gt;

&lt;p&gt;This continues onto the development, which will be crazy fast.&lt;/p&gt;

&lt;h2&gt;So why not just use Wordpress?&lt;/h2&gt;

&lt;p&gt;Believe me, I&amp;#39;m the first guy to avoid coding and leveraging the community wherever possible. Wordpress is the right choice in many circumstances, as is Tumblr and a lot of other sites. However, while blogs and brochureware are generally a solved problem, CMS&amp;#39;s are not.&lt;/p&gt;

&lt;p&gt;The client also probably isn&amp;#39;t get a hold of someone with my background if all they need is something as simple as Wordpress.&lt;/p&gt;

&lt;h2&gt;Why might a CMS not be a blog&lt;/h2&gt;

&lt;p&gt;Several reasons. I consider a blog to be an index showing articles in a reverse chronological order. Nothing more. Even this website I&amp;#39;ve made for myself is more. It has &lt;a href="/projects"&gt;projects&lt;/a&gt; which I can edit. Those are absolutely nothing like a blog. It&amp;#39;s just &amp;#39;content to manage&amp;#39;.&lt;/p&gt;

&lt;h2&gt;Simple features break off-the-shelf CMS&amp;#39;s&lt;/h2&gt;

&lt;p&gt;Maybe I want to link to GitHub and show my most recent commits for each article? Wordpress would be a particular pain in the ass for this, and Tumblr would be absolutely useless. In a custom CMS? Easy peasy.&lt;/p&gt;

&lt;p&gt;Still though, I love this kind of development where I can leverage my existing knowledge of similar systems (CMS&amp;#39;s in general) and focus on the specific feature at hand (GitHub integration).&lt;/p&gt;

&lt;h2&gt;Still, why do you &amp;#39;love&amp;#39; making CMS&amp;#39;s?&lt;/h2&gt;

&lt;p&gt;This is simple. I can easily make a platform, get a designer to make it purty (or half-ass it myself like I did here), then some writers create some awesome content!&lt;/p&gt;

&lt;p&gt;From then on, it can be used for &lt;em&gt;years&lt;/em&gt; without me having to lift a finger, yet I still feel like I was a part of creating each and every post!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/nq7gWpn64ag" height="1" width="1"/&gt;</content>
    <summary>The most common application that I have built has been the good old fashioned content management system. This includes more than blogs though, I would argue that anything where a user can edit content without changing a codebase is a CMS. However, just off the top of my head, Jekyll is absolutely a CMS but still doesn&amp;#39;t fit into that already generous bucket. </summary>
  <feedburner:origLink>http://dickey.xxx/why-i-love-making-cms-s</feedburner:origLink></entry>
  <entry>
    <title>memcache on Heroku's cedar stack in Rails 3.1</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/ss81UnQLO30/memcache-on-heroku-cedar-stack-in-rails-3-1" />
    <id>http://dickey.xxx/memcache-on-heroku-cedar-stack-in-rails-3-1</id>
    <updated>2011-11-28T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;memcache on Heroku's cedar stack in Rails 3.1&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/14/image/heroku-11bf8a389951cf6745b2918040fa5935.png' /&gt;&lt;p&gt;If you&amp;#39;re building a Rails site, you almost definitely need to have caching. memcache is the best solution for that problem right now. It&amp;#39;s not too hard, but there are only bits on the internet on how to do it.&lt;/p&gt;

&lt;h2&gt;Instructions&lt;/h2&gt;

&lt;p&gt;Install memcache addon&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku addons:add memcache
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install memcache locally&lt;/p&gt;

&lt;pre&gt;&lt;code class="bash"&gt;$ sudo port install memcached         # for macports
$ brew install memcached              # for homebrew
$ sudo apt-get install memcached      # for ubuntu/debian
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Put the &amp;#39;dalli&amp;#39; gem into your Gemfile (this is the memcache driver) and run the &amp;#39;bundle&amp;#39; command&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;# Gemfile
gem &amp;#39;dalli&amp;#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In production.rb and development.rb, set the cache_store&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;# /config/environments/production.rb
config.cache_store = :dalli_store
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;# /config/environments/development.rb
config.cache_store = :dalli_store
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now change your session initializer (for memcache session support)&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;# config/initializers/session_store.rb
require &amp;#39;action_dispatch/middleware/session/dalli_store&amp;#39;
YOURAPPNAMEHERE::Application.config.session_store :dalli_store
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://guides.rubyonrails.org/caching_with_rails.html"&gt;Now start caching things!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;How this works&lt;/h2&gt;

&lt;p&gt;This works without setting any configuration since dalli will connect to the MEMCACHE_SERVERS environment variable, which gets set when you install the addon. If that environment variable is not present, it will connect to localhost (which works for development).&lt;/p&gt;

&lt;h2&gt;Dev environment troubleshooting&lt;/h2&gt;

&lt;p&gt;The most common error you will see is dalli not being able to connect. First, make sure that memcache is running. For that, I like to use telnet to connect to the local running memcache service. It&amp;#39;s kinda fun too!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ telnet 127.0.0.1 11211
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then you can do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SET foo bar
GET foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(should return bar)&lt;/p&gt;

&lt;h2&gt;Still running into problems?&lt;/h2&gt;

&lt;p&gt;I&amp;#39;ve ran into a problem on Vagrant and a Windows development installs where Dalli would not be able to find the local running memcache service. For that, I found that setting the host to &amp;#39;127.0.0.1&amp;#39; fixed the problem. I imagine it&amp;#39;s something to do with IPv6, but I&amp;#39;m not sure.&lt;/p&gt;

&lt;p&gt;So to fix, just do&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export MEMCACHE_SERVERS=127.0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That worked for me!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/ss81UnQLO30" height="1" width="1"/&gt;</content>
    <summary>If you&amp;#39;re building a Rails site, you almost definitely need to have caching. memcache is the best solution for that problem right now. It&amp;#39;s not too hard, but there are only bits on the internet on how to do it.</summary>
  <feedburner:origLink>http://dickey.xxx/memcache-on-heroku-cedar-stack-in-rails-3-1</feedburner:origLink></entry>
  <entry>
    <title>node.js introduction</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/hM4Omv7CFGs/node-js-introduction" />
    <id>http://dickey.xxx/node-js-introduction</id>
    <updated>2011-11-26T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;node.js introduction&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/12/image/light-721ea223b412e3ceb169d8ee5f05d6fb.png' /&gt;&lt;p&gt;&lt;em&gt;node.js is an event-driven web server written in javascript.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;node.js is popular with big CS nerds. I had a very difficult time understanding exactly &amp;#39;what it was&amp;#39; when I first heard about it. This is my attempt to explain it for those of us without a neckbeard.&lt;/p&gt;

&lt;p&gt;Disclaimer: Some of what I&amp;#39;m saying in this article is not entirely true, I know. I&amp;#39;m over-simplifying how computers work to illustrate how node.js works, not explain how CPU schedulers work. That&amp;#39;d just be a snooze-fest anyways.&lt;/p&gt;

&lt;h2&gt;Why I&amp;#39;m trying out node.js&lt;/h2&gt;

&lt;p&gt;node.js is something that I&amp;#39;ve been very excited about. I&amp;#39;ve watched/read a lot of what Ryan Dahl and the rest of the community has said about node.js. It&amp;#39;s my latest hammer.&lt;/p&gt;

&lt;p&gt;node.js is an excellent tool if you want some kind of live interaction on a website. It is capable of very quickly delivering data to/from a web browser.&lt;/p&gt;

&lt;p&gt;What could you do with that? Well, as an example, say you were building a CRM. You could have a feature where viewing a customer&amp;#39;s profile could be updated live. So if a sales guy is on a call taking comments, another employee could be seeing the updates instantly. (No reloading of the page.)&lt;/p&gt;

&lt;p&gt;Yes, this has been done before with ajax and things, but node.js does it much, much faster and better. Even the fastest Rails requests will be 10x what node.js can do.&lt;/p&gt;

&lt;p&gt;My job is to use my knowledge of technical resources to solve problems. Node.js allows us to do neat things on web sites that so far really haven&amp;#39;t been leveraged by anyone. It&amp;#39;s very young and has tremendous potential.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve also been working on a little toy with node.js. More on that in a later post.&lt;/p&gt;

&lt;h2&gt;node.js should be used if you want a specific piece of your web architecture to be live and/or super fast&lt;/h2&gt;

&lt;p&gt;It works well for that, but it doesn&amp;#39;t have the same niceties of other web frameworks like rails, django, .net and everything else. It&amp;#39;s not that it couldn&amp;#39;t, just that it isn&amp;#39;t the intent.&lt;/p&gt;

&lt;p&gt;If you were building Facebook, for example, node.js would be good for updating the newsfeed when new status updates come in, but not great at much else.&lt;/p&gt;

&lt;h2&gt;Now, to explain HOW it works&lt;/h2&gt;

&lt;p&gt;So traditionally, there has always been a big problem with computers where the CPU can only do one thing at a time. It was solved long ago with multi-threading, allowing us to have multiple &amp;#39;threads&amp;#39; on a single CPU.&lt;/p&gt;

&lt;p&gt;So, to simplify, if you have 10 threads going on, a CPU scheduler will split up the CPU&amp;#39;s time evenly between all of them so they get equal time slices. So maybe in 1 second, each of the 10 threads would get 100ms.&lt;/p&gt;

&lt;p&gt;It switches between them all the time, and while it&amp;#39;s pretty fast, the switching has a ton of overhead. I won&amp;#39;t get into how, but let&amp;#39;s say in my CS class when I learned this I was actually amazed that computers are even as close to as fast as they are.&lt;/p&gt;

&lt;p&gt;Avoiding that overhead would be nice.&lt;/p&gt;

&lt;h2&gt;node.js is evented programming&lt;/h2&gt;

&lt;p&gt;This is the absolute core of node.js. It is &lt;strong&gt;not&lt;/strong&gt; the fact it&amp;#39;s &lt;em&gt;server side javascript&lt;/em&gt;. It&amp;#39;s a &lt;strong&gt;single&lt;/strong&gt; threaded server that acts upon callbacks and never blocks on the main thread.&lt;/p&gt;

&lt;p&gt;Why? Let me illustrate,&lt;/p&gt;

&lt;p&gt;So, if you think of a blog cms engine, for example. A traditional web server looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take in a request for the blog index&lt;/li&gt;
&lt;li&gt;Call out to the db to get the blog articles&lt;/li&gt;
&lt;li&gt;Build the html containing the blog articles&lt;/li&gt;
&lt;li&gt;Send the response out&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Node.js doesn&amp;#39;t work any different here. It&amp;#39;s under the hood where it&amp;#39;s different.&lt;/p&gt;

&lt;p&gt;Now, on the second step, (calling out to the db to get the blog articles), let&amp;#39;s say that takes 100ms. Almost the entire time the thread is waiting for the db to come back with its response. &lt;em&gt;We call this IO heavy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However on the third, where the server is building HTML from the database&amp;#39;s response, it&amp;#39;s crunching that database&amp;#39;s response and building HTML. It&amp;#39;s quicker, around 10ms, but it&amp;#39;s CPU intensive. It&amp;#39;s not waiting on anyone, just crunching away. &lt;em&gt;We call this CPU heavy.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now earlier I mentioned the bit about splitting the CPU&amp;#39;s time up between threads. If we have 1 thread where the CPU is crunching the HTML (CPU), and another where it&amp;#39;s waiting on the DB (IO), the CPU could literally (and does) waste an entire time-slice switching into the IO thread.&lt;/p&gt;

&lt;h2&gt;node.js solves this problem by running in a single, event-driven thread&lt;/h2&gt;

&lt;p&gt;It takes control of deciding what work needs to be done, rather than having a scheduler try to figure it out.&lt;/p&gt;

&lt;p&gt;Rather than have a new thread get created on each request, there is one thread for every single request. When a new one comes in, it fires an event that runs some code. VERY much like how jQuery works. When you make a call to a database, for example, rather than block until it&amp;#39;s returned, you just run a callback function after the call is complete.&lt;/p&gt;

&lt;p&gt;The difference isn&amp;#39;t really in node.js itself, it is &lt;strong&gt;your&lt;/strong&gt; code that ends up being different. It just &lt;strong&gt;heavily&lt;/strong&gt; guides you into doing it the node.js way. You can do this with other languages, but javascript&amp;#39;s syntax, and node&amp;#39;s framework is really good for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Heavy IO applications benefit well from this, whereas CPU intensive applications will not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;However, most web development is IO intensive, so that&amp;#39;s generally an OK tradeoff.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/hM4Omv7CFGs" height="1" width="1"/&gt;</content>
    <summary>node.js is an event-driven web server written in javascript.

node.js is popular with big CS nerds. I had a very difficult time understanding exactly &amp;#39;what it was&amp;#39; when I first heard about it. This is my attempt to explain it for those of us without a neckbeard.</summary>
  <feedburner:origLink>http://dickey.xxx/node-js-introduction</feedburner:origLink></entry>
  <entry>
    <title>CarrierWave on Heroku with CloudFront</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/4QnzmF3xoLA/using-carrierwave-on-heroku-for-image-uploading-w-cloudfront" />
    <id>http://dickey.xxx/using-carrierwave-on-heroku-for-image-uploading-w-cloudfront</id>
    <updated>2011-11-25T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;CarrierWave on Heroku with CloudFront&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/9/image/PM-821cc2ae97e62ebccabe59efd00805d2.png' /&gt;&lt;p&gt;This post will enable you to have your Rails app accept file uploads through a gem called CarrierWave. Optionally, you can use CloudFront in order to have a CDN backbone for those files. This is currently the best method for file uploading on Heroku.&lt;/p&gt;

&lt;p&gt;For a full-fledged working project with this on Heroku&amp;#39;s cedar stack, check out &lt;a href="http://github.com/dickeytk/painting-gallery"&gt;http://github.com/dickeytk/painting-gallery&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt; and get an AWS Access Key ID and an AWS Secret Access Key.&lt;/li&gt;
&lt;li&gt;Create a new S3 bucket in the US East Availability Zone. (Since that&amp;#39;s the same one that your Heroku dyno is already in)&lt;/li&gt;
&lt;li&gt;If you want to use CloudFront, add a CloudFront distribution pointing to the S3 bucket you just created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Instructions&lt;/h2&gt;

&lt;p&gt;Add the gems to your Gemfile&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;gem &amp;#39;fog&amp;#39;
gem &amp;#39;carrierwave&amp;#39;
gem &amp;#39;rmagick&amp;#39; # optional, for image resizing support
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add the file &amp;#39;./config/initializers/carrierwave.rb&amp;#39; for your CarrierWave configuration&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;# ./config/initializers/carrierwave.rb
CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider =&amp;gt; &amp;quot;AWS&amp;quot;,
    :aws_access_key_id =&amp;gt; ENV[&amp;#39;AWS_ACCESS_KEY_ID&amp;#39;],
    :aws_secret_access_key =&amp;gt; ENV[&amp;#39;AWS_SECRET_ACCESS_KEY&amp;#39;],
  }
  config.fog_directory = ENV[&amp;#39;S3_BUCKET&amp;#39;]

  # use only one of the following 2 settings
  config.fog_host = &amp;quot;http://#{ENV[&amp;#39;S3_BUCKET&amp;#39;]}.s3.amazonaws.com&amp;quot; # for no cloudfront
  config.fog_host = ENV[&amp;#39;S3_CDN&amp;#39;] # for cloudfront

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add your environment variables&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku config:add AWS_ACCESS_KEY_ID=[your_access_key_here]
$ heroku config:add AWS_SECRET_ACCESS_KEY=[your_access_key_here]
$ heroku config:add S3_BUCKET=[your_s3_bucket]
$ heroku config:add S3_CDN=[your_cloudfront_url] # optional for cloudfront support
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;#39;s it! Should be configured now. All you need to do is add a string column to a model for the file name, a file uploader to add files to a model, and a form to actually accept the uploads. &lt;a href="https://github.com/jnicklas/carrierwave"&gt;CarrierWave&amp;#39;s docs&lt;/a&gt; explain how to do that all very well.&lt;/p&gt;

&lt;h2&gt;Using your own domain&lt;/h2&gt;

&lt;p&gt;If you want to use your own domain (such as content.jeffdickey.info like I use on this site) simply add a CNAME in your dns config pointing to the S3 bucket, then change the S3_CDN environment variable to point to it.&lt;/p&gt;

&lt;h2&gt;Optional CloudFront note&lt;/h2&gt;

&lt;p&gt;Now, if you are going to use CloudFront, you should add this bit to your uploader which will append a file&amp;#39;s hash to the end of a filename. This is so CloudFront won&amp;#39;t cache old content.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;  # ./app/uploaders/image_uploader.rb
  # Appends hash to filename to prevent CloudFront from caching old content
  def filename
    if original_filename
      @hash ||= Digest::MD5.hexdigest(File.dirname(current_path))
      &amp;quot;#{file.basename.split(&amp;#39;_&amp;#39;).last}-#{@hash}.#{file.extension}&amp;quot;
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Known issue&lt;/h2&gt;

&lt;p&gt;There is a potential issue to look out for here. Uploading files that will take &amp;gt;30 seconds will result in Heroku killing the request, so you need to directly upload the files. &lt;a href="http://github.com/GreenAsJade/s3-swf-upload-plugin/tree/master"&gt;This S3 SWF upload plugin should help with that&lt;/a&gt;. But don&amp;#39;t throw that on just &amp;#39;because&amp;#39;. It&amp;#39;s likely to just cause grief.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;I hope this works out well for you! I&amp;#39;ve configured this type of setup several times now and seems to work great! I did it all from memory though, so let me know if you run into any issues.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/4QnzmF3xoLA" height="1" width="1"/&gt;</content>
    <summary>This post will enable you to have your Rails app accept file uploads through a gem called CarrierWave. Optionally, you can use CloudFront in order to have a CDN backbone for those files. This is currently the best method for file uploading on Heroku.</summary>
  <feedburner:origLink>http://dickey.xxx/using-carrierwave-on-heroku-for-image-uploading-w-cloudfront</feedburner:origLink></entry>
  <entry>
    <title>Unix tips du jour</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/KbCjMbU2QGo/unix-tips-du-jour" />
    <id>http://dickey.xxx/unix-tips-du-jour</id>
    <updated>2011-11-24T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;Unix tips du jour&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/8/image/manual-1495cdeb1838f87563b864f7a7a9f6c4.png' /&gt;&lt;p&gt;The thing about unix tools is they are incredibly hard to learn. Even if you understand a tool, you need to build it into your workflow, which takes serious time and experience. Here&amp;#39;s just a quick intro into 2 simple ones, and one complex one for you to chew on:&lt;/p&gt;

&lt;h2&gt;fc&lt;/h2&gt;

&lt;p&gt;fc opens the last ran command in your text editor, then runs it after you save.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s nice when you make a mistake.&lt;/p&gt;

&lt;h2&gt;ctrl-r&lt;/h2&gt;

&lt;p&gt;Search your last ran commands. Just try it.&lt;/p&gt;

&lt;h2&gt;rsync&lt;/h2&gt;

&lt;p&gt;This one is really scary.&lt;/p&gt;

&lt;p&gt;You probably already know this one, it just syncs a remote directory. A great use-case for web developers is when you have a server up and running, and want to change say, an HTML file, you can use rsync on the folder and will update just what has changed.&lt;/p&gt;

&lt;p&gt;It is complicated, but VERY good. If you have a server you want to attempt to update with local files (and if you&amp;#39;re a web developer you probably do), YOU NEED THIS.&lt;/p&gt;

&lt;p&gt;Spend 30 minutes reading the &lt;a href="http://ss64.com/bash/rsync.html"&gt;man page&lt;/a&gt; and you&amp;#39;ll thank me later.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s a bitch to learn and work into your workflow, and you won&amp;#39;t understand the rsync string you wrote, but you&amp;#39;ll be in love anyways.&lt;/p&gt;

&lt;p&gt;Besides, you can always just fc your rsync command to save it as a script and you only need to make it once!&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/KbCjMbU2QGo" height="1" width="1"/&gt;</content>
    <summary>The thing about unix tools is they are incredibly hard to learn. Even if you understand a tool, you need to build it into your workflow, which takes serious time and experience. Here&amp;#39;s just a quick intro into 2 simple ones, and one complex one for you to chew on:</summary>
  <feedburner:origLink>http://dickey.xxx/unix-tips-du-jour</feedburner:origLink></entry>
  <entry>
    <title>The Great Redis Misapprehension</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/0cfR7-Yub-w/the-great-redis-misapprehension" />
    <id>http://dickey.xxx/the-great-redis-misapprehension</id>
    <updated>2011-11-23T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;The Great Redis Misapprehension&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/5/image/redis-300dpi-0315a8013afee137cce47b474541d7f1.png' /&gt;&lt;p&gt;&lt;strong&gt;Redis is NOT a database.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#39;s closer to memcache than mysql, for example. However, it&amp;#39;s not a cache either.&lt;/p&gt;

&lt;p&gt;This is the biggest point I want to drill in people&amp;#39;s heads. For some reason, people seem to think it&amp;#39;s a key-value store, or some persistent database, but that&amp;#39;s totally not it at all.&lt;/p&gt;

&lt;p&gt;I myself thought this, and had a tough time learning why it was useful since that was stuck in my head, so if you&amp;#39;ve been thinking it&amp;#39;s persistent, get that OUT of your head now!&lt;/p&gt;

&lt;h2&gt;Redis is a data structure server&lt;/h2&gt;

&lt;p&gt;It&amp;#39;s super low level things like lists, sets, and yes, key-value, but that&amp;#39;s not the heart of it.&lt;/p&gt;

&lt;p&gt;There&amp;#39;s no one killer feature of Redis. The best way to learn its value is just to look through the docs at interesting things.&lt;/p&gt;

&lt;p&gt;You sort of feel like a toddler playing building blocks, but these building blocks are freaking awesome.&lt;/p&gt;

&lt;p&gt;It has some persistence support, but does not appear to be super durable. If you&amp;#39;re thinking of using like that though, you&amp;#39;re misunderstanding the tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; This comment on persistence has been met with much criticism from the community, so I will add to this: Redis can be configured to be a durable store. It is out of scope for this article, but the docs describe possible configurations very clearly: &lt;a href="http://redis.io/topics/persistence"&gt;http://redis.io/topics/persistence&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The following is 3 example use-cases for Redis&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Leaderboards&lt;/h2&gt;

&lt;p&gt;If you&amp;#39;re designing a leaderboard, you need to be using Redis. One of the few data types it supports is called &lt;a href="http://redis.io/commands#sorted_set"&gt;&amp;#39;sorted sets&amp;#39;&lt;/a&gt; and honestly, they should&amp;#39;ve just called the damn things &amp;#39;leaderboards&amp;#39;.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s pathetically easy to use. Say we&amp;#39;re building Tetris, and we want to show a high score table.&lt;/p&gt;

&lt;p&gt;Each time a user gets a score, use &lt;a href="http://redis.io/commands/zadd"&gt;ZADD&lt;/a&gt; to add their score to the system:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ZADD highscores 1337 dickeytk
ZADD highscores 100 whatgoodisaroad
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&amp;#39;s get the top 5 players using &lt;a href="http://redis.io/commands/zrangebyscore"&gt;ZRANGEBYSCORE&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ZRANGEBYSCORE highscores -inf +inf WITHSCORES LIMIT 0 5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don&amp;#39;t even need to explain that. It&amp;#39;s fast enough for you, in case you&amp;#39;re a worry wort.&lt;/p&gt;

&lt;p&gt;Check &lt;a href="http://redis.io/commands#sorted_set"&gt;the docs&lt;/a&gt; for more information on sorted sets.&lt;/p&gt;

&lt;h2&gt;Queue&lt;/h2&gt;

&lt;p&gt;You can do some super simple queuing things with Redis. I mean dead simple too, literally one line of code in almost every programming language I would say.&lt;/p&gt;

&lt;p&gt;It works just like you would expect.&lt;/p&gt;

&lt;p&gt;Put something at the end of the queue:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RPUSH my_list 6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(&lt;a href="http://redis.io/commands/rpush"&gt;RPUSH&lt;/a&gt; means &amp;#39;push data onto the right side of the list&amp;#39;)&lt;/p&gt;

&lt;p&gt;Grab the next thing from the beginning of the list:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LPOP my_list&lt;/code&gt;&lt;br&gt;
(&lt;a href="http://redis.io/commands/lpop"&gt;LPOP&lt;/a&gt; means &amp;#39;pop data from the left side of the list&amp;#39;)&lt;/p&gt;

&lt;p&gt;A common issue in web development though, is that your queue may not have anything in it! In which case it is often helpful to maybe do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="python"&gt;data = None
while not data:
    data = redis.(&amp;#39;LPOP&amp;#39;, &amp;#39;mylist&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just loop until you get your data. However, there&amp;#39;s a better way, using &lt;a href="http://redis.io/commands/blpop"&gt;BLPOP&lt;/a&gt;. BLPOP is just a blocking version of LPOP:&lt;/p&gt;

&lt;pre&gt;&lt;code class="python"&gt;data = redis.(&amp;#39;BLPOP&amp;#39;, &amp;#39;mylist&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which just blocks until it returns! Marinate on just how useful that is for a second.&lt;/p&gt;

&lt;h2&gt;A caching example!&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; The community was very upset about this section in my post. I still maintain that it is a perfectly acceptable way to handle cache invalidation, however, if you are implementing this in a production system, you definitely need to read &lt;a href="http://redis.io/commands/keys"&gt;http://redis.io/commands/keys&lt;/a&gt; thoroughly. Still though, even if this isn&amp;#39;t preferable for performance reasons, it&amp;#39;s pretty cool!&lt;/p&gt;

&lt;p&gt;Redis is pretty much a drop-in replacement for memcache. If you&amp;#39;ve used memcache, you probably have a caching pattern using keys like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;post/83/body&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;&lt;code&gt;post/83&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;or maybe like this&lt;/p&gt;

&lt;p&gt;&lt;code&gt;article:28:related_tags&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Basically, you&amp;#39;re namespacing the tags so they don&amp;#39;t conflict. Good on you for that! Now, as you&amp;#39;ve probably noticed, invalidation is no easy task, since in memcache, you can delete &lt;code&gt;post/83&lt;/code&gt; but that won&amp;#39;t delete &lt;code&gt;post/83/body&lt;/code&gt; since it&amp;#39;s just a string, memcache doesn&amp;#39;t parse anything.&lt;/p&gt;

&lt;p&gt;Now, this is where Redis comes in. You can find keys on wildcards! So you can just query it like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;keys post/83*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that will return all the keys you need to invalidate!&lt;/p&gt;

&lt;p&gt;As tabbyjabby on ycombinator mentioned that Antirez (one of the creators of Redis) wrote a very good article on many of the same things I have discussed here: &lt;a href="http://antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html"&gt;http://antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html&lt;/a&gt;&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/0cfR7-Yub-w" height="1" width="1"/&gt;</content>
    <summary>Redis is NOT a database.

It&amp;#39;s closer to memcache than mysql, for example. However, it&amp;#39;s not a cache either.</summary>
  <feedburner:origLink>http://dickey.xxx/the-great-redis-misapprehension</feedburner:origLink></entry>
  <entry>
    <title>The soapbox is open for business</title>
    <link rel="alternate" href="http://feedproxy.google.com/~r/jeffdickey/~3/JTIkCou0lSc/the-soapbox-is-open-for-business" />
    <id>http://dickey.xxx/the-soapbox-is-open-for-business</id>
    <updated>2011-11-22T00:00:00Z</updated>
    <author>
      <name>Jeff Dickey</name>
      <email>jeff@dickey.xxx</email>
    </author>
    <content type="html">
&lt;h1&gt;The soapbox is open for business&lt;/h1&gt;&lt;img src='http://d3u6t3wj2rw73g.cloudfront.net/post/4/image/welcome-34e7bc9a0ec554b98b767e530385f525.gif' /&gt;&lt;p&gt;Muahaha. I am now a blogger. I suppose technically this isn&amp;#39;t my first time blogging, but it&amp;#39;s the first time I&amp;#39;m blogging about something that isn&amp;#39;t what I had for breakfast.&lt;/p&gt;

&lt;p&gt;I don&amp;#39;t even eat breakfast anymore.&lt;/p&gt;

&lt;p&gt;Now I get to share what beer I&amp;#39;m drinking! Racer 5, of course. But I digress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why am I blogging?&lt;/strong&gt; Because I think I&amp;#39;m some sort of expert in my field with valuable information. It&amp;#39;s ridiculous, I know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What will I blog about?&lt;/strong&gt; Mostly technical things, there&amp;#39;s a few articles I&amp;#39;ve wanted to write for a while but just haven&amp;#39;t had the platform to do it from, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My long overdue love letter to Heroku&lt;/li&gt;
&lt;li&gt;A post, or series of posts, on useful unix commands (fc is a recent one that comes to mind)&lt;/li&gt;
&lt;li&gt;A more personal note on why I&amp;#39;m a web developer&lt;/li&gt;
&lt;li&gt;BEGINNER&amp;#39;S GUIDES! this is something I&amp;#39;ve wanted to do for a long time.&lt;/li&gt;
&lt;li&gt;Angle brackets, and why I need to be able to control every damn one of those suckers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What&amp;#39;s the end goal? 2 things really, I want to be a better writer, and I want to be more involved in the community. I want to write an article like &lt;a href="http://teddziuba.com/2011/10/node-js-is-cancer.html"&gt;this&lt;/a&gt; that really pisses people off haha&lt;/p&gt;

&lt;p&gt;So I hope you enjoy the new blog! My goal right now is A POST A DAY! I know at least for a long time I&amp;#39;ll definitely have some content.&lt;/p&gt;
    &lt;img src="http://feeds.feedburner.com/~r/jeffdickey/~4/JTIkCou0lSc" height="1" width="1"/&gt;</content>
    <summary>Muahaha. I am now a blogger. I suppose technically this isn&amp;#39;t my first time blogging, but it&amp;#39;s the first time I&amp;#39;m blogging about something that isn&amp;#39;t what I had for breakfast.</summary>
  <feedburner:origLink>http://dickey.xxx/the-soapbox-is-open-for-business</feedburner:origLink></entry>
</feed>
