<?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 &#187; Peer-to-Peer</title>
	<atom:link href="http://jens.mooseyard.com/category/peer-to-peer/feed/" rel="self" type="application/rss+xml" />
	<link>http://jens.mooseyard.com</link>
	<description>Little boxes made of words, by Jens Alfke</description>
	<lastBuildDate>Thu, 19 Jan 2012 18:29:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<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>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>
	</channel>
</rss>

