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

<channel>
	<title>Digg the Blog &#187; Digg Technology</title>
	<atom:link href="http://blog.digg.com/?feed=rss2&#038;cat=14" rel="self" type="application/rss+xml" />
	<link>http://blog.digg.com</link>
	<description></description>
	<lastBuildDate>Thu, 19 Nov 2009 15:08:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A New Kid&#8217;s Perspective on Digg&#8217;s Engineering Culture</title>
		<link>http://blog.digg.com/?p=1081</link>
		<comments>http://blog.digg.com/?p=1081#comments</comments>
		<pubDate>Thu, 12 Nov 2009 16:13:19 +0000</pubDate>
		<dc:creator>Chris Goffinet</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=1081</guid>
		<description><![CDATA[As one of the most recent additions to Digg&#8217;s engineering team, I thought I would share with you some of what it&#8217;s like to work at a place that&#8217;s doing some really innovative and exciting things on the Web. When I joined Digg a little over six months ago, I had no idea what to [...]]]></description>
			<content:encoded><![CDATA[<p>As one of the most recent additions to Digg&#8217;s engineering team, I thought I would share with you some of what it&#8217;s like to work at a place that&#8217;s doing some really innovative and exciting things on the Web. When I joined Digg a little over six months ago, I had no idea what to expect. Coming from an organization of 15,000+ employees at Yahoo, you form certain expectations. Startup life is an entirely different animal in terms of speed and agility and one of the key lessons I&#8217;ve learned is that you must strike a balance between engineering and business. My first few weeks of joining Digg, I began watching and tediously studying what makes the engineering organization tick. Culture plays a large part in how engineering works with other departments such as operations and product. The culture at Digg is great and I can&#8217;t stress that enough. Getting to work on hard problems is what every great engineer strives for. We want to be challenged and pushed to our limits. I&#8217;m excited to say that I joined a company that allows me to do that.</p>
<h2>Operations vs Engineering</h2>
<p>In many companies, you have the engineers and then you have the operations team. Engineers complain that the operations people aren&#8217;t nimble and agile. The operations people complain that the engineers never plan or keep them in the loop until the last minute. In many ways it&#8217;s an uphill battle for most organizations. Because I deeply care so much about infrastructure, it forces me to play a dual role. I have to understand what&#8217;s involved from the engineering effort, and what&#8217;s required to fulfill the needs of the operations team to keep things moving at light speed. One of the great things at Digg is that the two teams work closely together to achieve the same goals. Respect and guidance is key.</p>
<h2>Under the hood</h2>
<p>We’ve been making a lot of changes internally. Starting with providing more ownership to engineers, and investing in infrastructure that will scale and allow us the agility to make rapid decisions. A few months ago we moved the entire Digg codebase from Subversion over to Git. Ultimately we saw the headaches of merging in subversion and we had enough engineers already using it on open source projects, that we knew it was the right direction to improving our foundation as a company. Working at Yahoo, I quickly learned how valuable distributed computing, storage and logging can be for an engineering team to function. At Digg we have been been making investments into our data storage infrastructure (Hadoop &amp; Cassandra), along with building out massive logging infrastructure that allows us the ability to collect metrics and reporting in real-time. The core infrastructure team at Digg has been using Hadoop, and our logging framework to mirror production traffic against our test clusters to analyze performance and do internal dark launches. Performance is critical to engineering and our cost of operations. We’ve been working hard on eventual consistency between multiple datacenters, multi-tier caching, front-end and CDN performance, automatic failover of services across datacenters, and building a new software stack that isn’t just scalable and fast, but is also cost effective and flexible.</p>
<h2>Open Source</h2>
<p>Digg’s support of open source has been truly refreshing; considering at other companies I’ve worked at it has proven difficult to get patches or new projects released. Not many companies realize the true value that open source provides. VP of Engineering, John Quinn, saw this early on. I was really happy to see someone on the executive management team actually understand its importance. It was one of the many reasons I joined Digg. In terms of open source at Digg, we are heavily involved in the community. We understand its importance to our infrastructure as well as how important it is to give back to the community. We have developers working on: Cassandra, Thrift, Scribe, Hadoop, Hive, and memcached to name a few. Along with a slew of our own projects over on Github.</p>
<h2>Bringing it together</h2>
<p>Without a solid foundation to really build upon, you’re left spinning your wheels on cruft, frustration and telling the product people, that new addition or change is going to take weeks to months, instead of days. I like thinking in days, and sometimes that surprises people. When your tools are automated and your foundation is solid, it really allows you to iterate, test and actually make a decision. We’ve all sat in meeting after meeting trying to come up with ideas and decisions of what to do, just to setup up another meeting. You have to have a balance of risk, foundation, culture, open source and most of all, talented people who can see the big picture.</p>
<p>We have many hard problems to solve here at Digg, and many more amazing ideas to build on. We are making remarkable strides in just the few months that I’ve started working at this company and I look forward to the road ahead&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=1081</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding Things Up</title>
		<link>http://blog.digg.com/?p=1015</link>
		<comments>http://blog.digg.com/?p=1015#comments</comments>
		<pubDate>Thu, 08 Oct 2009 17:18:09 +0000</pubDate>
		<dc:creator>John Quinn</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=1015</guid>
		<description><![CDATA[We&#8217;ve heard from you that performance is important and the Digg engineering team are busy working on making our site load faster. We&#8217;ve been moving static resources such as CSS, JavaScript and images to a CDN and testing several providers. We have been converting to high performance distributed databases for key features. We have also [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve heard from you that performance is important and the Digg engineering team are busy working on making our site load faster. We&#8217;ve been moving static resources such as CSS, JavaScript and images to a <a href="http://en.wikipedia.org/wiki/Content_delivery_network">CDN</a> and testing several providers. We have been <a href="http://blog.digg.com/?p=966">converting</a> to high performance distributed databases for key features. We have also significantly improved our use of cache control directives and removed dependencies on 3rd party sites with performance issues.</p>
<p>Today, we&#8217;re also making some changes to reduce page payloads and minimize HTTP requests with subtle UI changes. By removing the 16px user icon from stories on the home page and other story lists, we&#8217;re reducing HTTP requests to Digg for a warm cache load by around 75%.</p>
<p>This is just the start of the performance initiatives that will unfold over the next few months and will result in order-of-magnitude speed-ups for many use cases.</p>
<p>Cheers,</p>
<p>John.</p>
<p>&#8220;If everything seems under control, you&#8217;re just not going fast enough.&#8221;, Mario Andretti</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=1015</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Looking to the future with Cassandra</title>
		<link>http://blog.digg.com/?p=966</link>
		<comments>http://blog.digg.com/?p=966#comments</comments>
		<pubDate>Wed, 09 Sep 2009 16:42:11 +0000</pubDate>
		<dc:creator>Ian</dc:creator>
				<category><![CDATA[Digg Technology]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[infrastructure]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=966</guid>
		<description><![CDATA[Digg has been researching ways to scale our database infrastructure for some time now. We’ve adopted a traditional vertically partitioned master-slave configuration with MySQL, and also investigated sharding MySQL with IDDB. Ultimately, these solutions left us wanting. In the case of the traditional architecture, the lack of redundancy on the write masters is painful, and [...]]]></description>
			<content:encoded><![CDATA[<p>Digg has been researching ways to scale our database infrastructure for some time now. We’ve adopted a <a href="http://blog.digg.com/?p=213">traditional vertically partitioned master-slave</a> configuration with MySQL, and also investigated sharding MySQL with <a href="http://blog.digg.com/?p=607">IDDB</a>. Ultimately, these solutions left us wanting. In the case of the traditional architecture, the lack of redundancy on the write masters is painful, and both approaches have significant management overhead to keep running.</p>
<p>Since it was already necessary to abandon data normalization and consistency to make these approaches work, we felt comfortable looking at more exotic, non-relational data stores. After considering HBase, Hypertable, Cassandra, Tokyo Cabinet/Tyrant, Voldemort, and Dynomite, we settled on <a href="http://incubator.apache.org/cassandra/">Cassandra</a>.</p>
<p>Each system has its own strengths and weaknesses, but Cassandra has a good blend of everything. It offers column-oriented data storage, so you have a bit more structure than plain key/value stores. It operates in a distributed, highly available, peer-to-peer cluster. While it’s currently lacking some core features, it gets us closer to where we want to be than the other solutions.</p>
<p>We started thinking seriously about deploying Cassandra in production around three weeks ago. After looking at the site for something that would be a good fit, we settled on green badges. These badges appear on the Digg icon for a story when one of your friends has dugg it. This has been a problematic feature to support as we’ve grown, and corners had to be cut to keep it from breaking. They’re disabled on large pages (such as top in 365) and highly digg stories.</p>
<p>The fundamental problem is endemic to the relational database mindset, which places the burden of computation on reads rather than writes. This is completely wrong for large-scale web applications, where response time is critical. It’s made much worse by the serial nature of most applications. Each component of the page blocks on reads from the data store, as well as the completion of the operations that come before it.</p>
<p>Non-relational data stores reverse this model completely, because they don’t have the complex read operations of SQL. The model forces you to shift your computation to the writes, while reducing most reads to simple operations – the equivalent of <code>SELECT * FROM `Table`</code>.</p>
<div class="outline-2">
<h2>The Problem</h2>
<div>
<p>In both models, we’re computing the intersection of two sets:</p>
<ol>
<li> Users who dugg an item.</li>
<li> Users that have befriended the digger.</li>
</ol>
</div>
</div>
<div class="outline-2">
<h2>The Relational Model</h2>
<div>
<p>The schema for this information in MySQL is:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`Diggs`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span>      INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`itemid`</span>  INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`userid`</span>  INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`digdate`</span> DATETIME<span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`user`</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`userid`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`item`</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`itemid`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8;
&nbsp;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`Friends`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span>           INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`userid`</span>       INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`username`</span>     VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`friendid`</span>     INT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`friendname`</span>   VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`mutual`</span>       TINYINT<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`date_created`</span> DATETIME<span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>                <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">UNIQUE</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`Friend_unique`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`userid`</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">`friendid`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">KEY</span>        <span style="color: #ff0000;">`Friend_friend`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`friendid`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>utf8;</pre></div></div>

<p>The <code>Friends</code> table contains many million rows, while <code>Diggs</code> holds hundreds of millions. Computing the intersection with a <code>JOIN</code> is much too slow in MySQL, so we have to do it in PHP. The steps are:</p>
<ol>
<li> Query <code>Friends</code> for all my friends. With a cold cache, this takes around 1.5 seconds to complete.</li>
<li> Query <code>Diggs</code> for any diggs of a specific item by a user in the set of friend user IDs. This query is <em>enormous</em>, and looks something like:

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">`digdate`</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`Diggs`</span>
 <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #ff0000;">`userid`</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">59</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">9006</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15989</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">16045</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">29183</span><span style="color: #66cc66;">,</span>
                    <span style="color: #cc66cc;">30220</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">62511</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">75212</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">79006</span><span style="color: #66cc66;">&#41;</span>
   <span style="color: #993333; font-weight: bold;">AND</span> itemid <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">13084479</span> <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">`digdate`</span> <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`id`</span> <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">4</span>;</pre></div></div>

<p>The real query is actually much worse than this, since the <code>IN</code> clause contains every friend of the user, and this can balloon to hundreds of user IDs. A full query can actually clock in at 1.5kb, which is many times larger than the actual data we want. With a cold cache, this query can take <em>14 seconds</em> to execute.</li>
</ol>
<p>Of course, both queries are cached, but due to the user-specific nature of this data, it doesn’t help much.</p></div>
</div>
<div class="outline-2">
<h2>The Non-Relational Model</h2>
<div>
<p>Since non-relational data stores don’t have schemas in the same sense as relational databases, it’s harder to explain the Cassandra model. Non-relational schemas are much more flexible, and they’re mostly convention.</p>
<p>What we did is create a set of buckets per <code>(user, item)</code> pair, with each bucket containing a list of users who dugg the item who are also friends of the viewing user. With this layout, reads don’t require computation.</p>
<p>When an item is dugg, we asynchronously populate Cassandra. This job fetches the list of followers of the digging user, and places one column in each of their buckets. This is a large amount of data for popular users. Kevin Rose, for example, has 40,000 followers. Thanks to Cassandra’s excellent write performance and batch operations, every column is inserted at once, atomically, <em>in under a second.</em></p>
<p>There’s no such thing as a free lunch, of course, and the fundamental trade-off in this model is CPU vs. disk. We have to store the computed results on disk, rather than generating them on the fly. It’s an acceptable trade-off in our case, since disks are cheap and scaling SQL is very hard.</p>
<p>For this feature, the fully denormalized Cassandra dataset weighs in at 3 terabytes and 76 billion columns.</p></div>
<div class="outline-3">
<h3>Conclusion</h3>
<div>
<p>We haven’t made any secret of our interest in NOSQL in general and Cassandra specifically. We believe in this technology, and we are contributing to its ongoing development, both by submitting patches and by funding development of features necessary to support wide scale deployment.</p>
<p>This is the first thing we’ve migrated to Cassandra, but it definitely won’t be the last.</p></div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=966</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Recent Changes to NOFOLLOW on External Links</title>
		<link>http://blog.digg.com/?p=864</link>
		<comments>http://blog.digg.com/?p=864#comments</comments>
		<pubDate>Wed, 02 Sep 2009 20:31:23 +0000</pubDate>
		<dc:creator>John Quinn</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=864</guid>
		<description><![CDATA[Hi all,
We’ve made a few changes to the way Digg links to external sites that may impact some folks in the SEO community. These changes reduce the incentive to post spammy content (or link spam) to Digg, while still flowing &#8217;search engine juice&#8217; freely to quality content. We’ve added rel=”nofollow” to any external link that [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all,</p>
<p>We’ve made a few changes to the way Digg links to external sites that may impact some folks in the SEO community. These changes reduce the incentive to post spammy content (or link spam) to Digg, while still flowing &#8217;search engine juice&#8217; freely to quality content. We’ve added <code>rel=”nofollow”</code> to any external link that we’re not sure we can vouch for. This includes all external links from comments, user profiles and story pages below a certain threshold of popularity.</p>
<p>This work was done in consultation with leading experts from the SEO/SEM and link spam fields, in an effort to lookout for the interests of content providers and the Digg community. As always, we will closely monitor these changes in the wild and iterate based on feedback.</p>
<p>Cheers,<br />
John</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=864</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding the needle in the haystack</title>
		<link>http://blog.digg.com/?p=956</link>
		<comments>http://blog.digg.com/?p=956#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:05:59 +0000</pubDate>
		<dc:creator>sammy</dc:creator>
				<category><![CDATA[Digg Technology]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[solr]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=956</guid>
		<description><![CDATA[Hey Diggers,
Many in the community have expressed interest in understanding how our new search works.  We&#8217;re using Apache SOLR/Lucene which helped us scale horizontally and solved many of our relevancy issues as well as enabling discovery of new content through facets.  Beyond site search, the rich set of features has allowed us build a platform that [...]]]></description>
			<content:encoded><![CDATA[<p>Hey Diggers,</p>
<p>Many in the community have expressed interest in understanding how our new search works.  We&#8217;re using Apache <a href="http://lucene.apache.org/solr/">SOLR</a>/<a href="http://lucene.apache.org/">Lucene</a> which helped us scale horizontally and solved many of our relevancy issues as well as enabling discovery of new content through facets.  Beyond site search, the rich set of features has allowed us build a platform that enables other features such as Related By Source and Related By Keywords.  I&#8217;ve recently had the pleasure of doing a <a href="http://www.lucidimagination.com/Community/Hear-from-the-Experts/Podcasts-and-Videos/Grant-Ingersoll-Talks-Sammy-Yu">podcast</a> with Grant Ingersoll from Lucid Imagination that discusses some of these details.   I hope this podcast gives some insight with regards to how we&#8217;ve built the new search platform.</p>
<p>&#8216;Til next time,<br />
Sammy</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=956</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DUI is 1.0.0!</title>
		<link>http://blog.digg.com/?p=996</link>
		<comments>http://blog.digg.com/?p=996#comments</comments>
		<pubDate>Tue, 01 Sep 2009 16:05:50 +0000</pubDate>
		<dc:creator>Micah Snyder</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=996</guid>
		<description><![CDATA[Hey all,
Just a quick note about our DUI JavaScript project: Two weeks ago I pushed v1.0.0 of DUI to Digg&#8217;s Github, and nothing appears to have melted, so as of right now I&#8217;m officially declaring it Ready For Prime Time(tm).
1.0.0 is a complete rewrite from the ground up. The API has changed significantly, and much [...]]]></description>
			<content:encoded><![CDATA[<p>Hey all,</p>
<p>Just a quick note about our <a href="http://github.com/digg/dui" target="_blank">DUI JavaScript project</a>: Two weeks ago I pushed v1.0.0 of DUI to <a href="http://github.com/digg" target="_blank">Digg&#8217;s Github</a>, and nothing appears to have melted, so as of right now I&#8217;m officially declaring it Ready For Prime Time(tm).</p>
<p>1.0.0 is a complete rewrite from the ground up. The API has changed significantly, and much cruft has been slain, so you should probably give <a href="http://wiki.github.com/digg/dui" target="_blank">the wiki</a> a once-over before diving in.</p>
<p>Also, I&#8217;ll be speaking at <a href="http://events.jquery.com/jquery-conference-2009/" target="_blank">jQuery Conference &#8216;09</a> in September. If you&#8217;re curious about DUI, feel free to attend my session and grill me about everything I did wrong ;)</p>
<p>Cheers,</p>
<p>- Micah</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=996</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>digg.git &#8211; part 1</title>
		<link>http://blog.digg.com/?p=900</link>
		<comments>http://blog.digg.com/?p=900#comments</comments>
		<pubDate>Fri, 21 Aug 2009 15:17:20 +0000</pubDate>
		<dc:creator>Matt Erkkila</dc:creator>
				<category><![CDATA[Digg Technology]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[digg]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=900</guid>
		<description><![CDATA[Over the last 12-16 months Digg has seen some pretty big growth internally.  Our engineering team has tripled in size and we added both a QA and R&#38;D team.  We went from releasing code once every 3-4 months to releasing code every day.  We encountered a number of roadblocks during the transition, some easy to [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last 12-16 months Digg has seen some pretty big growth internally.  Our engineering team has tripled in size and we added both a QA and R&amp;D team.  We went from releasing code once every 3-4 months to releasing code every day.  We encountered a number of roadblocks during the transition, some easy to overcome, others, not so easy.  We had to change some of our processes, adapt some new technology, and change a lot of peoples mindsets.</p>
<p>When I started with the company the entire engineering team would work on the same project together, everyone in the company would get together in a conference room for an afternoon or two and do QA, and when it was all done, we released it and moved on to the next project.  Fast-forward to today, we have multiple projects, all being developed in parallel, with QA testing each feature as the engineer writes it.  And as soon as it is finished and signed off on, it&#8217;s released.</p>
<p>In the beginning we used <a href="http://subversion.tigris.org/" target="_blank">Subversion</a>.  We checked out, branched, committed, merged, and tagged.  It was far from perfect, it didn&#8217;t make anyone happy, but it&#8217;s what we had.  And it worked, mostly.  It was simple to understand and pretty easy to use.  But it didn&#8217;t scale.  As our engineering team grew, more and more work was being done in the same code base, we started stepping on each others toes more and more.</p>
<p>The integration process (merging a feature into trunk for release) would sometime take days and result in numerous conflicts in the code.  It was up to the person doing the merging to resolve it himself or try and track down the original developer to determine which pieces needed to be kept.  This resulted in both a large number of bugs as well as code just simply disappearing.  Something that was costing us time, money, and impacting our users experience.  All of which we take very seriously.</p>
<p>We knew there must be a better way, so we started looking for it.  We tried upgrading from subversion 1.4 to 1.5, which has &#8220;merge tracking&#8221;.  We hoped it would make our integration process easier.  But after working with it for a few weeks we realized that the &#8220;merge tracking&#8221; feature was akin to putting lipstick on a pig.  And as nice as it sounded, it just wasn&#8217;t going to cut it.</p>
<p>Then everyone started talking about <a href="http://git-scm.com/" target="_blank">Git</a>.  A few of us had heard about it, only a couple had ever used it, and mostly just for personal projects.  But it was the next cool thing.  It was GREAT!  It&#8217;s going to make our engineers more productive and make their lives so much easier.  It was like someone was handing us a nice tall cold glass of cherry kool-aid and telling us everything was going to be OK.  Would you drink it?  Well, we did.  Not the entire glass at first, just a little sip.  Then we realized, it wasn&#8217;t so bad, it actually felt kind of good.  So what did we do?  In true Digg fashion, we chugged the rest of the glass and asked for seconds.</p>
<p>So why is Git so great?  Well, simply put, it&#8217;s powerful and it&#8217;s distributed.</p>
<p>It allows you to do complex tasks with only a few commands.  It makes things like branching and merging almost completely thoughtless.  It even allows you, and goes so far as to encourage you, to rewrite history.  It really lets each engineer work the way they want to.  And when they&#8217;re ready, allows them to push their code upstream for others to see.  It manages code and changesets so drastically different from Subversion that it truly takes a complete mental shift about how you think about source control to even begin to understand it.  But believe me, it&#8217;s a good thing.</p>
<p>But Git does have it&#8217;s downsides.  At first it can be difficult to understand what is really happening behind the scenes when you run a command and if something does go wrong, you really need to understand how Git works internally to correct your mistake.  It also isn&#8217;t completely polished yet, there are no good GUI&#8217;s for it and the error messages you get when a command fails might as well be written in sanskrit.</p>
<p>Even with all of its downsides, its steep learning curve, confusing error messages, and lack of polished UI&#8217;s.  It works.  It works so well in fact that after switching to Git, we were able to reduce the time our integration process took from days to minutes.  Literally from 1-2 days down to about 30 minutes.  And, after it&#8217;s done, we have much more confidence that the merge was done correctly.  We&#8217;re also able to release code on a daily basis, with very minimal effort, something that was extremely painful to do under Subversion.</p>
<p>Stay tuned for part two.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=900</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Much Ado About IE6</title>
		<link>http://blog.digg.com/?p=878</link>
		<comments>http://blog.digg.com/?p=878#comments</comments>
		<pubDate>Fri, 10 Jul 2009 17:59:46 +0000</pubDate>
		<dc:creator>Mark Trammell</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=878</guid>
		<description><![CDATA[Here at Digg, like most sites, the designers, developers, and QA engineers spend a lot of time making sure the site works in IE6, an eight-year-old browser superseded by two full releases. It consumes time that could be spent building the future of Digg. Here&#8217;s what we&#8217;re gonna do — and not do — about [...]]]></description>
			<content:encoded><![CDATA[<p>Here at Digg, like most sites, the designers, developers, and QA engineers spend a lot of time making sure the site works in IE6, an eight-year-old browser superseded by two full releases. It consumes time that could be spent building the future of Digg. Here&#8217;s what we&#8217;re gonna do — and not do — about it.</p>
<h3>Should Digg block IE6?</h3>
<p>Currently, IE6 usage accounts for 10% of Digg visitors and 5% of page views on Digg. While this is down from 13% and 8% a year ago respectively, IE6 still accounts for a fairly large portion of Digg usage. That said, a lot of time is spent by Digg engineers supporting site activity like diggs, buries, and comments in IE6, and while it accounts for 5% of site traffic, IE6 accounts for only 1% of diggs, buries, and comments.</p>
<table border="1px">
<caption>IE6 as a percentage of all browsers</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Visitors</th>
<th scope="col">Page Views</th>
<th scope="col">Diggs</th>
<th scope="col">Buries</th>
<th scope="col">Comments</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td class="firstColumn" scope="row">Jun 2008</td>
<td>13%</td>
<td>8%</td>
<td>3%</td>
<td>4%</td>
<td>5%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">Jul 2008</td>
<td>13%</td>
<td>8%</td>
<td>3%</td>
<td>3%</td>
<td>4%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Aug 2008</td>
<td>13%</td>
<td>7%</td>
<td>2%</td>
<td>3%</td>
<td>4%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">Sept 2008</td>
<td>12%</td>
<td>7%</td>
<td>2%</td>
<td>2%</td>
<td>3%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Oct 2008</td>
<td>12%</td>
<td>6%</td>
<td>2%</td>
<td>2%</td>
<td>3%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">Nov 2008</td>
<td>11%</td>
<td>6%</td>
<td>2%</td>
<td>3%</td>
<td>3%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Dec 2008</td>
<td>11%</td>
<td>6%</td>
<td>2%</td>
<td>2%</td>
<td>3%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">Jan 2009</td>
<td>10%</td>
<td>5%</td>
<td>2%</td>
<td>2%</td>
<td>3%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Feb 2009</td>
<td>10%</td>
<td>6%</td>
<td>2%</td>
<td>1%</td>
<td>2%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">Mar 2009</td>
<td>10%</td>
<td>5%</td>
<td>2%</td>
<td>2%</td>
<td>2%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Apr 2009</td>
<td>10%</td>
<td>5%</td>
<td>2%</td>
<td>1%</td>
<td>2%</td>
</tr>
<tr class="even">
<td class="firstColumn" scope="row">May 2009</td>
<td>10%</td>
<td>5%</td>
<td>1%</td>
<td>1%</td>
<td>1%</td>
</tr>
<tr class="odd">
<td class="firstColumn" scope="row">Jun 2009</td>
<td>10%</td>
<td>5%</td>
<td>1%</td>
<td>1%</td>
<td>1%</td>
</tr>
</tbody>
</table>
<p><img src="http://farm3.static.flickr.com/2504/3707763212_2416eaf176_o.jpg" alt="Graph of IE6 as a percentage of all browsers" width="512" height="300" /></p>
<p>Based on the amount of activity and the relative rate of its decline, we&#8217;re likely to stop supporting IE6 for logged in activity like digging, burying, and commenting. Users of IE6 would still be able to view pages — just not logged in. This won&#8217;t happen tomorrow, but we&#8217;re thinking about doing it soon. If you have an opinion on this, hop into the comments.</p>
<h3>Should Digg prompt IE6 users to upgrade?</h3>
<p>A message suggesting the IE6 user upgrade seems like a logical approach. Then we wondered, &#8220;With a number of sites showing upgrade messages to IE6 users, why haven&#8217;t they already upgraded?&#8221; To find out, we ran a message to IE6 users on Digg asking, &#8220;Have 45 seconds? Help Digg by taking a quick three question survey.&#8221; The three questions were:</p>
<ul>
<li>What browser(s) do you use at work? (Please choose all that apply.) [IE, Firefox, Opera, Safari, Chrome, Other]</li>
<li>What browser(s) do you use at home? (Please choose all that apply.) [IE, Firefox, Opera, Safari, Chrome, Other]</li>
<li>You are currently using Internet Explorer 6. Why?</li>
</ul>
<p>Based on the 1571 results, people use IE6 much more often at work.</p>
<table border="1px">
<caption>Browser usage at home/work</caption>
<thead>
<tr>
<th scope="col">Location</th>
<th scope="col">IE</th>
<th scope="col">Firefox</th>
<th scope="col">Opera</th>
<th scope="col">Safari</th>
<th scope="col">Chrome</th>
<th scope="col">Other</th>
</tr>
</thead>
<tbody>
<tr>
<td scope="row">Home</td>
<td>56%</td>
<td>46%</td>
<td>5%</td>
<td>15%</td>
<td>15%</td>
<td>4%</td>
</tr>
<tr>
<td scope="row">Work</td>
<td>90%</td>
<td>19%</td>
<td>2%</td>
<td>3%</td>
<td>7%</td>
<td>3%</td>
</tr>
</tbody>
</table>
<p><img src="http://farm3.static.flickr.com/2528/3707763234_ec3254068a_o.jpg" alt="Graph of browser usage at home and work" width="512" height="270" /></p>
<p>This goes directly to why most folks use IE6: <strong>they don&#8217;t have a choice</strong>. Three out of four IE6 users on Digg said they can&#8217;t upgrade due to some technical or workplace reason.</p>
<table border="1px">
<caption>IE6 usage reasons</caption>
<tbody>
<tr>
<td scope="row">I can&#8217;t upgrade because my computer runs an old version of Windows (2000, ME, or 98).</td>
<td>7%</td>
</tr>
<tr>
<td scope="row">I can&#8217;t upgrade because I don&#8217;t have administrator access on my computer.</td>
<td>37%</td>
</tr>
<tr>
<td scope="row">I can&#8217;t upgrade because someone at work says I can&#8217;t.</td>
<td>33%</td>
</tr>
<tr>
<td scope="row">I don&#8217;t feel a need to upgrade.</td>
<td>17%</td>
</tr>
<tr>
<td scope="row">I prefer IE6 to other browsers.</td>
<td>7%</td>
</tr>
</tbody>
</table>
<p><img src="http://farm4.static.flickr.com/3483/3707763174_5bf03a2cdb_o.jpg" alt="Graph of IE6 usage reasons" width="512" height="175" /></p>
<p>Giving them a message saying, &#8220;Hey! Upgrade!&#8221; in this case is not only pointless; it&#8217;s sadistic.</p>
<p>We&#8217;re committed to developing to Web standards and building new ways to help you discover the best of the Web. Keeping an eye on what technologies folks use and why they&#8217;re being used is a big part of it.</p>
<p>Slainte,<br />
Trammell</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=878</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Digg API Features and More Developer Control</title>
		<link>http://blog.digg.com/?p=817</link>
		<comments>http://blog.digg.com/?p=817#comments</comments>
		<pubDate>Tue, 16 Jun 2009 18:56:18 +0000</pubDate>
		<dc:creator>John Quinn</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=817</guid>
		<description><![CDATA[Hi all,
Today, we&#8217;ve introduced some exciting new additions to the Digg API, so that developers can create increasingly useful and interesting applications using Digg data.
One of the most requested features has been for a search endpoint and we&#8217;re excited to make it available in this release. This feature utilizes the same search functionality introduced a [...]]]></description>
			<content:encoded><![CDATA[<p>Hi all,</p>
<p><span id="OBJ_PREFIX_DWT3110" class="Object">Today</span>, we&#8217;ve introduced some exciting new additions to the Digg API, so that developers can create increasingly useful and interesting applications using Digg data.</p>
<p>One of the most requested features has been for a search endpoint and we&#8217;re excited to make it available in this release. This feature utilizes the same search functionality <a href="http://blog.digg.com/?p=653">introduced</a> a couple months back with the overhaul of Digg search and provides a powerful solution for finding specific content on Digg. You&#8217;ll be able to use the advanced shortcuts, common search tricks, as well as search by source (domain). See the <a href="http://apidoc.digg.com/SearchStories">Search API documentation</a> for more details.</p>
<p>We&#8217;ve also added a series of <a href="http://apidoc.digg.com/ListStories">related stories endpoints</a>, so that you can find related information for any story on Digg. One variation finds stories similar diggers have dugg. Another returns stories with similar keywords. Finally, we&#8217;ve included an endpoint for <a href="http://apidoc.digg.com/ListStories">favorites</a> on Digg, which are an indication of the stories that people find exceptional in some manner.</p>
<p>These features are just the beginning of some changes that we&#8217;re currently working on and plan to introduce in the coming months. These will include endpoints for participating &#8212; such as Digging and burying &#8212; so that even richer and full featured applications can be created off the Digg platform.</p>
<p>Finally, a significant but subtle change we want to announce is a reworking of our <a href="http://apidoc.digg.com/LicenseAgreement">API license</a>. We want to give developers more control over the applications they develop by removing most of the commercial limitations. Developers should now have the confidence that they can benefit from the works they create using the Digg API, with full ownership free of fees!</p>
<p>We hope you enjoy these changes and, as always, welcome your feedback.</p>
<p>Cheers,</p>
<p>John</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=817</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DUI.Stream and MXHR</title>
		<link>http://blog.digg.com/?p=621</link>
		<comments>http://blog.digg.com/?p=621#comments</comments>
		<pubDate>Wed, 22 Apr 2009 17:44:55 +0000</pubDate>
		<dc:creator>Micah Snyder</dc:creator>
				<category><![CDATA[Digg Technology]]></category>

		<guid isPermaLink="false">http://blog.digg.com/?p=621</guid>
		<description><![CDATA[Hola,
Although we usually wait until a feature is fully baked before showing off the technology behind it, we&#8217;re just too excited about this new project to keep it to ourselves. Digg&#8217;s Front End Architecture team has been experimenting a lot with performance improvements, and we&#8217;re just about done with one that we think will change [...]]]></description>
			<content:encoded><![CDATA[<p>Hola,</p>
<p>Although we usually wait until a feature is fully baked before showing off the technology behind it, we&#8217;re just too excited about this new project to keep it to ourselves. Digg&#8217;s Front End Architecture team has been experimenting a lot with performance improvements, and we&#8217;re just about done with one that we think will change the way you get data from high-traffic websites. First though, a bit of background:</p>
<p>One of the ways that high-performance websites like Yahoo suggest speeding up load times is by <a href="http://developer.yahoo.com/performance/rules.html" target="_blank">reducing the number of HTTP requests</a> per page. We started thinking about what we could do to reduce HTTP overhead, and where we could get the biggest benefits from it. Well, one thing led to another and the next thing we knew we were talking about writing a generalized framework for bundling files, sending them through a single request, then separating them for use once they head down the pipe.</p>
<p>We call this technique MXHR (short for Multipart XMLHttpRequests), and we wrote an addition to our <a href="http://github.com/digg/dui" target="_blank">Digg User Interface library</a> called <a href="http://github.com/digg/stream" target="_blank">DUI.Stream</a> to implement it. Specifically, DUI.Stream opens and reads multipart HTTP responses piece-by-piece through an XHR, passing each chunk to a JavaScript handler as it loads.</p>
<p>Why do this? Well, DUI.Stream will allow developers to drastically improve the speed of uncached page loads by bundling most of their resources into a single HTTP request, with a single time-to-first-byte and no request throttling by the user agent. Additionally, the size of the response has no effect on the rendering time of each chunk, as the client handles each piece of the response on the fly and can inject it into the DOM for rendering immediately, in the exact order you specify. On a high traffic, high-activity site like Digg, we have to display incredible amounts of data on each permalink &#8212; typically hundreds of user images within the first 50 comment threads on a page alone, not to mention the UI chrome and actual comment data. (You can see this for yourself: notice the number of HTTP requests that queue up when you expand a page of comments). So our primary use case for DUI.Stream is turning that first long, arduous page load on an empty cache into something nearly indistinguishable from a page of data with fully cached resources.</p>
<p>Let&#8217;s talk a bit about the architectural benefits of implementing MXHRs with DUI.Stream. Back when the web was based largely on a page metaphor (i.e.: one central document with external references), whenever you loaded the page, the page requested its images, stylesheets, etc, then you were done. These days you&#8217;re just as often loading an application; the page progressively enhances into a stateful UI by loading extra stylesheets, scripts and a whole mess of UI chrome after the initial request. Yet, we&#8217;re still using the old model flow of get markup &#8211;&gt; render markup &#8211;&gt; request external resources &#8211;&gt; load and display externals.</p>
<p>Take our modal login dialog box for example. In order to reduce requests we bundle its JavaScript in with the rest of the page, we put its CSS up in the header with the rest of the styles, then we request only the markup for the dialog box, render it, and let it fire its own HTTP requests for the images that make up its chrome. In this broken model, HTTP connections and rendering behaviors split our UI architecture up into different parts of the page that all render at different times at the browser&#8217;s discretion. Even if we put everything into one cohesive structure and loaded the CSS link, script tag and markup together, they&#8217;d still all fire their own HTTP requests and the images would still come in afterwards on the first page load. This just won&#8217;t do.</p>
<p>Now, let&#8217;s rethink how our login dialog could work using DUI.Stream. We can request a Stream that contains everything needed to render and use the dialog box. As each part comes in, it gets passed through to be built, and renders immediately with no image backfill or delayed JS behavior. The DUI.Stream framework can then pass those resources back into cacheable elements for our next page load, which can happily 302 its way quickly through the rendering process. Pretty sweet right? Right.</p>
<p>Before we get into actual code, I have to stress that the DUI.Stream client, with all its aforementioned badassitude, is an alpha release &#8212; it&#8217;s better than a proof of concept, but it&#8217;s definitely not ready for prime time. Think of it like Miles and Hurley&#8217;s time travel discussion on Lost:  There are still a few plot holes, but what we&#8217;ve seen so far is pretty cool. With that in mind, let&#8217;s save the talk about future features for a bit later and get into what DUI.Stream does right now.</p>
<p>Here&#8217;s a TLDR example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> DUI.<span style="color: #660066;">Stream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
s.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'text/html'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>payload<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#stream'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">append</span><span style="color: #009900;">&#40;</span>payload<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
s.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'complete'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;D. Plainview: I'm finished!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
s.<span style="color: #660066;">load</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'testStreamData.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>DUI.Stream works on a pretty simple mechanism: create a DUI.Stream, register listeners for each mimetype you plan to send (as well as an optional onComplete), then send a request to a URL that implements an MXHR responder. I&#8217;ll leave the details of DUI.Stream&#8217;s inner-workings to those of you who want to look through the source. As always, our code is released under a open-source license so if you find any fugly parts, feel free to let us know or send us a patch.</p>
<p>You can see the <a href="http://demos.digg.com/stream/streamDemo.html" target="_blank">demo code in action</a>, and I&#8217;ve included some rough timing numbers to demonstrate just how much faster DUI.Stream is than a regular uncached page load. YMMV with the demo, so don&#8217;t be surprised if it falls over in your browser or occasionally reports wacky numbers. Check out the roadmap below for cross-browser info. Also, we have a <a href="http://demos.digg.com/stream/imageDemo.html" target="_blank">demo that handles images</a> that performs atrociously well in Firefox and Safari, but at present IE doesn&#8217;t play nice with it (shocking, I know). You can test drive it at your own risk.</p>
<p>If you&#8217;re curious about responders, we&#8217;ve thrown together a few demos in Python, Ruby, Perl and Java in the <a href="http://github.com/digg/stream/tree/9010257b1a6e1c236374d5205f0cee108a32256a/examples" target="_blank">DUI.Stream GitHub repository</a>. We&#8217;ll be releasing a full set of documentation once we hammer out the rest of the DUI.Stream client. Rest assured you won&#8217;t have to implement anything based on a blog post and some demos.</p>
<p>Here are the things still on our short-term roadmap:</p>
<ul>
<li>Cache detection. If you wanted to implement DUI.Stream right now, you&#8217;d have to switch between regular requests and MXHRs on your own. We don&#8217;t recommend that.</li>
<li>Background caching. A big part of implementing this is going to be loading the MXHR through DUI.Stream, then turning any cacheable chunks into their normal, cache-friendly tags.</li>
<li>Support for multiple headers per chunk. Specifically, we&#8217;ll be adding a set of custom headers to allow for UI-specific information to be sent, like CSS selectors for greater control in handlers.</li>
<li>XMLHttpRequest.multipart support. Right now we&#8217;re not using this flag, since we aren&#8217;t keeping connections open for a server-push implementation yet. Like I said, It&#8217;s an alpha ;)</li>
<li>IE7 and IE8 object tag workarounds. In the current build, bouncing binary streams into object tags in IE has some interesting results.</li>
</ul>
<p>Anyways, I hope you like what you&#8217;ve seen so far. Several of my teammates have been busting their asses to get this ready to show off &#8212; specifically Jordan Alperin, Arsenio Santos, Chris Goffinet, and Arin Sarkissian &#8212; and we&#8217;re all pretty excited about it. As always, if you have any questions, comments or thoughts, let us know!</p>
<p>Cheers,<br />
- Micah</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.digg.com/?feed=rss2&amp;p=621</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
