<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace V5 Site Server v5.13.159 (http://www.squarespace.com) on Fri, 24 May 2013 03:06:55 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>PipelineDeals Dev blog</title><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/</link><description></description><lastBuildDate>Fri, 28 Dec 2012 16:39:52 +0000</lastBuildDate><copyright></copyright><language>en-US</language><generator>Squarespace V5 Site Server v5.13.159 (http://www.squarespace.com)</generator><item><title>Achieving consistent, worry-free, super-fast deploys using AWS and ELBs</title><dc:creator>Grant Ammons</dc:creator><pubDate>Wed, 26 Dec 2012 19:41:49 +0000</pubDate><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/2012/12/26/achieving-consistent-worry-free-super-fast-deploys-using-aws.html</link><guid isPermaLink="false">1001415:11574374:32238501</guid><description><![CDATA[<p>At <a href="http://www.pipelinedeals.com">PipelineDeals</a>, we deploy code frequently, usually 2-3x per week, and sometimes even more often. As all web application developers know, deploying is sort of a nervous process. I mean, sure, 99.99% of the time, everything will go perfectly smooth. All your tests pass, your deploy to staging went perfectly, all the tickets have been verified. There is no reason to fear hitting the button. And, the vast majority of the time, this is true.</p>

<p>But all web application developers <em>also</em> know that sometimes, there is a snag. Sometimes the fates are against you, and for whatever reason, something goes bust.  Perhaps you have a series of sequenced events that must occur to deploy, and one of the events silently failed because the volume that /tmp is mounted on temporarily had a 100% full disk. Perhaps that upload of the new assets to S3 did not work. Perhaps you did not deploy to ALL the servers you needed to deploy to.</p>

<p>And then, the worst happens. For a short period while you are scrambling to revert, your customers see your mistake. They start questioning the reliability of your system.  Your mistake (and it is yours, even if some bug in some server caused the problem) is clearly visible to your customers, your bosses, and your peers.</p>

<h2>Taking advantage of the tools we have</h2>

<p>PipelineDeals runs on <a href="http://aws.amazon.com">Amazon AWS</a>. We utilize EC2 for our server instances, ELB for our load balancing, ElastiCache for our memcached storage.
We are also major proponents of <a href="http://www.opscode.com/chef">Opscode's Chef</a>, and use it to spin up and configure any type of instance that makes up our stack.</p>

<p>Since we have all these fantastic tools, we decided to use them in a way that makes deploying seamless and easy. We wrote a simple Rakefile called
<a href="https://github.com/PipelineDeals/deployer">Deployer</a> that orchestrates a seamless app server deploy.</p>

<h2>Using the Deployer script</h2>

<p>The first thing it does is creates new app servers that have the new code on them. Once the app servers have completed their configuration, the deployer rakefile will register those new app servers with a test ELB load balancer.</p>

<p><span class="full-image-block ssNonEditable"><span><img src="http://devblog.pipelinedeals.com/storage/deploy1.001.png?__SQUARESPACE_CACHEVERSION=1356712468582" alt=""/></span></span></p>

<p>From there, we can do a final walkthrough of what exactly is going into production, and indeed the app server is up, awake, and ready to receive requests.</p>

<p>After that final validation, we simply run <code>rake deploy</code>, which adds the new app servers to the current load balancers, verifies their health, then removes the old app
servers from the production LB.  This all runs in about 3 seconds, so the transition is smooth and seamless.</p>

<p><span class="full-image-block ssNonEditable"><span><img src="http://devblog.pipelinedeals.com/storage/deploy2.001.png?__SQUARESPACE_CACHEVERSION=1356712765990" alt=""/></span></span></p>

<p>If indeed anything was wrong with our code, or we found it was generating an error we did not expect, we can simply run <code>rake rollback</code> which does the opposite.</p>

<p>Or, if we are completely satisfied that everything looks ok, we can run <code>rake cleanup</code> which will tag the new app servers as the current production servers, and terminate
the old app servers.</p>

<h2>Takeaways</h2>

<p>Originally we designed the Deployer for when we launch large projects, or risky chunks of code.  But I have found that we have started using the Deployer for nearly every
deploy, because it is so easy.  </p>

<p>If your company utilizes Chef, EC2, and ELB, <a href="https://github.com/PipelineDeals/deployer">check out</a> the deployer.  It might work great for your deployment workflow!</p>
<p><br/><br/></p>]]></description><wfw:commentRss>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/rss-comments-entry-32238501.xml</wfw:commentRss></item><item><title>What it means to be truly geographically redundant on AWS</title><dc:creator>Grant Ammons</dc:creator><pubDate>Wed, 05 Dec 2012 20:55:36 +0000</pubDate><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/2012/12/5/what-it-means-to-be-truly-geographically-redundant-on-aws.html</link><guid isPermaLink="false">1001415:11574374:31694706</guid><description><![CDATA[<p><a href="pipelinedeals.com">PipelineDeals</a> is hosted on <a href="aws.amazon.com">Amazon's AWS cloud platform</a>, and has been since 2007. &nbsp; During these years we have been exposed to <a href="http://aws.amazon.com/message/65648/">two</a> <a href="http://aws.amazon.com/message/67457/">separate</a> mass outages, all of which affected their US-EAST availability zone.</p>
<p>Compared to other AWS availability zones, US-EAST center is their busiest, has the cheapest hourly server rates, and (happens to be) the most prone to massive outages.</p>
<p>Given that the majority of our customer base happens to be closer to the east coast, we keep our servers hosted in US-EAST. &nbsp;What this means, however, is that we must be prepared to jump ship to another availibility zone with as little downtime as possible.</p>
<h2>Setting up for geographic redundancy</h2>
<p>PipelineDeals relies heavily on <a href="http://www.opscode.com/chef/">chef</a> for our server configuration managment. &nbsp; Over the past couple months we have made deep investments in our chef cookbooks to ensure that we can bring up any type of server in our stack to 100%, by simply running a rake command. &nbsp;Given that we can do this, we can effortlessly bring up any type of server in any AWS availability zone.</p>
<h2>An ounce of prevention</h2>
<p>We noticed that the past two massive outages were related to each other. &nbsp;They both had to do with Amazon's EBS system, which provides external storage, and also acts as a root device for certain types of instances. &nbsp; We noticed during the outage that our EBS-backed instances were experiencing problems.&nbsp;</p>
<p>We decided to become proactive about it. &nbsp;All of our production servers now no longer rely on EBS-backed instances. &nbsp;Because we use chef to bring up instances, we do not need the benefit of rebooting or stopping servers, thus we do not need one of the major benefits that EBS-backed servers provide. &nbsp;In fact, removing our dependence on EBS has forced our hand to utilize chef to its fullest potential.</p>
<p>We switched our chef recipes to run against instance store backed instances, which do not rely on the EBS subsystem. &nbsp;Since the outage we have replaced all running EBS-backed instances with instance store-backed instances.&nbsp;</p>
<h2>Guarding against the 'mad rush'</h2>
<p>Typically when an outage occurs in US-EAST, there is a massive rush to start firing up instances in other availability zones. &nbsp;So much so that it could take tens of minutes, possibly even hours to fire up servers, all in the midst of an emergency.</p>
<p>To guard against that, we have a "skeleton crew" set of servers that are always on, in US-WEST-1. &nbsp;They include a database slave, an application server, and a background process server. &nbsp;If we need to fail over to our skeleton crew in the west, we could be up while assessing the situation in the east, and/or firing up more powerful hardware in the west.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://devblog.pipelinedeals.com/storage/redundancy.001.png?__SQUARESPACE_CACHEVERSION=1355773347318" alt="" /></span></span></p>
<p>Essentially what would happen is we would promote our slave in the west to become a master, fire up a new west coast slave, and start firing up the ancillary servers that make up the full PipelineDeals experience.</p>
<h2>Practice makes perfect</h2>
<p>The multi-day threat of hurricaine sandy facilitated multiple practice runs to fail over to the west. &nbsp;This included exercising every single one of our chef recipes that make up the entire infrastructure of PipelineDeals.</p>
<p>During that time we made many many commits to our chef repository, and ensured that we could fire up servers to 100%, time after time.</p>
<p>In addition, we were able to combine roles of servers, to reduce the amount of servers needed to make up the entire PipelineDeals experience.&nbsp;</p>
<p>&nbsp;</p>]]></description><wfw:commentRss>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/rss-comments-entry-31694706.xml</wfw:commentRss></item><item><title>Announcing V3 of the PipelineDeals API</title><dc:creator>Grant Ammons</dc:creator><pubDate>Mon, 18 Jun 2012 19:33:02 +0000</pubDate><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/2012/6/18/announcing-v3-of-the-pipelinedeals-api.html</link><guid isPermaLink="false">1001415:11574374:16812054</guid><description><![CDATA[<p>The developers at PipelineDeals are happy to announce a new version of our API.   V3 introduces many changes, including the following:</p>

<ul>
<li>Read-only access to all of your admin data</li>
<li>A new, simplified way of handling custom fields for Deals, People, and Companies</li>
<li>New, more powerful filtering for Deals, People and Companies</li>
</ul>

<p>You can get the full scoop by going to our <a href="http://www.pipelinedeals.com/api/docs">API documentation</a>.</p>

<h3>Starting out</h3>

<p>Access to our API is now disabled by default.  To ensure the security of your account, you must enable the new API before you can use it.  Account admins can can enable your api by going to the <a href="https://www.pipelinedeals.com/admin/api">API section</a> or the Admin menu.</p>

<h3>Read-only access to all of your admin data</h3>

<p>We now provide read-only access to all of your admin data.  This includes things like person statuses, sources, deal stages, note and event categories, as well as all custom fields defined for Deals, Companies, and People.</p>

<p>This will enable you to do things with the api you previously could not, like tagging or assigning a status to a person, setting the stage of a deal, or assigning a category id to a note.</p>

<h3>Handling custom fields</h3>

<p>We have greatly simplified how to store and retrieve custom fields for all of our entities that have custom fields, including Deals, People and Companies.</p>

<p>For instance, say your company is set up to have 3 deal custom fields.  The first, Region, is a multiselect dropdown.  The second, Square footage, is a numeric, and the 3rd, Product type, is a single-select dropdown.</p>

<p>When retrieving a single deal, you'll get back the custom fields for that deal in a new, clean way.</p>

<pre><code>curl "https://api.pipelinedeals.com/api/v3/deals/3.json?api_key=2R4X8Df77lUcP7Iwa1j" | prettify_json.rb

{
  "id": 3,
  "name": "Grant's Deal"
  ...
  "custom_fields": {
    "custom_label_82": [28,29,30]  // this is our region custom field
    "custom_label_83": null,       // this is our square footage field
    "custom_label_90": 49,         // this is our product type dropdown field
  },
}
</code></pre>

<p>The region field contains an array of custom field label dropdown entry ids.  You can get your custom field label dropdown choices by using the <a href="http://www.pipelinedeals.com/api/docs/resources/deal_custom_field_labels">deal custom field labels list api call</a>.</p>

<p>This makes working with custom fields very easy.  To update your fields, simply POST the data back to us, with the ids you want checked:</p>

<pre><code>curl -X PUT "https://api.pipelinedeals.com/api/v3/deals/3.json?api_key=2R4X8Df77lUcP7Iwa1j" -d \
  "'deal': { 
    'custom_fields': {
      'custom_label_82': [31,32],
      'custom_label_82': 456,
      'custom_label_90': null
    }
  "
</code></pre>

<p>The deal will be updated with the correct custom fields.  This custom_fields object is available for Deals, People, and Companies.</p>

<h3>New, more powerful filtering for Deals, People, and Companies</h3>

<p>You can filter and sort a list of Deals, People or Companies using our new powerful filtering framework.</p>

<p>All available filters are listed in the <a href="http://www.pipelinedeals.com/api/docs">API documentation</a>.</p>
]]></description><wfw:commentRss>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/rss-comments-entry-16812054.xml</wfw:commentRss></item><item><title>Javascript error reporting for fun and profit</title><dc:creator>Grant Ammons</dc:creator><pubDate>Sun, 12 Feb 2012 20:56:17 +0000</pubDate><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/2012/2/12/javascript-error-reporting-for-fun-and-profit-1.html</link><guid isPermaLink="false">1001415:11574374:15003314</guid><description><![CDATA[<p>Here at <a href="http://www.pipelinedeals.com">PipelineDeals</a>, our app is very Javascript intensive.  In fact, for our Jupiter release, we moved much of our logic from rails to the browser and Javascript, using <a href="http://documentcloud.github.com/backbone/">Backbone.js</a>, <a href="http://coffeescript.org/">Coffeescript</a> and a host of other new cutting edge technologies.</p>

<p>During deploys and other edge cases, we want to know if a user has received a javascript error, just  like we would with any other type of exception.  We deploy very frequently.   A few weeks ago we ran into a problem where one of our app servers did not minify and concatenate one of our javascript files correctly, and led to a host of issues that customers saw.  In order to prevent this in the future, we decided to search around and see if we could have javascript errors report to one of our favorite tools, <a href="http://newrelic.com">NewRelic RPM</a>.</p>

<p>As it turns out, catching and reporting Javascript errors is pretty easy.  We ended up hooking into <code>window.onerror</code>, which we define right after we add jQuery, right at the top of the page.</p>

<pre><code>// Determine if the error occurred before or after document ready
jQuery(function() { window.documentIsReady = true; });

// report a maximum of 5 errors
window.MaximumErrorCount = 5;

window.onerror = function(errorMsg, file, lineNumber) {
  window.errorCount || (window.errorCount = 0);

  // this example assumes a ppd object that has various information about 
  // our environment and our logged in user.
  if (ppd.env == 'production' &amp;&amp; window.errorCount &lt;= window.MaximumErrorCount) {
    window.errorCount += 1;

    // post the error with all the information we need.
    jQuery.post('/javascript_error', {error: errorMsg, file: file, location:     window.location.href, lineNumber: lineNumber, userId: ppd.User.id, documentReady:     window.documentIsReady, ua: navigator.userAgent});
  }
}
</code></pre>

<p>The above code will execute if the user receives a javascript error.  It will then do an ajax post to our app, which will handle the error.</p>

<pre><code>class JavascriptErrorController &lt; ApplicationController

  def javascript_error
      # post the error to newrelic.
      # You could also send an email, notify hipchat, whatever.
      NewRelic::Agent.notice_error("Javascript error: #{params[:error]}", {:uri =&gt; params[:location], :params =&gt; params})
    end
    head :ok
  end
end
</code></pre>

<p>Not only has this been invaluable for catching that rare, but painful asset problem, but it will also catch legitimate issues and race cases where sometimes a variable might not be defined.</p>

<p>In NewRelic, javascript errors get report just like any other error, and if we do have an asset problem, our error rate will shoot through the roof and all the devs will be notified.</p>

<p><span class="full-image-block ssNonEditable"><span><img src="http://devblog.pipelinedeals.com/storage/Screen Shot 2012-02-12 at 4.17.23 PM.png?__SQUARESPACE_CACHEVERSION=1329081624861" alt=""/></span></span></p>
]]></description><wfw:commentRss>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/rss-comments-entry-15003314.xml</wfw:commentRss></item><item><title>Improving Rails Performance with Twitter's Kiji Ruby</title><dc:creator>Michael Pellon</dc:creator><pubDate>Wed, 07 Sep 2011 19:01:23 +0000</pubDate><link>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/2011/9/7/improving-rails-performance-with-twitters-kiji-ruby.html</link><guid isPermaLink="false">1001415:11574374:12764688</guid><description><![CDATA[<div id="_mcePaste"></div>
<div id="_mcePaste" style="text-align: justify; font-size: 100%;"></div>
<div id="_mcePaste" style="text-align: justify;">In March, Twitter unveiled "<a href="http://engineering.twitter.com/2011/03/building-faster-ruby-garbage-collector.html">Kiji</a>", an effort to significantly reduce the impact of running the garbage collector in the Ruby Enterprise Edition (REE) runtime. &nbsp;Many have criticized their effort because it focused on the older 1.8.7 instead of the newer 1.9.x version of ruby. &nbsp; But for older, larger apps that still run Rails 2.x or need ruby 1.8, &nbsp;Kiji may be worth exploring.</div>
<div style="text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="text-align: justify;"></div>
<div style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<p>&nbsp;</p>
<div id="_mcePaste" style="text-align: justify;">MRI relies on a single heap that basically resembles &nbsp;a <a href="http://en.wikipedia.org/wiki/Slab_allocation">slab allocator</a>. &nbsp; New slabs are created via <a href="http://en.wikipedia.org/wiki/Malloc">malloc()</a> &nbsp;and carved up into a fixed 40-byte slot. &nbsp;Each slot can hold a variety of ruby objects. &nbsp; When a slab becomes full, &nbsp;GC is invoked to clean things up by looking for non-reachable objects. &nbsp;If the slab is still full after GC, then a new slab is allocated.</div>
<div style="text-align: justify;"></div>
<div style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="text-align: justify;">MRI&rsquo;s GC uses a very simple naive <a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)#Na.C3.AFve_mark-and-sweep">mark-and-sweep</a> algorithm. &nbsp;When MRI GC runs, all code execution stops until GC is finished. &nbsp; The implementation is such that it does not (easily) leave the door open to use more advanced GC techniques.&nbsp;</div>
<div style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">For large applications, and espcially web-based applications, this can become a major issue. &nbsp; &nbsp;There is a direct relationship between the number of objects and the garbage collection runtime. &nbsp;More objects equals more time spent garbage collecting and less time serving customer requests.&nbsp;</div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div id="_mcePaste" style="text-align: justify;"></div>
<div style="text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">This is where Kiji comes in.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">Kiji&rsquo;s GC acts like a type of <a href="http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)#Generational_GC_.28ephemeral_GC.29">generational</a> algorithm by splitting objects into heaps based on their age with the notion that younger objects are more likely to become garbage. &nbsp;While not a &ldquo;true&rdquo; implementation of a generational GC, because objects cannot move between heaps , there are still benefits to using it. &nbsp; Kiji&rsquo;s GC allows the CPU to continue executing ruby code while GC is run. &nbsp;For web-based applications, this is a huge win, as your users do not have to wait for GC to perform a full run during the request cycle.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">Kiji also changes the way that frequently-used objects are stored in the heap. &nbsp;For web-based ruby applications, the majority of &ldquo;live&rdquo; objects in the heap are RNodes. &nbsp; &nbsp;RNodes are responsible for holding the actual source code of the application. &nbsp;Kiji implements a long-life stack that solely stores RNodes which is garbage collected much less frequently than the primary stack. &nbsp;Because of the primary stack now has less objects, GC runs complete much faster, at the expense of the application consuming more memory.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">Twitter&rsquo;s initial <a href="http://engineering.twitter.com/2011/03/building-faster-ruby-garbage-collector.html">announcement </a>and subsequent <a href="http://engineering.twitter.com/2011/05/faster-ruby-kiji-update.html">followup</a> both included results from running the <a href="http://twitter.com">twitter.com</a> webapp under synthetic load but having run Kiji in production for nearly two months we are excited to share the noticeable difference it has made within our own stack.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">In&nbsp;the figure below we have collected several weeks worth of runtime data from our production application servers. Each point in the figure represents the average of one day's worth of data collected in one minute samples. To understand the potential effect Kiji might have our application's runtime we captured both the average time a customer's request spent solely within the Ruby runtime as well as our application's apdex, an open standard that converts response time measurements into the degree to which user expectations are met. An application's apdex can range uniformly from zero (no users satisfied) to one (all users satisfied) <span style="font-family: sans-serif; color: #000000;"><span style="line-height: 19px;">.</span></span></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"><span style="font-family: sans-serif; color: #000000;"><span style="line-height: 19px;"><span class="full-image-block ssNonEditable"><span><img src="http://devblog.pipelinedeals.com/storage/post-images/Screen%20shot%202011-09-07%20at%202.30.06%20PM.png?__SQUARESPACE_CACHEVERSION=1315429588450" alt="" /></span></span><br /></span></span></div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">Days spent running REE or Kiji neatly cluster along expected lines, with REE posting signficantly higher response times and subsquently lower apdexes. Whle utilizing nearly fifty percent less of the CPU than REE, Kiji did, however, bring a nearly three fold memory increase. Overall Kiji shaved off nearly one second from our page load time bringing us to an average of three seconds per page well below today's global average.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">If&nbsp;you would like to take Kiji for a spin with your own application you can find it on&nbsp;<a href="https://github.com/twitter/rubyenterpriseedition187-248">Github</a>. We would love to hear about your experiences using Kiji (or another alternative Ruby runtime) with Rails.</div>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;"><span style="text-decoration: underline;"><strong>Technical Notes:</strong></span>&nbsp;</div>
<div style="font-size: 100%; text-align: justify;"></div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;">* Our production application servers use Debian 5.0, we have successfully compiled Kiiji on RPM-based distributions (RedHat/CentOS/Fedora) as well. To date we have been unable to successfullly build Kiji on an Ubuntu based box (Lucid - 10.04 and later tested) due to an bug triggered by libc6.&nbsp;</div>
<p>&nbsp;</p>
<div style="font-size: 100%; text-align: justify;"></div>
<div style="font-size: 100%; text-align: justify;">* We built Kiji against Google's TCMalloc instead of malloc() producing the same binary as Twitter using the method they provided in their <a href="https://github.com/twitter/rubyenterpriseedition187-248/blob/master/README-kiji">README</a>.</div>]]></description><wfw:commentRss>http://devblog.pipelinedeals.com/pipelinedeals-dev-blog/rss-comments-entry-12764688.xml</wfw:commentRss></item></channel></rss>