<?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>Thought Palace</title>
	<atom:link href="http://jens.mooseyard.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jens.mooseyard.com</link>
	<description>Little boxes made of words, by Jens Alfke</description>
	<lastBuildDate>Tue, 09 Feb 2010 17:58:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Re: Idea for alternative RSS syncing system</title>
		<link>http://jens.mooseyard.com/2010/02/re-idea-for-alternative-rss-syncing-system/</link>
		<comments>http://jens.mooseyard.com/2010/02/re-idea-for-alternative-rss-syncing-system/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 17:57:10 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Peer-to-Peer]]></category>
		<category><![CDATA[Social Software]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=392</guid>
		<description><![CDATA[Brent "NetNewsWire" Simmons raises the idea of "an open protocol (and open source server) for syncing RSS/Atom subscriptions":http://inessential.com/2010/02/08/idea_for_alternative_rss_syncing_system, that is, a way of keeping multiple local newsreader apps (like on a Mac and an iPhone) in sync with each other, so that they share the same set of subscribed feeds, and remember which articles have already been read. You can think of it as "IMAP for RSS".

NetNewsWire already does this using Google Reader, and Apple's PubSub framework (which is what Safari and Mail use) shares the read/unread state using MobileMe. But it would be nice to have an open protocol.

I have some experience with this, having implemented the sync system used by PubSub. It's an interesting problem -- you might think I would have just used Apple's SyncServices, and it's true that it would have worked great for the subscription list, but it doesn't scale well to huge numbers of rapidly-changing "read/unread" flags.

I have two suggestions (which I would have made on Brent's blog, except he doesn't allow comments anymore.)]]></description>
			<content:encoded><![CDATA[	<p>Brent &#8220;NetNewsWire&#8221; Simmons raises the idea of <a href="http://inessential.com/2010/02/08/idea_for_alternative_rss_syncing_system" title="">an open protocol for syncing <span class="caps">RSS</span>/Atom subscriptions</a>, that is, a way of keeping multiple local newsreader apps (like on a Mac and an iPhone) in sync with each other, so that they share the same set of subscribed feeds, and remember which articles have already been read. You can think of it as &#8220;IMAP for <span class="caps">RSS</span>&#8221;.</p>

	<p>NetNewsWire already does this using Google Reader as an intermediary, and Apple&#8217;s PubSub framework (which is what Safari and Mail use) shares the read/unread state using MobileMe. But it would be nice to have an open protocol.</p>

	<p>I have some experience with this, having implemented the sync system used by PubSub. It&#8217;s an interesting problem&#8212;you might think I would have just used Apple&#8217;s SyncServices, and it&#8217;s true that it would have worked great for the subscription list, but it doesn&#8217;t scale well to huge numbers of rapidly-changing &#8220;read/unread&#8221; flags.</p>

	<p>I have two suggestions (which I would have made on Brent&#8217;s blog, except he doesn&#8217;t allow comments anymore.)</p>

	<h2>CouchDB</h2>

	<p><a href="http://couchdb.apache.org" title="">CouchDB</a> is an awesome web-centric database engine. It doesn&#8217;t use <span class="caps">SQL</span>; instead, it&#8217;s a glorified key-value store whose values are arbitrary <span class="caps">JSON</span> objects, and which uses map-reduce for efficient querying. The basic <span class="caps">API</span> is pure <span class="caps">REST</span>, though glue libraries for many languages exist.</p>

	<p>CouchDB natively supports syncing data through distributed groups of servers. It&#8217;s sort of like the way distributed version-control systems like Git or Mercurial work: multiple CouchDB instances each store a replica of the same data set, but can &#8220;pull&#8221; changes from each other over <span class="caps">HTTP</span> to stay in sync.</p>

	<p>CouchDB is pretty lightweight and is already being used on the desktop by client apps: <span class="caps">GNOME</span> has been <a href="https://launchpad.net/desktopcouch" title="">integrating it into the Linux desktop</a> to use as a shared store for user data like contacts and bookmarks. It plays a similar role to SyncServices on Mac OS, but it&#8217;s all open source and any two instances can sync with each other instead of requiring a proprietary server. I hear this is already shipping in the latest Ubuntu releases.</p>

	<p>It doesn&#8217;t look as though anyone&#8217;s designed a schema for storing <span class="caps">RSS</span> subscriptions this way, but it would be pretty easy to define one. You then need a local agent running CouchDB (it can be stripped down to be pretty small), a client library for Cocoa apps, and an upstream CouchDB server to sync to.</p>

	<h2><span class="caps">REST</span>-Logging</h2>

	<p>This protocol is similar to what I came up with for PubSub. It&#8217;s a simple extension of <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" title=""><span class="caps">REST</span></a>, but I haven&#8217;t heard of it being used elsewhere. The idea is that you model an append-only log file as an <span class="caps">HTTP</span> resource. The items that are logged are &#8216;events&#8217; describing changes in the data model, in this case the subscriptions and articles.</p>

	<p>The sync algorithm looks like this:</p>

	<ol>
		<li>Download all the data that&#8217;s been added to the remote log file since your last sync. Remember the file&#8217;s ETag.</li>
			<li>Parse that data into a sequence of log entries, and process them in order. Each entry names a model object (feed or article) and an action (subscribe, unsubscribe, mark read, mark unread). Apply those changes to the local data store.</li>
			<li>Query your local data store to find all the changes that have been made since your last sync. <em>Ignore</em> the remote changes you just applied in the previous step, and also any earlier local changes that duplicate a remote change (like marking the same article as read.)</li>
			<li>Generate a series of log entries for those changes and concatenate them into a data blob.</li>
			<li>Upload that blob, appending it to the remote log file. Remember the resulting ETag. In case of a conflict (someone else has changed the remote file since step 1), toss out the blob and return to step 1.</li>
	</ol>

	<p>You can think of the log file as a queue or message stream that&#8217;s being collaboratively read and written by all of the clients. This sounds like something you&#8217;d need a fancy web-app to manage, but it turns out that all it takes is a typical <span class="caps">HTTP 1</span>.1 server and a trivial server-side script.</p>

	<p>The download is a conditional <span class="caps">GET</span>, as used for fetching feeds themselves. The difference is that you use a &#8220;Range:&#8221; header to request <em>only the bytes past the last known <span class="caps">EOF</span></em>. For example, if the last time you read the log it was 123456 bytes long, you add the header &#8220;Range: 123456-&#8221; to the request. This ensures that you only get back the new bytes that were added to the end. (And since this is a conditional <span class="caps">GET</span>, if the file hasn&#8217;t changed at all you just get back an empty 304 response.)</p>

	<p>That&#8217;s all you need to do to track changes. Since the file is append-only, the only bytes you need to read are the ones added to the end. This request efficiently sends you just those bytes.</p>

	<p>What&#8217;s cool is that this require <em>no server-side software</em>. If the log is a static file, any regular <span class="caps">HTTP</span> server like Apache will automatically handle <span class="caps">GET</span> requests for it, even byte-range ones. (Ranges are already used by browsers to resume interrupted downloads.) And it sends the response at high speed, since the server&#8217;s just streaming from a file, without multiple back-and-forth requests and without expensive database queries.</p>

	<p>How about writing? Ideally you&#8217;d use the same approach, with a byte-range <span class="caps">PUT</span> that specifies that the request body should go at the end of the file. Unfortunately most servers don&#8217;t support this for static files, even though it&#8217;s basically just <span class="caps">HTTP 1</span>.1. But it&#8217;s really easy to implement. Any <span class="caps">PHP</span> crufter should be able to whip up a one-page script that simply responds to a <span class="caps">POST</span> by reading the request body and appending it to a local file (while doing the necessary ETag and range verification.) The great thing is that this script doesn&#8217;t have to know anything at all about <span class="caps">RSS</span> or subscriptions or unread counts; it&#8217;s completely generic. You can upgrade the data model without having to touch the script, and you could use the same script to sync anything, not just <span class="caps">RSS</span>.</p>

	<p>(Yes, there is a semi-obvious drawback to this protocol: the file grows without limit. Surprisingly, this is not a problem most of the time, since clients only upload or download new data; the only real limit is the maximum file size or disk quota allowed by the server. But it does present a problem for a new client, whose first-time sync would download the entire file. This can be worked around by having new clients ignore very old data (only download the latest 10MB, say) or by periodically writing a compact subscription list to a separate <span class="caps">URL</span>.)</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2010/02/re-idea-for-alternative-rss-syncing-system/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>The Music I Liked Of 2009</title>
		<link>http://jens.mooseyard.com/2009/12/the-music-i-liked-of-2009/</link>
		<comments>http://jens.mooseyard.com/2009/12/the-music-i-liked-of-2009/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 18:31:35 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Me]]></category>
		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=388</guid>
		<description><![CDATA[Every year the Albums Of The Year lists seem more and more removed from my experience. (Most of the time I haven't heard a single album on the list.) Worse, we're now getting into the Of The Decade lists, making me realize how long this has been going on*. If you ask me the top albums of the '80s or '90s, I don't have too much trouble rattling off a bunch of names. But this decade? I get confused and have to start thinking hard and looking through the back covers of my mix CDs. Why is that? <i>[Ed.: it's because you're getting old. Duh.]</i>

Let me start with this year, 2009. What was good? Hm; my prosthetic brain units at iTunes and last.fm tell me that it's...]]></description>
			<content:encoded><![CDATA[	<p>Every year the Albums Of The Year lists seem more and more removed from my experience. (Most of the time I haven&#8217;t heard a single album on the list.) Worse, we&#8217;re now getting into the Of The Decade lists, making me realize how long this has been going on*. If you ask me the top albums of the &#8216;80s or &#8216;90s, I don&#8217;t have too much trouble rattling off a bunch of names. But this decade? I get confused and have to start thinking hard and looking through the back covers of my mix CDs. Why is that? <i>[Ed.: it&#8217;s because you&#8217;re getting old. Duh.]</i></p>

	<p>Let me start with this year, 2009. What was good? Hm; my prosthetic brain units at iTunes and last.fm tell me that it&#8217;s:</p>

	<p>&bull; <strong>Dysrhythmia</strong>, &quot;<a href="http://www.myspace.com/dysrhythmiaband">Psychic Maps</a>&quot; [jaw-dropping instrumental math-metal, will have you banging your head in 7/13 time.]</p>

	<p>&bull; <strong>Isis</strong>, &quot;<a href="http://pitchfork.com/reviews/albums/13009-wavering-radiant/">Wavering Radiant</a>&quot; [post-metal? huge lowercase-&#8217;p&#8217; progressive epics. so good I&#8217;m willing to overlook the cookie-monster vocals.]</p>

	<p>&bull; <strong>Pelican</strong>, &quot;<a href="http://www.emusic.com/album/Pelican-Ephemeral-MP3-Download/11487598.html">Ephemeral</a>&quot; <span class="caps">EP </span>[is it post-rock with big riffs? or restrained brainy instrumental metal?]</p>

	<p>&bull; <strong>Apricot Rail</strong>, &quot;<a href="http://music.hiddenshoal.com/artists/apricot-rail/">Apricot Rail</a>&quot; [ok, this is instrumental-post-rock for sure, but atypically cheerful, kind of like Do Make Say Think. they&#8217;ve even got oboes omg!]</p>

	<p>&bull; <strong>The Happy Hollows</strong>, &quot;<a href="http://www.myspace.com/thehappyhollows">Spells</a>&quot; [this is the token recognizably-indie-rock album on the list. are they secretly Deerhoof covering the Pixies? Or Lush covering Interpol? also, they are <a href="http://www.rockscope.com/article/259/Happy-Hollows---Spaceland">hella cute</a> and I can&#8217;t wait to see them live]</p>

	<p>&bull; <strong>Dirty Projectors</strong>, &quot;<a href="http://westernvinyl.com/artists/dirty_projectors.html">Bitte Orca</a>&quot; [I still can&#8217;t figure this out, with its Afrobeat guitar lines, intricate interlocking vocals, weird rhythms and weirder lyrics. ok, that description makes it sound like &quot;Remain In Light&quot;, which it isn&#8217;t at all like, but maybe is somehow.]</p>

	<p>&bull; <strong>Elisa Luu</strong>, &quot;<a href="http://agora.hiddenshoal.com/index.php?main_page=product_info&#038;cPath=42&#038;products_id=117">Chromatic Sigh</a>&quot; [can I say &quot;eclectic&quot; with a straight face? really interesting electronic music, clearly song-like, ranging between poles of rock and ambient.]</p>

	<p>&bull; <strong>Anduin + Jasper TX</strong>, &quot;<a href="http://www.boomkat.com/item.cfm?id=177591">The Bending Of Light</a>&quot; [guitar-based drone. majestic.]</p>

	<p>&bull; <strong>Brock van Wey</strong>, &quot;<a href="http://www.popmatters.com/pm/review/116078-brock-van-wey-white-clouds-drift-on-and-on/">White Clouds Drift On And On</a>&quot; [exactly what it sounds like. it comes with or without beats, your choice.]</p>

	<p>&bull; <strong>Eluder</strong>, &quot;<a href="http://www.archaichorizon.com/releases/ah030/ah030.html">Drift</a>&quot; [exactly what it sounds like, too. careful with this one, some people have had trouble returning to earth afterwards.]</p>

	<p>&bull; <strong>J&oacute;nsi &#038; Alex</strong>, &quot;<a href="http://jonsiandalex.com/">Riceboy Sleeps</a>&quot; [Sigur R&oacute;s guitarist and his boyfriend do Stars Of The Lid. delicious in small doses.]</p>

	<p>&bull; <strong>Victoire</strong>, &quot;<a href="http://www.emusic.com/features/spotlight/2009_200903-qa-selects-victoire.html">A Door Into The Dark</a>&quot; <span class="caps">EP </span>[a string ensemble that embraces electronics as a natural part of their sound]</p>

	<p>&bull; <strong>Sub</strong>, &quot;<a href="http://www.plainaudio.com/dnb/releases/pp030md.html">Id</a>&quot; <span class="caps">EP </span>[nothing new, but basically the best Photek tracks I&#8217;ve heard in ten years.]</p>

	<p>PS: there might be some last minute additions to this list if Kate Simko&#8217;s &quot;Sounds Of The Atom Smashers&quot; and Concern&#8217;s &quot;Truth And Distance&quot; live up to their potential.<br />
<span class="caps">PPS</span>: ZOMG I forgot Sunn O)))&#8217;s stark and forbidding &quot;Monoliths And Dimensions&quot;, whose final track &quot;Alice&quot; is deserving of a space up there.<br />
<span class="caps">PPPS</span>: Yes, a mix of this stuff is forthcoming&#8230;</p>

	<p><span style="font-size: smaller; ">* It&#8217;s not like I&#8217;ve been having trouble finding great new music, or that I resent other people for all picking different music than me; but it&#8217;s a little sad to not be part of the zeitgeist. Long ago it was really important to me whether punk and new wave would break dinosaur rock&#8217;s lock on the mainstream, or whether little-known underground bands like the Cure or the Pixies would get the recognition they deserved. I think the peak of my with-it-ness was circa 1990-91 when I could rattle off the name of every shoegazer band that mattered and I treated every issue of Melody Maker as a shopping list to take with me to the import bin at Tower to find the next Cranes or Chapterhouse.</span></p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/12/the-music-i-liked-of-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ottoman Status</title>
		<link>http://jens.mooseyard.com/2009/12/ottoman-status/</link>
		<comments>http://jens.mooseyard.com/2009/12/ottoman-status/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 17:12:16 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Me]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=386</guid>
		<description><![CDATA[Yes, I'm still working on Ottoman (my append-only multiversion-concurrent storage library). As the code grows in size and complexity, so it grows in its resistance to being changed. But I just pushed "my latest changes":http://bitbucket.org/snej/ottoman/changesets/ up to bitbucket.org. What's new? ...]]></description>
			<content:encoded><![CDATA[	<p>Yes, I&#8217;m still working on Ottoman (my append-only multiversion-concurrent storage library). As the code grows in size and complexity, so it grows in its resistance to being changed, but as Piet Hein said and I never tire of quoting:</p>

	<blockquote><em>Problems worthy of attack</em><br />
<em>Prove their worth by fighting back.</em></blockquote>

	<p>I just pushed <a href="http://bitbucket.org/snej/ottoman/changesets/" title="">my latest changes</a> up to bitbucket.org. What&#8217;s new?</p>

	<p><strong>Variable-sized top-level index.</strong> Previously, the hash data structure used a top level array of 256 hashtables. I&#8217;ve now made that &#8216;256&#8217; a variable that scales with the number of records. This saves a lot of room for smaller datasets. (Sounds easy, right? I thought so too. But it ended up triggering significant changes to the file format and algorithms and took a lot of debugging.)</p>

	<p><strong>The return of the trees! part un.</strong> I started this as a project to learn about B+trees, but when I got to the point of implementing the append-only multiversion stuff I did it with hashtables first because it&#8217;s more straightforward that way, and the tree code went into the freezer. Well, it&#8217;s back now. There is a &#8220;new&#8221; <a href="http://bitbucket.org/snej/ottoman/src/tip/src/Tree.h" title="">Tree</a> class that can be used to read and write persistent B+trees. It&#8217;s not yet integrated into the top-level Ottoman class, though, so you can only use it on its own, not intermixed with hash-tables, and without the <span class="caps">API</span> for tracking versions.</p>

	<p>The next task is of course to integrate the tree <span class="caps">API</span> into the Ottoman class. But more than that, it will be entwined with the hashtable such that trees will serve as searchable indexes into the data store. So the hashtable will provide extremely fast but unordered access via a unique &#8220;record ID&#8221;, but you can build as many indexes as you like that will use ordered secondary keys (of your choice) to look up hash values.</p>

	<p>At that point, I believe Ottoman will be ready to serve as a substrate for <span class="caps">HTML</span> local data storage, for <a href="http://jchrisa.net/drl/_design/sofa/_show/post/HTML5-Storage-Continues" title="">implementing a CouchDB-compatible database</a> (a la <a href="http://github.com/jchris/WebWorkerStorage/blob/master/JSONDB.md" title=""><span class="caps">JSONDB</span></a>), or for other fun databasey purposes.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/12/ottoman-status/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZSync</title>
		<link>http://jens.mooseyard.com/2009/11/zsync/</link>
		<comments>http://jens.mooseyard.com/2009/11/zsync/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 01:51:03 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Me]]></category>
		<category><![CDATA[Peer-to-Peer]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=384</guid>
		<description><![CDATA["ZSync":http://www.zarrastudios.com/ZSync/ZSync.html is a new Mac/iPhone library that uses my "BLIP":http://bitbucket.org/snej/mynetwork/wiki/BLIP/Overview P2P networking protocol.]]></description>
			<content:encoded><![CDATA[	<p><a href="http://www.zarrastudios.com/ZSync/ZSync.html" title="">ZSync</a> is a new Mac/iPhone library that uses my <a href="http://bitbucket.org/snej/mynetwork/wiki/BLIP/Overview" title=""><span class="caps">BLIP</span></a> P2P networking protocol:</p>

	<blockquote>&#8220;ZSync is an open source syncing library designed to allow easy syncing of data between an iPhone/iPod Touch and the <span class="caps">OS X </span>Desktop.<br />
ZSync utilizes the <span class="caps">BLIP</span> library and Apple&#8217;s Sync Services to allow easy and seamless syncing of data.&#8221;</blockquote>

	<p>It&#8217;s still in early development though, with a first public release expected in January:</p>

	<blockquote>Right now the code is in a private GitHub repository while the initial framework and protocols are fleshed out.  This is expected to go public in January of 2010.  Until then we are keeping the development team very small so that we can flesh out the design without a lot of overhead.</blockquote>

	<p>This looks like it&#8217;ll be super useful for iPhone apps that want to integrate with their Mac siblings, especially since their design won&#8217;t require you to have the Mac app running while you sync.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/11/zsync/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dogfooding Chrome</title>
		<link>http://jens.mooseyard.com/2009/11/dogfooding-chrome/</link>
		<comments>http://jens.mooseyard.com/2009/11/dogfooding-chrome/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 17:21:40 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=382</guid>
		<description><![CDATA[As everyone knows who works in the pet-food industry (or computer software for that matter), it can be hard to start eating your own dogfood. Case in point: I just this week set Chrome to be my default browser, though I've been working on it for four months now.

Partly that's because when I started in July the Mac version of Chrome was too immature; and partly it's because a web browser is something you need to have running and working all the time -- especially since the Chrome project's bug tracker and code-review tool are web-based.

But Mac Chrome is quite stable enough to use now, and as I haven't been doing much Chrome development on this MacBook Pro lately (it takes too long to compile compared to my souped-up Mac Pro) I've installed the latest dev-channel build and replaced Safari with it.]]></description>
			<content:encoded><![CDATA[	<p>As everyone knows who works in the pet-food industry (or computer software for that matter), it can be hard to start eating your own dogfood. Case in point: I just this week set Chrome to be my default browser, though I&#8217;ve been working on it for four months now.</p>

	<p>Partly that&#8217;s because when I started in July the Mac version of Chrome was too immature; and partly it&#8217;s because a web browser is something you need to have running and working all the time&#8212;especially since the Chrome project&#8217;s bug tracker and code-review tool are web-based.</p>

	<p>But Mac Chrome is quite stable enough to use now, and as I haven&#8217;t been doing much Chrome development on this MacBook Pro lately (it takes too long to compile compared to my souped-up Mac Pro) I&#8217;ve installed the latest <a href="http://dev.chromium.org/getting-involved/dev-channel" title="">dev-channel build</a> and replaced Safari with it in my Dock and as my default browser.</p>

	<p>It&#8217;s hard to get used to a new browser, after all these years. I remember that I dropped <span class="caps">IE 5</span> like a hot rock as soon as Safari became useable, but that&#8217;s because IE sucked so badly on <span class="caps">OS X </span>(as you youngsters may not remember.) But Safari is a great browser. Chrome&#8217;s great too, but in different ways, and the Mac version&#8217;s not finished yet so there are some missing bits.</p>

	<p>I should note that I generally don&#8217;t work on the user-visible parts of Chrome, rather the underlying WebKit engine; so I haven&#8217;t been focusing on the UI much, or noticing the features being added, until experiencing them as an end-user.</p>

	<p>In Chrome&#8217;s favor:</p>

	<ul>
		<li>It definitely feels faster. At work I&#8217;ve been obsessing over some micro-benchmarks, but in regular use what I notice is simply that pages come up more quickly. I think a lot of this has to do with <span class="caps">DNS</span> pre-fetching, because <span class="caps">DNS</span> query times here at home can often be slow.</li>
		<li>The UI of the tabs is better than Safari&#8217;s. I like that they take up less room (though without eliminating the title bar the way the Safari 4 beta did), and the transition animations when opening/closing/detaching tabs are extremely slick, definitely Apple-quality.</li>
		<li>The downloads shelf at the bottom of the window is more visible than Safari&#8217;s little Downloads window, which always gets hidden behind the browser.</li>
		<li>The list of recently-closed tabs at the bottom of the new-tab page is very thoughtful and handy. In general I find the new-tab page more useful than Safari&#8217;s, if less flashy.</li>
	</ul>

	<p>Rough edges (remember, this is a pre-beta build):</p>

	<ul>
		<li><span class="caps">PDF</span> display doesn&#8217;t work well. There&#8217;s no way to switch pages yet (making multi-page documents unusable), there&#8217;s no zooming, the Save command doesn&#8217;t work, and often the renderer process starts redrawing constantly and eating up <span class="caps">CPU</span> time.</li>
		<li>The only indication you have that a page is loading is the little 16&#215;16-pixel spinning circle that replaces the tab&#8217;s icon. I like the visual design of this, but it&#8217;s too hard to find. I still miss the big progress bar in the address bar from Safari 1-3. (Cursor feedback would be nice&#8212;wasn&#8217;t there a browser once that put a little wristwatch badge on the arrow cursor?)</li>
		<li>The bookmarking UI is still unfinished and unpolished. In particular, there&#8217;s no way to edit/move/delete bookmarks yet. I love the idea of being able to quickly bookmark by clicking a Google-y star icon, but in practice it pops up a floating panel for choosing a folder, which makes me think about where to put it just like Safari&#8217;s bookmark sheet does. I&#8217;d rather the star button just added it to an &#8220;Unsorted&#8221; folder that I could open and organize later.</li>
		<li>Autofill doesn&#8217;t seem to work as well as in Safari. For example, it won&#8217;t autofill login forms until I type in the username; I think this may be a security feature, but I find it annoying.</li>
	</ul>

	<p>I&#8217;ve been impressed by Chrome&#8217;s stability too, for a pre-beta development build. The app hasn&#8217;t crashed once, and I haven&#8217;t even gotten the &#8220;Oh, snap!&#8221; page that shows that a renderer process crashed. (I&#8217;ve seen plugins crash a few times, but that&#8217;s probably Flash&#8217;s fault, and as in Safari on 10.6, this doesn&#8217;t affect the browser or even the rest of the page.)</p>

	<p>One thing I&#8217;m really looking forward to is <a href="http://blog.chromium.org/2009/09/extensions-status-on-runway-getting.html" title="">extensions</a>. Safari&#8217;s a closed system, and I&#8217;ve long been envious of the plethora of cool plug-ins available for Firefox. I&#8217;m looking forward to using, and maybe <a href="http://code.google.com/chrome/extensions/index.html" title="">developing</a>, extensions for Chrome. (In the current dev channel Mac release, extensions can be installed, but the ones I&#8217;ve tried don&#8217;t do anything yet.)</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/11/dogfooding-chrome/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Ottoman Update: Direct-Write Mode</title>
		<link>http://jens.mooseyard.com/2009/10/ottoman-update-direct-write-mode/</link>
		<comments>http://jens.mooseyard.com/2009/10/ottoman-update-direct-write-mode/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 16:36:05 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[ottoman]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=367</guid>
		<description><![CDATA[	I&#8217;ve pushed a new update of my Ottoman storage library.

	What&#8217;s new is the option to have individual additions to the dictionary written directly to disk, instead of being buffered in memory until you save a new version. This helps performance if you&#8217;re writing a ton of data all at once. And there&#8217;s a simple demo called PackDir that writes a ton of data all at once: it packs the contents of an entire directory tree into an Ottoman file, with keys being filenames and values being file contents.

	To implement this I had to violate the lockless semantics a bit, because having multiple clients appending key/value pairs to the file at the same time would make it a lot harder to keep their revisions straight. So before being able to do any direct puts, you have to enter an [ugh] ExclusiveTransaction.

	(Of course, the issues with locking don&#8217;t matter if the file is only being used by one process. Or even if there are multiple readers but only one writer, since the locks don&#8217;t interrupt readers.)
 ]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ve pushed <a href="http://bitbucket.org/snej/ottoman/changesets/" title="">a new update</a> of my Ottoman storage library.</p>

	<p>What&#8217;s new is the option to have individual additions to the dictionary written directly to disk, instead of being buffered in memory until you save a new version. This helps performance if you&#8217;re writing a ton of data all at once. And there&#8217;s a simple demo called <a href="http://bitbucket.org/snej/ottoman/src/tip/test/PackDir.cpp" title="">PackDir</a> that writes a ton of data all at once: it packs the contents of an entire directory tree into an Ottoman file, with keys being filenames and values being file contents.</p>

	<p>To implement this I had to violate the lockless semantics a bit, because having multiple clients appending key/value pairs to the file at the same time would make it a lot harder to keep their revisions straight. So before being able to do any direct puts, you have to enter an [ugh] ExclusiveTransaction.</p>

	<p>(Of course, the issues with locking don&#8217;t matter if the file is only being used by one process. Or even if there are multiple readers but only one writer, since the locks don&#8217;t interrupt readers.)</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/10/ottoman-update-direct-write-mode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Dungeon Master</title>
		<link>http://jens.mooseyard.com/2009/10/the-dungeon-master/</link>
		<comments>http://jens.mooseyard.com/2009/10/the-dungeon-master/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 15:18:29 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Fiction]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Humor]]></category>
		<category><![CDATA[parody]]></category>
		<category><![CDATA[poetry]]></category>
		<category><![CDATA[RPG]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=361</guid>
		<description><![CDATA[	Call the roller of big dice,
The long-haired one, and bid him whip
On kitchen tables consecutive 18&#8217;s.
Let the fighters dawdle in such armor
As they are used to wear, and let the mages swap
Delicious spells from last month&#8217;s Dragon.
Let a fumble be finale of its caster:
The only emperor is the dungeon master.

	Take from the manual of monsters
Painted with three crude beasts, that sheet
On which I enumerated his stats once,
And spread it so as to cover his face.
If his bag remains, rifle his hoard
To see who gets his precious +6 sword.
Light the lamp to run away faster.
The only emperor is the dungeon master.

	{ after Wallace Stevens }
 ]]></description>
			<content:encoded><![CDATA[	<p>Call the roller of big dice,<br />
The long-haired one, and bid him whip<br />
On kitchen tables consecutive 18&#8217;s.<br />
Let the fighters dawdle in such armor<br />
As they are used to wear, and let the mages swap<br />
Delicious spells from last month&#8217;s Dragon.<br />
Let a fumble be finale of its caster:<br />
The only emperor is the dungeon master.</p>

	<p>Take from the manual of monsters<br />
Painted with three crude beasts, that sheet<br />
On which I enumerated his stats once,<br />
And spread it so as to cover his face.<br />
If his bag remains, rifle his hoard<br />
To see who gets his precious +6 sword.<br />
Light the lamp to run away faster.<br />
The only emperor is the dungeon master.</p>

	<p>{ <a href="http://www.everypoet.com/archive/poetry/Wallace_Stevens/wallace_stevens_the_emperor_of_ice_cream.htm" title="">after Wallace Stevens</a> }</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/10/the-dungeon-master/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Lost Lesson Of Instant Typing</title>
		<link>http://jens.mooseyard.com/2009/10/the-lost-lesson-of-instant-typing/</link>
		<comments>http://jens.mooseyard.com/2009/10/the-lost-lesson-of-instant-typing/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 22:00:10 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Ideas]]></category>
		<category><![CDATA[Me]]></category>
		<category><![CDATA[Social Software]]></category>
		<category><![CDATA[iChat]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=351</guid>
		<description><![CDATA[	Farhad Manjoo writing in Slate about Google Wave:

	The trouble is, everything you type into Wave is transmitted live, in real time&#8212;every keystroke was getting sent to Zach just as I hit it. This made me too self-conscious to get my thoughts across.

	&#8230; Maybe I should just delete what I&#8217;d written and say, &#8220;Twitter works because it&#8217;s simple.&#8221; But I couldn&#8217;t do that, because Zach was watching me. He could see me struggling right now&#8212;he could see that I&#8217;d gotten myself stuck in a textual cul-de-sac and that I was desperately searching for a way out without looking foolish. Now I saw Zach beginning to type: &#8220;Don&#8217;t let the live-typing get you down!&#8221; The game was up; what was the point of making a point now? I ended my thought clumsily and then resolved never to attempt to say anything very deep on Wave.

	The same thing happened seven years ago with the live-typing feature that I implemented in iChat 1.0 (which was only supported for Bonjour chats.) I thought it was an awesome idea, and I&#8217;d wanted to have it in a chat program since about 1997. But it turned out that, in actual use, people hated it, for exactly the [...]]]></description>
			<content:encoded><![CDATA[	<p>Farhad Manjoo <a href="http://www.slate.com/id/2232311/pagenum/all" title="">writing in Slate</a> about Google Wave:</p>

	<blockquote>The trouble is, everything you type into Wave is transmitted live, in real time&#8212;every keystroke was getting sent to Zach just as I hit it. This made me too self-conscious to get my thoughts across.</blockquote>

	<blockquote>&#8230; Maybe I should just delete what I&#8217;d written and say, &#8220;Twitter works because it&#8217;s simple.&#8221; But I couldn&#8217;t do that, because Zach was watching me. He could see me struggling right now&#8212;he could see that I&#8217;d gotten myself stuck in a textual cul-de-sac and that I was desperately searching for a way out without looking foolish. Now I saw Zach beginning to type: &#8220;Don&#8217;t let the live-typing get you down!&#8221; The game was up; what was the point of making a point now? I ended my thought clumsily and then resolved never to attempt to say anything very deep on Wave.</blockquote>

	<p>The same thing happened seven years ago with the live-typing feature that I implemented in iChat 1.0 (which was only supported for Bonjour chats.) I thought it was an awesome idea, and I&#8217;d wanted to have it in a chat program since about 1997. But it turned out that, in actual use, people hated it, for exactly the reasons Manjoo describes: it makes you self-conscious. We took it out in the next release.</p>

	<p>(Interestingly, I hate video chat for a very similar reason. Somehow, the fact that my picture is being shown in real time to the remote person makes me horrifically self-conscious, even though it wouldn&#8217;t bother me at all to talk face-to-face with that person. I don&#8217;t know whether it&#8217;s the little preview on my screen, or the fact that the person is spookily both present and not-present, but the few times I&#8217;ve tried video-chat have been really unpleasant.)</p>

	<p>I&#8217;m usually on the side of more technology. I believe that our online communications tools are still horribly primitive and have only scratched the surface of what&#8217;s possible. But this was a case where more technology was bad.</p>

<pre>The low-tech alternative that lots of people use in IM,
is to write in short fragments,
each a separate message,
so the other person can see them one by one
without waiting for you to finish the whole sentence.</pre>

	<p>The difference is that you&#8217;re in control over when to send a partial message, and the other person knows you&#8217;re in control, and so on. I still think it might be possible to do this in a higher-tech way, like using a hot-key to send a partial message on demand without having the funky line-breaks, but the current approach isn&#8217;t so bad as long as you&#8217;re not embarrassed about unintentional free verse.</p>

	<p>I could have told the Wave people about what I&#8217;d learned, except I didn&#8217;t know Wave existed until April (shortly before the public announcement), and even then I was just some guy lost in the crowd at the demos&#8230;.</p>

	<p>Part of the problem, in both cases, is that live typing is one of those Cool Demo Features that looks really awesome when showing off the app. Features like that can be dangerous because they are legitimately very useful during the app&#8217;s gestation, when exciting demos are a key survival trait; but then they can&#8217;t be removed later on because they&#8217;re so well-known, even if they turn out to be useless. Sometimes these features aren&#8217;t actually harmful to the user experience, they just make the code more complex and harder to maintain. Instant typing is both, unfortunately. (The clever sync algorithms and rapid-fire network messages Wave uses would be needed even without live typing, but the fact that they have to run on every few keystrokes, not just every minute or so, pushes those things so much harder.)</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/10/the-lost-lesson-of-instant-typing/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Ottoman For Cocoa (and bug-fixes)</title>
		<link>http://jens.mooseyard.com/2009/09/ottoman-for-cocoa-and-bug-fixes/</link>
		<comments>http://jens.mooseyard.com/2009/09/ottoman-for-cocoa-and-bug-fixes/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 04:52:21 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[ottoman]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=347</guid>
		<description><![CDATA[	I&#8217;ve pushed out a few updates to the Ottoman library today. These fix a couple of embarrassing bugs, and also add an API in regular ol&#8217; Objective-C for those of you who aren&#8217;t into that funky &#8220;C++&#8221; stuff.

	(The Cocoa stuff uses MYUtilities, so if you&#8217;re not already using that, please read the setup instructions.)
 ]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ve pushed out a few <a href="http://bitbucket.org/snej/ottoman/changesets/" title="">updates to the Ottoman library</a> today. These fix a couple of embarrassing bugs, and also add an <span class="caps">API</span> in regular ol&#8217; Objective-C for those of you who aren&#8217;t into that funky &#8220;C++&#8221; stuff.</p>

	<p>(The Cocoa stuff uses MYUtilities, so if you&#8217;re not already using that, please read the <a href="http://bitbucket.org/snej/mynetwork/wiki/Setup" title="">setup instructions</a>.)</p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/09/ottoman-for-cocoa-and-bug-fixes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternate images for Ottoman logo</title>
		<link>http://jens.mooseyard.com/2009/09/alternate-images-for-ottoman-logo/</link>
		<comments>http://jens.mooseyard.com/2009/09/alternate-images-for-ottoman-logo/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 04:56:46 +0000</pubDate>
		<dc:creator>jens</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[ottoman]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://jens.mooseyard.com/?p=345</guid>
		<description><![CDATA[	It&#8217;s got a moose! But then I found the ottoman with hanging files inside and it was even more perfect&#8230;

	

	I thought this one was pretty damn stylish too:

	
 ]]></description>
			<content:encoded><![CDATA[	<p>It&#8217;s got a moose! But then I found the ottoman with hanging <em>files</em> inside and it was even more perfect&#8230;</p>

	<p><div style="text-align:center;"><img src="http://jens.mooseyard.com/wp-content/uploads/2009/09/moose-storage-ottoman.jpg" alt="moose-storage-ottoman.jpg" border="0" width="416" height="349" /></div></p>

	<p>I thought this one was pretty damn stylish too:</p>

	<p><div style="text-align:center;"><img src="http://jens.mooseyard.com/wp-content/uploads/2009/09/abstract-design-storage-ottoman.jpg" alt="abstract-design-storage-ottoman.jpg" border="0" width="550" height="504" /></div></p>
 ]]></content:encoded>
			<wfw:commentRss>http://jens.mooseyard.com/2009/09/alternate-images-for-ottoman-logo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->