<?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>theChrisWalker.net</title>
	<atom:link href="http://thechriswalker.net/feed" rel="self" type="application/rss+xml" />
	<link>http://thechriswalker.net</link>
	<description>I like Web Development</description>
	<lastBuildDate>Fri, 28 May 2010 14:45:32 +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>HTML5 WebSockets, very cool. (part 1)</title>
		<link>http://thechriswalker.net/2010-05/html5-websockets-very-cool-part-1.html</link>
		<comments>http://thechriswalker.net/2010-05/html5-websockets-very-cool-part-1.html#comments</comments>
		<pubDate>Fri, 28 May 2010 14:45:32 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=215</guid>
		<description><![CDATA[I only found out about these at the Future of Web Design on Tuesday. I knew they existed in the spec but had never really investigated what they were or how they worked. Now I know I am excited. It seems they are to web apps what the XMLHTTPRequest was when it started to get [...]]]></description>
			<content:encoded><![CDATA[<p>I only found out about these at the Future of Web Design on Tuesday. I knew they existed in the spec but had never really investigated what they were or how they worked. Now I know I am excited. It seems they are to web apps what the XMLHTTPRequest was when it started to get used for AJAX. So let&#8217;s look at what they are, and then why they can be so beneficial to web development. It&#8217;s also worth pointing out at this stage that only Chrome 4+ (I think that version, I&#8217;m writing from memory) supports WebSockets natively although apparently Mozilla want to implement them in the next iteration of Firefox (they are already available with an add-on), so don&#8217;t expect to be using them in any non-specialist projects just yet.</p>
<p><span id="more-215"></span></p>
<h2>What are WebSockets?</h2>
<p>WebSockets are a connection that the browser makes to a server. Unlike a normal HTTP request, this is not a simple &#8220;send request&#8221;, &#8220;receive response&#8221; connection. This is a persistent and full-duplex connection. They can run over port 80 (or 443 for a WebSocket over TLS/SSL) and so have little difficulty with firewalls. There are some concerns over their interaction with proxies, particularly transparent ones. Once the browser sets up the WebSocket, you can send UTF8 text over it, and receive text data from the server. All this sending and receiving over data requires no more headers and only a 2 byte overhead per message.</p>
<h2>Why are they going to be so useful?</h2>
<p>It&#8217;s really the last sentence of that last paragraph that is important. The problem is trying to get data from the server when it&#8217;s available. Web apps using AJAX (or similar techniques), have to ask for data and then get a response, i.e. polling for updates or using Comet-like long polling techniques &#8211; where the request is made and the connection opened but the response is delayed until the server decides it has something useful to say. The Comet technique allows much better real-time updates from the server, but there&#8217;s still the overhead of the HTTP request headers and then the response headers/content.</p>
<p>WebSockets aim to alleviate both issues. Once the socket is open, data can flow from the server to the client whenever the server decides it wants to. Also the client can send information to the server without have to send any extra headers, any info it receives from the server is also header free and therefore the process is very efficient. HTTP headers tend to bulk up with Cookies and remain the same size irrespective of the payload sent.</p>
<h2>Do you have an example I can actually use?</h2>
<p>I do, but it&#8217;s not exactly ready for distribution yet. I built a very basic chat client that uses WebSockets as a demo for myself. The hardest bit was writing a socket server in PHP that could handle multiple clients and manage the broadcasting of data to them. I will post all the code in part 2 &#8212; watch this space! (in the mean time a search for &#8220;websocket&#8221; on Google Code will find you some examples (it&#8217;s what I based my code on&#8230;)</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-05/html5-websockets-very-cool-part-1.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tethering the Google G1 &#8212; at last!</title>
		<link>http://thechriswalker.net/2010-03/tethering-the-google-g1-at-last.html</link>
		<comments>http://thechriswalker.net/2010-03/tethering-the-google-g1-at-last.html#comments</comments>
		<pubDate>Fri, 26 Mar 2010 18:29:51 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[G1]]></category>
		<category><![CDATA[Phones]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=204</guid>
		<description><![CDATA[Wow, I have wanted this for such a long time and I finally found out how to do it today. In fact I have posted this entry whilst on the bus using my Android phone&#8217;s 3G capabilities with my laptop connected by USB.
And you don&#8217;t have to have root access!
OK, so how does it work. [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, I have wanted this for such a long time and I finally found out how to do it today. In fact I have posted this entry whilst on the bus using my Android phone&#8217;s 3G capabilities with my laptop connected by USB.</p>
<h2>And you don&#8217;t have to have root access!</h2>
<p>OK, so how does it work. There&#8217;s two parts. One on the PC (or Mac&#8230;) and one on the phone. The phone bit is easy thanks to the man behind <a href="http://code.google.com/p/proxoid/">Proxoid</a> a proxy App for Android. It&#8217;s free and available in the Marketplace. Also it&#8217;s a tiny download and has almost zero configuration!  The PC bit requires the Android SDK, which is a free download from Google. Here are the instructions:<br />
<span id="more-204"></span></p>
<h3>Phone Setup</h3>
<ol>
<li><img style="float:right" src="http://chart.apis.google.com/chart?cht=qr&#038;chs=128x128&#038;chl=market%3A%2F%2Fsearch%3Fq%3Dproxoid" alt="market://search?q=proxoid" title="market://search?q=proxoid" /> Get &#8220;Proxoid&#8221; from the marketplace (<a href="market://search?q=proxoid">market://search?q=proxoid from your phone</a> or use the QR code) </li>
<li>Enable USB Debugging  from <em>Settings > Applications > Development > USB Debugging</em></li>
<li>Run Proxoid and connect your phone to your PC by USB.</li>
<li>(optional) Choose the port you want to use (default: 8080)</li>
</ol>
<h3>PC Setup</h3>
<p>These steps are pretty generic, as they will be different for different operating systems. I&#8217;ll give full instructions for Linux Mint 8 (the distor I am using) which should work for most Ubuntu/Debian type systems.</p>
<ol>
<li>Download Android SDK from <a href ="http://developer.android.com/sdk/index.html">http://developer.android.com/sdk/index.html</a></li>
<li>Extract it somewhere.</li>
<li>Start the ADB server (more code below)</li>
<li>Start the port forwarding.</li>
<li>Change your network proxy</li>
</ol>
<p>So on Mint that goes along the lines of:</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">wget</span> http:<span class="sy0">//</span>developer.android.com<span class="sy0">/</span>sdk<span class="sy0">/</span>download.html?<span class="re2">v</span>=android-sdk_r05-linux_86.tgz<br />
$ <span class="kw2">tar</span> xcf android-sdk_r05-linux_86.tgz<br />
$ <span class="kw3">cd</span> android-sdk-linux_86<span class="sy0">/</span>tools<br />
$ <span class="kw2">sudo</span> .<span class="sy0">/</span>adb start-server<br />
<span class="sy0">*</span> daemon not running. starting it now <span class="sy0">*</span><br />
<span class="sy0">*</span> daemon started successfully <span class="sy0">*</span><br />
$ <span class="kw2">sudo</span> .<span class="sy0">/</span>adb forward tcp:<span class="nu0">8080</span> tcp:<span class="nu0">8080</span><br />
$ gnome-network-properties</div></div>
<p>That will bring up the network proxy setup. I have a &#8220;location&#8221; set for the proxy which is a SOCKS Proxy at &#8220;localhost&#8221; on port 8080 (or whichever yort u choose).</p>
<p>Open you&#8217;re browser and bingo Internet over 3G &#8211; try http://whatismyip.com to check you&#8217;re not on your usual IP address!</p>
<p>As the SOCKS proxy pretty much only works for HTTP and web based traffic you might want to use FoxyProxy for Firefox which allows you to change proxy settings quickly and easily. Definitely a good idea for windows users, not sure how easy it is on a Mac. Also I wrapped the ADB commands into a single script that I can run to start the tethering.</p>
<p>There you go.  Tethered 3G internet access for Android phones!</p>
<p>So far not free and non-jailbroken way to do this on an iPhone (please someone prove me wrong!)&#8230;</p>
<p><strong>UPDATE: 15th May 2010</strong> I have since found that Proxoid doesn&#8217;t always work for me. However the same effect can be achieved (and more securely) using ConnectBot (or any other SSH client supporting Dynamic Port Forwarding) to setup a SOCKS proxy SSH tunnel.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-03/tethering-the-google-g1-at-last.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VPS Migration for thechriswalker.net &#8211; New Host, New OS, no Plesk</title>
		<link>http://thechriswalker.net/2010-03/vps-migration-for-thechriswalker-net-new-host-new-os-no-plesk.html</link>
		<comments>http://thechriswalker.net/2010-03/vps-migration-for-thechriswalker-net-new-host-new-os-no-plesk.html#comments</comments>
		<pubDate>Thu, 25 Mar 2010 19:16:21 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Server Administration]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=198</guid>
		<description><![CDATA[Not that I didn&#8217;t like Plesk. I just have the urge to understand things well, and I couldn&#8217;t understand all of how Plesk worked&#8230; So I wanted it &#8220;all-manual&#8221;, like the true hardcore (read: idiot) I am.
I had been using a VPS to host this website (amongst other things) and it was getting old. It [...]]]></description>
			<content:encoded><![CDATA[<p>Not that I didn&#8217;t like Plesk. I just have the urge to understand things well, and I couldn&#8217;t understand all of how Plesk worked&#8230; So I wanted it &#8220;all-manual&#8221;, like the true hardcore (read: <em>idiot</em>) I am.</p>
<p>I had been using a VPS to host this website (amongst other things) and it was getting old. It ran on CentOS 4 and used Plesk as a control panel. PHP was down at version 4.2.2 or something and MySQL still at version 4.x. I didn&#8217;t understand server administration as well as I do now and the whole thing was a bit of a mess. So I decided a fresh start, with a VPS on more powerful hardware and built cleanly.</p>
<p>So I went for a basic VPS from <a href="http://www.34sp.com">34SP.com</a> with no control panel and using Ubuntu 9.04 as the OS. They set up the server quickly and so I went about configuring it how I wanted. There were a couple of snags along the road and so I&#8217;ll tell you about them here too.</p>
<p><span id="more-198"></span></p>
<h2>The Basics, disabling root.</h2>
<p>First things first, the VPS came with the root account enabled and that as the only user on the system. Now I like to have my root account disabled and use sudo, so I created an admin user, granted sudo rights and disabled the root account. The command used are below.</p>
<p>Create user and set password:</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit"><span class="co0"># useradd admin</span><br />
<span class="co0"># passwd admin</span><br />
<span class="co0"># visudo</span></div></div>
<p>Now in the sudoer&#8217;s file you&#8217;ll see a line for root which looks something like:</p>
<div class="codecolorer-container text mac-classic" ><div class="text codecolorer" style="font-family:inherit">root ALL=(ALL) ALL</div></div>
<p>duplicate this line but with you&#8217;re username:</p>
<div class="codecolorer-container text mac-classic" ><div class="text codecolorer" style="font-family:inherit">admin ALL=(ALL) ALL</div></div>
<p>save and exit. Now log out of <tt>root</tt> and back in as <tt>admin</tt>, then disable the root account:</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">sudo</span> <span class="kw2">passwd</span> <span class="re5">-l</span> root</div></div>
<p>and we&#8217;re done!. Now on this system my home directory wasn&#8217;t created (probably because I didn&#8217;t give the right flags in the <tt>useradd</tt> command. So we need to make it.</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">sudo</span> <span class="kw2">mkdir</span> <span class="re5">-p</span> <span class="sy0">/</span>home<span class="sy0">/</span>admin</div></div>
<h2>LAMP Stack</h2>
<p>34SP had installed Apache but not PHP or MySQL, both of which I wanted. In fact I wanted the following:</p>
<ul>
<li> Apache with mod_rewrite</li>
<li> PHP5.3+ (5.3 is important to me) with APC, Xdebug and MongoDB</li>
<li> MongoDB server </li>
<li> MySQL5 server </li>
</ul>
<p>I also needed to migrate my blog from it&#8217;s current location, to the new server. The Blog uses Wordpress 2.8.something and the latest version at time of writing is 2.9.2 (time to upgrade!). Wordpress doesn&#8217;t mention PHP5.3 support so this could be fun.</p>
<p>So, first hurdle, the default Ubuntu Repositories do not have packages for PHP5.3. This leaves 2 options, compile from source or find a repositiory which does have the packages. Knowing which I&#8217;d prefer and having already heard of dotdeb.org I added the dotdeb.org PHP5.3 repository to my <tt>sources.list</tt> and then I could install PHP5.3.2 and xdebug and apc right from <tt>apt</tt>!</p>
<p>After editing <tt>/etc/apt/sources.list</tt>:</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">sudo</span> <span class="kw2">apt-get</span> update<br />
$ <span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> php5 php5-mysql php5-cli php5-xdebug php5-apc mysql5-server</div></div>
<p>But I also wanted MongoDB which is only available as a PECL module. So I need the <tt>php5-dev</tt> package. unfortunately, this gave me an error about <tt>libtool</tt> not being the correct version. and the only way to resolve it (that I could find) was to use libtool from the previous Ubuntu release.</p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">sudo</span> <span class="kw2">apt-get</span> purge libtool<br />
$ <span class="kw2">wget</span> http:<span class="sy0">//</span>cn.ubuntu.com<span class="sy0">/</span>hardy<span class="sy0">/</span>libtool.deb<br />
$ <span class="kw2">sudo</span> <span class="kw2">dpkg</span> <span class="re5">-i</span> libtool.deb<br />
$ <span class="kw2">sudo</span> <span class="kw2">apt-get</span> <span class="kw2">install</span> php5-dev</div></div>
<p>Then it worked like a dream and I could finally use <tt>pecl</tt></p>
<div class="codecolorer-container bash mac-classic" ><div class="bash codecolorer" style="font-family:inherit">$ <span class="kw2">sudo</span> pecl <span class="kw2">install</span> mongo</div></div>
<p>That was the PHP module, but what about the actual MongoDB server itself? Well, there&#8217;s a repository for that as well. Add it to your sources.list, update then you can <tt>apt-get install mongodb</tt>. no configuration necessary. The phpinfo() output shows the mongo extension installed correctly and the mongo shell functions to show the mongodb server is working fine.</p>
<p>OK, now time to get my blog up and running, so I create a new virtual host in <tt>/etc/apache2/sites-available</tt> and use the apache tool to enable it <tt>sudo a2ensite thechriswalker.net</tt>. I have all my virtual hosts in <tt>/var/www/vhost/<domain>/{httpdocs,logs}</tt>, I change to the httpdocs directory and grab wordpress <tt> wget http://wordpress.org/latest.tar.gz</tt>, unzip and browse to it to see if it worked!</p>
<p>Well, of course it didn&#8217;t &#8211; I hadn&#8217;t done a couple of things. First I needed to restart Apache to enable the Virtual Host I had created. Then I realised that the DNS hadn&#8217;t propagated so I needed to set a static <tt>hosts</tt> entry on my local computer. This done I tried again &#8211; success!</p>
<p>So I dumped the database from the old VPS, copied (scp&#8217;d) my custom theme, plugins and some other non-wordpress content across to the new one. On the new one, I imported the wordpress database and tried to access it again. It took me through a 2 step &#8220;we need to update your database&#8221; (it was 2.8 not 2.9 remember) screen which worked great! That was easier than expected and I haven&#8217;t seen anything behave oddly under PHP5.3 &#8211; result.</p>
<h2>More</h2>
<p>Now I just need to setup the email side of things, I want to be able to send and recieve mail securely through this server, but thats a job for another day&#8230; Also I moved the email for this domain over to Google Apps, as I like GMail so much, so I may not even bother with the email part of this!</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-03/vps-migration-for-thechriswalker-net-new-host-new-os-no-plesk.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mongo &#8212; and the coolness of Document-Oriented Databases</title>
		<link>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html</link>
		<comments>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 21:44:22 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Databases]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Rapid Application Development]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=173</guid>
		<description><![CDATA[I have been following a PHP Rapid Application Development Framework called Lithium with much interest (for other reasons which I fully intend to blog about later) and they are the ones I owe for turning me on to document oriented database systems. 
So what are they and why are they so cool, and what/who the [...]]]></description>
			<content:encoded><![CDATA[<p>I have been following a PHP Rapid Application Development Framework called <a href="http://lithify.me" title="The Most RAD PHP Framework: Lithium">Lithium</a> with much interest (for other reasons which I fully intend to blog about later) and they are the ones I owe for turning me on to document oriented database systems. </p>
<p>So what are they and why are they so cool, and what/who the hell is &#8220;Mongo&#8221;?</p>
<p>Let&#8217;s deal with the what first. &#8220;Traditional&#8221; database systems are Relational, they are characterised by strictly defined tables, strong relations between tables and their <a href="http://wikipedia.org/wiki/ACID" title="ACID on Wikipedia">ACID</a> compliance. It simple terms that means you say: </p>
<p><em>&#8220;I want a table of users and each one <strong>will</strong> have a first name, a last name and an email address, and each of those <strong>will</strong> be a &#8216;text&#8217; entry of a maximum of 255 characters&#8221;</em>.</p>
<p>If at a later date you want to add more info, then you have to go back and alter your table definition, give the old rows default values and fix any coding bugs that relied on the previous structure (not that you&#8217;d ever develop such a dependant application). Now the approach in a document oriented database is that you say:</p>
<p><em>&#8220;I want a table of users&#8221;</em></p>
<p>Then you can give each one whatever data you want. you may have one user with a name and address, another with a name and phone number only, a third might have a phone number and address but no first name. All these records can co-exist! That&#8217;s pretty different and I really didn&#8217;t know whether it was a good idea. So I played with <a href="http://mogodb.org/" title="MongoDB homepage">MongoDB</a>.</p>
<p><span id="more-173"></span></p>
<p>MongoDB is really cool. I installed it my laptop simply and fired up the shell to play. The syntax is very javascript-like, becasue it <em>is</em> javascript! So we can do this.</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit">MongoDB shell version<span class="sy0">:</span> 1.3.3<span class="sy0">-</span><br />
url<span class="sy0">:</span> test<br />
connecting to<span class="sy0">:</span> test<br />
type <span class="st0">&quot;help&quot;</span> <span class="kw1">for</span> help<br />
<span class="sy0">&gt;</span> db.<span class="me1">myFirstMongoDB</span>.<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#123;</span>key<span class="sy0">:</span><span class="st0">&quot;value&quot;</span><span class="sy0">,</span> mixed<span class="sy0">:</span><span class="br0">&#91;</span><span class="st0">&quot;one&quot;</span><span class="sy0">,</span><span class="st0">&quot;two&quot;</span><span class="sy0">,</span><span class="st0">&quot;three&quot;</span><span class="br0">&#93;</span><span class="sy0">,</span> deep<span class="sy0">:</span><span class="br0">&#123;</span>has<span class="sy0">:</span><span class="br0">&#123;</span>another<span class="sy0">:</span><span class="st0">&quot;object&quot;</span><span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><br />
ObjectId<span class="br0">&#40;</span><span class="st0">&quot;4b96b836ea70a136feb89c20&quot;</span><span class="br0">&#41;</span><br />
<span class="sy0">&gt;</span> db.<span class="me1">myFirstMongoDB</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span> <span class="st0">&quot;_id&quot;</span> <span class="sy0">:</span> ObjectId<span class="br0">&#40;</span><span class="st0">&quot;4b96b836ea70a136feb89c20&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;key&quot;</span> <span class="sy0">:</span> <span class="st0">&quot;value&quot;</span><span class="sy0">,</span> &nbsp;<span class="st0">&quot;mixed&quot;</span> <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;one&quot;</span><span class="sy0">,</span> <span class="st0">&quot;two&quot;</span><span class="sy0">,</span> <span class="st0">&quot;three&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span> <br />
&nbsp; &nbsp;<span class="st0">&quot;deep&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;has&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;another&quot;</span> <span class="sy0">:</span> <span class="st0">&quot;object&quot;</span> <span class="br0">&#125;</span> <span class="br0">&#125;</span> <span class="br0">&#125;</span><br />
<span class="sy0">&gt;</span></div></div>
<p>Notice two amazing things here.</p>
<ol>
<li>We never created the table! we simply call <tt>db.myFirstMongoDB...</tt> which creates the &#8220;collection&#8221; (as they are called in the document oriented world). We certainly never defined a schema!</li>
<li>We passed an object with nested data. Not just simple fields! We can use this in a much more useful way in the next example</li>
</ol>
<p>So why might you want to do this. Consider a website with articles. Articles are written by a person, they are published on a date and the have content, tags, comments, view counts, trackbacks, and a proprietary rating system. If this where a relational database, we are looking at the following tables:</p>
<div class="codecolorer-container text mac-classic" ><div class="text codecolorer" style="font-family:inherit">articles: holds the article, date, person_id, view counts, proprietary rating<br />
people: holds the writers<br />
comments: the comments, related by article_id<br />
trackbacks: link back details<br />
ratings: the info for the proprietary system.<br />
tags: tag info<br />
tags_articles: a join table linking tags to the articles</div></div>
<p>Joining all that info together is not only complex, but can be a fair amount of load on the system. As more info wants to be added by the website owners changes become more complicated and difficult. However with Mongo I can hold the article in one collection like this:</p>
<p>[</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit"><span class="br0">&#123;</span> <br />
&nbsp; <span class="st0">&quot;published&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 21:21:00&quot;</span><span class="sy0">,</span> <br />
&nbsp; <span class="st0">&quot;author&quot;</span><span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;name&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Chris Walker&quot;</span><span class="sy0">,</span> <span class="st0">&quot;profile&quot;</span><span class="sy0">:</span> <span class="st0">&quot;/profiles/chris-walker&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;title&quot;</span><span class="sy0">:</span> <span class="st0">&quot;My amazing Article&quot;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;content&quot;</span><span class="sy0">:</span> <span class="st0">&quot;here's the text...&quot;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;tags&quot;</span><span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;wonder&quot;</span><span class="sy0">,</span> <span class="st0">&quot;amazement&quot;</span><span class="sy0">,</span> <span class="st0">&quot;mongo&quot;</span><span class="sy0">,</span> <span class="st0">&quot;demo&quot;</span><span class="sy0">,</span> <span class="st0">&quot;chris&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;comments&quot;</span><span class="sy0">:</span> <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Rosie&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span> <span class="st0">&quot;What is this?&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 22:02:00&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Chris&quot;</span><span class="sy0">,</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://thechriswalker.net/&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span><span class="st0">&quot;it's class, that's what!&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 23:12:00&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;anonymous&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span><span class="st0">&quot;I am your father.&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-10 01:25:20&quot;</span> <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#93;</span><span class="sy0">,</span><br />
&nbsp; rating<span class="sy0">:</span> <span class="br0">&#123;</span> stars<span class="sy0">:</span> <span class="nu0">5</span><span class="sy0">,</span> tagline<span class="sy0">:</span> <span class="st0">&quot;what a monster!&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; views<span class="sy0">:</span> <span class="nu0">1024</span><span class="sy0">,</span><br />
&nbsp; trackbacks<span class="sy0">:</span> <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://some.blog/some/where&quot;</span><span class="sy0">,</span> <span class="st0">&quot;quote&quot;</span><span class="sy0">:</span> <span class="st0">&quot;the text for the link&quot;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://some.other.blog/some/where/else&quot;</span><span class="sy0">,</span> <span class="st0">&quot;quote&quot;</span><span class="sy0">:</span> <span class="st0">&quot;the text they used to link here&quot;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#93;</span><br />
<span class="br0">&#125;</span></div></div>
<p>So that might look like a more complex entity. It is, but you can search for values in sub-documents, you can filter results on existence of certain keys, and you can pull all this info one result. Your previous 7 tables and 8 joins, just became 1 collection and no joins. guess which is quicker?</p>
<p>Try to pull articles with a certain tag: &#8220;balls&#8221;? In SQL you&#8217;d be doing this:</p>
<div class="codecolorer-container sql mac-classic" ><div class="sql codecolorer" style="font-family:inherit"><span class="kw1">SELECT</span> <span class="st0">`article_id`</span> <span class="kw1">FROM</span> <span class="st0">`tags_articles`</span> <span class="st0">`ta`</span> <span class="kw1">JOIN</span> <span class="st0">`tags`</span> <span class="st0">`t`</span> <span class="kw1">ON</span> <span class="st0">`ta`</span><span class="sy0">.</span><span class="st0">`tag_id`</span> <span class="sy0">=</span> <span class="st0">`t`</span><span class="sy0">.</span><span class="st0">`id`</span> <span class="kw1">WHERE</span> <span class="st0">`t`</span><span class="sy0">.</span><span class="st0">`name`</span> <span class="sy0">=</span> <span class="st0">'balls'</span></div></div>
<p>And that would just get you the list of Id&#8217;s and you&#8217;d still need to get the info for each article. In Mongo with the collection we described above, you&#8217;d do:</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit">db.<span class="me1">articles</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="br0">&#123;</span> tags<span class="sy0">:</span> <span class="st0">&quot;balls&quot;</span><span class="br0">&#125;</span><span class="br0">&#41;</span></div></div>
<p>How much easier is that, and we&#8217;ve now got all the info, not just the &#8220;id&#8221;s! I was just amazed at how easy that is!</p>
<p>Of course this simplicity comes with a price, you lose the relational elements making tight relationships harder to work with. Also you some ease in aggregating things like &#8220;tags&#8221;, but MapReduce support makes this very efficient anyway.</p>
<p>In my next blog I&#8217;ll talk about Lithium, Mongo and how fast you can build a full blown web app with these tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>UPnP Wizardry</title>
		<link>http://thechriswalker.net/2010-01/upnp-wizardry.html</link>
		<comments>http://thechriswalker.net/2010-01/upnp-wizardry.html#comments</comments>
		<pubDate>Tue, 12 Jan 2010 15:18:37 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[UPnP]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=167</guid>
		<description><![CDATA[You may notice an Xbox360 related theme in my current posts, as after getting one, most of my technology thought process is involved in something to do with it. Hence the Xbox Live Gamercard API I wrote about before. Now we get on to UPnP.
Universal Plug and Play is used for 2 mains things as [...]]]></description>
			<content:encoded><![CDATA[<p>You may notice an Xbox360 related theme in my current posts, as after getting one, most of my technology thought process is involved in something to do with it. Hence the <a href="http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html">Xbox Live Gamercard API</a> I wrote about before. Now we get on to <a href="http://en.wikipedia.org/wiki/Universal_Plug_and_Play">UPnP</a>.</p>
<p>Universal Plug and Play is used for 2 mains things as far as I can tell.</p>
<ol>
<li>Dynamically opening holes in firewalls/NAT configurations for inbound connections to services. (<em>bad!</em></li>
<li>Media Discover/playback/control on a local network. (<em>good!</em>)</li>
</ol>
<p>The first is bad in my opinion. I don&#8217;t want the ability for some software behind my firewall to allow connections into my network. It might make some software function a little more smoothly, but if it&#8217;s that important that connections can be made inbound I would have set up a port-forward myself.</p>
<p>So I am only concerned with the second scenario.</p>
<p> <span id="more-167"></span></p>
<p>The situation was that the Xbox360 can Stream Music/Pictures and Video from a <a href="www.xbox.com/PCsetup">Windows based PC</a>. Great, except if you haven&#8217;t got a windows based PC, or you have all your media on a fileserver running Ubuntu Server and don&#8217;t want to have to have another PC on just to stream to your Xbox360. So I did some digging and it turns out that the Xbox360 uses a &#8220;<em>standardised</em>&#8221; UPnP discovery protocol. I say &#8220;<em>standardised</em>&#8221; because it&#8217;s not quite compliant, but close enough.</p>
<p>I look at the options available and try <a href="http://ushare.geexbox.org/">uShare </a>first. It looks good, but the Xbox won&#8217;t see it and it can&#8217;t read the ID3 info from my music &#8211; rendering the whole thing useless.</p>
<p>Next <a href="http://www.twonkyvision.de/buy_server.html">TwonkyMediaServer</a>. I read somewhere that the linux demo doesn&#8217;t expire. I hope not, because it worked beautifully pretty much out of the box. The only gripe is that there&#8217;s no nice init scripts and I have to run a shell script every time I want to start/stop/status/restart it. But it read my media and the Xbox360 recognised it and I haven&#8217;t looked back.</p>
<p>So I thought, <em>Wow, this UPnP thing is pretty cool. but it must be more than this?</em>. So I booted up a Windows7 PC. I had had trouble with this machine because Windows Media Player didn&#8217;t like the fact that all my music was on a Read-Only SMB share. That and I hate the way the Windows won&#8217;t let you connect to different shares on the host with different credentials! How rubbish!</p>
<p>Still WMP12 didn&#8217;t like my read-only filesystem. However, with Twonky running on the network, all the music just &#8220;appeared&#8221; like magic in the &#8220;Other Libraries&#8221; section. nice.</p>
<p>Then I thought of another thing that had been annoying me. <em>Why can&#8217;t I stream media from my fileserver to my Android phone over Wifi?</em></p>
<p>Well, guess what? There&#8217;s an App for that!</p>
<p><a href="http://www.andromote.de/">Andromote</a> can connect to UPnP media servers and play back the content. Also, and this is quite cool, I can specifiy the media server as Twonky, specify the Media Renderer (i.e. what plays it) as my Windows7 PC, and use the Andromote App as the Control Point &#8211; allow full media browsing, playback, skipping, seeking and volume control of the PC from my phone. Pretty neat, eh?</p>
<p>The whole time, all the servers and renderers are auto-discovered, no configuration necessary. That&#8217;s pretty cool.</p>
<p>So in summary UPnP media is in 3 distinct parts and the best bit is that each part can be on a separate physical machine, or 2 on 1, or 1 each on 3 separate physical devices. Very flexible. The parts:</p>
<p><strong>Media Server</strong> &#8212; Serves the media &#8211; duh. i.e. media is physically stored (or accessed from) here.</p>
<p><strong>Media Renderer</strong> &#8212; Plays back the media &#8211; simples.</p>
<p><strong>Media Control Point</strong> &#8212; Controls the Media. Reads media info and tells the renderer what to play.</p>
<p>So the most common configuration is the server on one machine and the renderer and control point in another. That&#8217;s how the Xbox360 works.</p>
<p>So that was my experience into UPNP. I realise now that it was slightly unecessary as my old Xbox, running <a href="http://xbmc.org/">XBMC</a>, would have (<a href="http://xbmc.org/wiki/?title=UPnP_Sharing#Compatible_UPnP_ControlPoints_and_Media-Players_.28UPnP-clients.29">according to their wiki</a>) worked as the UPNP media server out of the box and is conencted to all my shares, and isn&#8217;t a hassle to turn on as it sits right next to my Xbox360. It&#8217;ll be my fallback if Twonky does expire&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-01/upnp-wizardry.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xbox Live Gamercard API</title>
		<link>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html</link>
		<comments>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html#comments</comments>
		<pubDate>Thu, 31 Dec 2009 11:34:25 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=155</guid>
		<description><![CDATA[So, got decided to join most of my friends and I got an Xbox 360. Me being me though, I got interested in the way that all the information about your &#8220;Gamertag&#8221; is stored an accessible on the xbox.com website. Wouldn&#8217;t it be fun to do something with this data!
As it turns out, I was [...]]]></description>
			<content:encoded><![CDATA[<p>So, got decided to join most of my friends and I got an Xbox 360. Me being me though, I got interested in the way that all the information about your &#8220;Gamertag&#8221; is stored an accessible on the xbox.com website. Wouldn&#8217;t it be fun to do something with this data!</p>
<p>As it turns out, I was beaten to the post by Duncan MacKensie (<a href="http://duncanmackenzie.net/Blog/put-up-a-rest-api-for-xbox-gamertag-data">http://duncanmackenzie.net/Blog/put-up-a-rest-api-for-xbox-gamertag-data</a>) who hosts a webservice to retrieve gamer data from Microsoft. <del datetime="2009-12-31T11:41:44+00:00"> I could find <strong>no</strong> details about how this service works, where the data comes from or anything! Either he has a relationship with Microsoft, or he scrapes xbox.com but either way, the data seems pretty consistent and reliable.</del> <em>Actually it turns out this information was right there on his website&#8230; <a href="http://www.duncanmackenzie.net/Blog/if-you-are-wondering-where-i-get-my-xbox-live-info">http://www.duncanmackenzie.net/Blog/if-you-are-wondering-where-i-get-my-xbox-live-info</a> So he gets it as part of his membership to the Xbox Community Developer Program.</em></p>
<p>However, the webservice is great, and returns XML which is fine, but I thought it would be more useful to me to have a PHP API for this data. So I wrote one which retrieves data from Duncans webservice.</p>
<p> <span id="more-155"></span></p>
<p>Then I thought wouldn&#8217;t it be great to be able to use this dynamically in a webpage, so I wrote a service frontend which will return JSON formatted data. Then I thought wouldn&#8217;t it be useful to let other people use this as well, so I modified it and it can now cope with JSONP requests with a &#8220;_callback&#8221; parameter.</p>
<p>OK, so what does this all mean.</p>
<p><strong>The PHP</strong></p>
<p>The class is called gamertag and the usage is very simple:</p>
<div class="codecolorer-container php mac-classic" ><div class="php codecolorer" style="font-family:inherit"><span class="kw2">&lt;?php</span><br />
<span class="co1">// include the class file</span><br />
<span class="kw1">require</span> <span class="st0">&quot;gamertag.php&quot;</span><span class="sy0">;</span><br />
<br />
<span class="co1">//instantiate</span><br />
<span class="re0">$G</span> <span class="sy0">=</span> <span class="kw2">new</span> Gamertag<span class="br0">&#40;</span><span class="st_h">'thechriswalker'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="co1">//get data</span><br />
<span class="re0">$data</span> <span class="sy0">=</span> <span class="re0">$G</span><span class="sy0">-&gt;</span><span class="me1">getArray</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw3">print_r</span><span class="br0">&#40;</span><span class="re0">$G</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>which outputs something like this:</p>
<pre class='code'>Array
(
    [Gamertag] => thechriswalker
    [AccountStatus] => Silver
    [State] => Valid
    [ProfileUrl] => http://live.xbox.com/member/thechriswalker
    [TileUrl] => http://avatar.xboxlive.com/avatar/thechriswalker/avatarpic-l.png
    [AvatarFullUrl] => http://avatar.xboxlive.com/avatar/thechriswalker/avatar-body.png
    [Country] => United Kingdom
    [Location] => Bradninch
    [Bio] =>
    [Reputation] => 58.72229
    [ReputationImageUrl] => http://live.xbox.com/xweb/lib/images/gc_repstars_external_12.gif
    [Zone] => Recreation
    [GamerScore] => 230
    [PresenceInfo] => Array
        (
            [Valid] => true
            [Info] => Last seen 12/29/09   playing Modern Warfare® 2
            [Info2] =>
            [LastSeen] => Tue, 29 Dec 2009 21:35:22 +0000
            [Online] => false
            [StatusText] => Offline
            [Title] => Modern Warfare® 2
        )

    [RecentGames] => Array
        (
            [0] => Array
                (
                    [Name] => Modern Warfare® 2
                    [TotalAchievements] => 50
                    [TotalGamerScore] => 1000
                    [Image32Url] => http://tiles.xbox.com/tiles/Z+/tF/12dsb2JgbA9ECgQJGgYfVl5UL2ljb24vMC84MDAwIAABAAAAAPhq63g=.jpg
                    [Image64Url] => http://tiles.xbox.com/tiles/CE/Vx/0Gdsb2JhbC9ECgQJGgYfVl5UL2ljb24vMC84MDAwAAAAAAAAAP9eRRc=.jpg
                    [LastPlayed] => Tue, 29 Dec 2009 21:32:52 +0000
                    [Achievements] => 9
                    [GamerScore] => 115
                    [DetailsURL] => http://live.xbox.com/en-US/profile/Achievements/ViewAchievementDetails.aspx?tid=%09%5d%3a%60m%2fl%3b%7cw&amp;compareTo=thechriswalker
                )

            [1] => Array
                (
                    [Name] => PGR 4
                    [TotalAchievements] => 60
                    [TotalGamerScore] => 1250
                    [Image32Url] => http://tiles.xbox.com/tiles/Y1/qn/0Gdsb2JgbA9ECgR8GgMfWSlaL2ljb24vMC84MDAwIAABAAAAAP+IWnw=.jpg
                    [Image64Url] => http://tiles.xbox.com/tiles/DP/ST/12dsb2JhbC9ECgR8GgMfWSlaL2ljb24vMC84MDAwAAAAAAAAAPi89BM=.jpg
                    [LastPlayed] => Mon, 28 Dec 2009 16:59:25 +0000
                    [Achievements] => 5
                    [GamerScore] => 115
                    [DetailsURL] => http://live.xbox.com/en-US/profile/Achievements/ViewAchievementDetails.aspx?tid=%09%5d%3a%15%18*iAq%0b&amp;compareTo=thechriswalker
                )

        )

)</pre>
<p>So now we can easily get at the data. The source code for the class (which is not fully tested, but the basics work!) is at <a href="http://thechriswalker.net/xbox360/gamertag.source.php">http://thechriswalker.net/xbox360/gamertag.source.php</a> (NB it requires either PHP5 (for json_encode) or the PEAR Services_JSON class if you want to use the &#8220;getJSON()&#8221; method).</p>
<p><strong>The JSON</strong></p>
<p>PHP is well and good but what if I want to use a JSON/JSONP (JSONP is for cross-domain information requesting and is very useful for public information services, see http://en.wikipedia.org/wiki/JSON#JSONP) request, well, that can be done at <a href="http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG">http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG</a> for the straight JSON or <a href="http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG&#038;_callback=YOUR_CALLBACK_FUNCTION_NAME"> http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG&#038;_callback=YOUR_CALLBACK_FUNCTION_NAME</a> for JSONP.</p>
<p>The first returns just JSON with a content type &#8220;application/json&#8221; and the second returns a javascript function call to your callback function with the JSON object as the only parameter and a content type of &#8220;text/javascript&#8221;.</p>
<p>These enabled me to build a simple Google Gadget to display a Gamercard:</p>
<p><center><br />
<script src="http://www.gmodules.com/ig/ifr?url=http://thechriswalker.net/xbox360/xblgamercard.xml&amp;up_gamertag=thechriswalker&amp;synd=open&amp;w=600&amp;h=200&amp;title=Xbox+Live+Gamertag+Info+for+%22chriswalker%22&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999&amp;output=js"></script></center></p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ZFS-FUSE and OpenSolaris and why Google Groups are such a good resource&#8230;</title>
		<link>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html</link>
		<comments>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html#comments</comments>
		<pubDate>Thu, 03 Sep 2009 10:21:22 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[fileserver]]></category>
		<category><![CDATA[Solaris]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=150</guid>
		<description><![CDATA[As my last post said, I&#8217;m using ZFS and love the way it works, but am having trouble with the performance of ZFS-FUSE. It&#8217;s not unusable, I just expected more.
So I thought, OpenSolaris. It&#8217;s the original implementation of the filesystem it must be great, so I export my zpools and boot from the LiveCD (another [...]]]></description>
			<content:encoded><![CDATA[<p>As my <a href='http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html'>last post</a> said, I&#8217;m using ZFS and love the way it works, but am having trouble with the performance of ZFS-FUSE. It&#8217;s not unusable, I just expected more.</p>
<p>So I thought, OpenSolaris. It&#8217;s the original implementation of the filesystem it must be great, so I export my zpools and boot from the LiveCD (another great reason to try it).</p>
<p>However it wasn&#8217;t going to be that easy&#8230; When I try to import my zpools in Solaris I get errors stating the vdev&#8217;s are corrupt! Something like:</p>
<blockquote><p>status: One or more devices contains corrupted data.<br />
action: The pool cannot be imported due to damaged devices or data.</p></blockquote>
<p>Scared I boot back to linux.</p>
<p><span id="more-150"></span></p>
<p>All the disks and zpools are fine. So, back to Solaris and they still look corrupt. So I search and find <a href='http://groups.google.com/group/zfs-fuse/browse_thread/thread/0fe4c06dad476d0d#'>this</a> on the ZFS-FUSE Google Group.</p>
<p>Sun claims best practice is to use an entire disk when assigning disks to vdevs, rather than just partitions. So that&#8217;s what I did in linux. However the Linux implementation differs form the Solaris one and whole disks added in Solaris get a single partition first and that is added to the vdev.</p>
<p>Great! Now I have these zpools I can&#8217;t use anywhere else. To test I used a pool I set up as a mirror and detached a vdev (one disk). I then repartitioned the disk to have one big partition and also wiped the ZFS pool info from it (easier said than done! <a href='http://techarcana.net/2009/02/19/stubbornly-persistent-zfs-pools/'>Ghost pools seem to be a problem!</a>). Then I re-inserted the new partition into the the zpool and waited for resilver. Then I did the same with the other drive, detach from pool, partition, attach partition and resilver.</p>
<p>Bingo. It works in Solaris! Now I just have to find a spare 750Gb disk so I can do the same for my JBOD style zpool&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why didn&#8217;t I know about ZFS before?</title>
		<link>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html</link>
		<comments>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html#comments</comments>
		<pubDate>Thu, 06 Aug 2009 09:31:11 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[fileserver]]></category>
		<category><![CDATA[Solaris]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=141</guid>
		<description><![CDATA[I have a fileserver at home. I have done for many years now. The first incarnation was based on Fedora Core 3 (which will tell you *exactly* how long ago that was&#8230;) and was very simple. I had an old Xbox HDD (8GB Seagate) and 2 shiny new 200GB Western Digiatl drives for storage.
This was [...]]]></description>
			<content:encoded><![CDATA[<p>I have a fileserver at home. I have done for many years now. The first incarnation was based on Fedora Core 3 (which will tell you *exactly* how long ago that was&#8230;) and was very simple. I had an old Xbox HDD (8GB Seagate) and 2 shiny new 200GB Western Digiatl drives for storage.</p>
<p>This was also my first major experience with Linux as a whole, so I was trying to keep things simple. So I did a default type install, with LVM on the 2&#215;200GB disks to give one logical 400GB partition.</p>
<p>All was fine and dandy until I wanted to upgrade a couple of years later and not knowing much about LVM, wiped all my data. Yes, ALL my data. I had some important stuff backed up, but a lot of non-critical but frustrating to lose data (many GBs of painstakingly ripped and encoded CDs and Audiobooks for example). </p>
<p><span id="more-141"></span></p>
<p>I was gutted, and vowed not to use LVM again (note my solution to my mistake and lack of knowledge &#8211; never use the software again! Well thought out!). So I rebuilt the server using CentOS 4.x ( I can&#8217;t remember&#8230;) and added another 250GB disk. This time I kept each disk seperate with it&#8217;s own filesystem.</p>
<p>This worked fine for ages until the disks were nearly full and I spent all my time moving data from one disk to another to gain a few GBs extra on another disk. Nightmare.</p>
<p>So I decided it was time to start again and did some research into the available filesystems people use for fileservers, how software RAID can be implemented and so on. In this time I came across ZFS and I couldn&#8217;t believe what it could do. It seemed to good to be true. I now know this to be false and it can&#8217;t do everything, but it can do an awful lot!</p>
<p>So how can I use ZFS? Well, if you use any Solaris variant, then you probably already are. Otherwise chances are slim that you&#8217;ve encountered it. I didn&#8217;t really want to go down the OpenSolaris route, but instead stick to Linux where I&#8217;m more comfortable. This poses issues, as the licencing behind ZFS from Sun doesn&#8217;t fit with GPL, so no kernel support for ZFS. Instead someone (I&#8217;d love to reference but I forget his name, google will surely help &#8211; <a href="http://google.com/search?q=ZFS+FUSE">http://google.com/search?q=ZFS+FUSE</a>) has ported ZFS to FUSE which is great except for the massive memory usage and the poor performance. </p>
<p>Those actually sound like quite big issues! Well, the memory thing is not so bad as it seems. ZFS is not memory instense (well, actually it constantly uses about 256Mb so it&#8217;s not light) but uses available memory cache to store data in case it needs it again. A good idea, as the memory is otherwise just doing nothing! The Performance is pretty poor though. It&#8217;s enough for my network and to stream music, pictures and video over my network. But single file transfer never hits much more than 8Mb/s read or write.</p>
<p>Now I&#8217;m interested in trying some of the other OS options, as ZFS is easy to &#8220;export&#8221; from one OS and &#8220;import&#8221; into another. What are the options?</p>
<ul>
<li><strong>Option 1: OpenSolaris &ndash;</strong> Seems like a good idea. The native platform, has a good AMP stack so should be fine for my needs. Have heard some stability issues, but not so much with ZFS, but the OS itself.</li>
<li><strong>Option 2: Nextenta &ndash;</strong> Solaris Kernel with GNU userland. Supposed to be a good happy medium, sounds too much like a compromise to me&#8230;</li>
<li><strong>Option 3: BTRFS &ndash;</strong> different route totally but a new filesystem designed not to mirror ZFS, but to take the best of everything it can. Some aspects very like ZFS. Very promising project, but too young.</li>
</ul>
<p>Kinda only leaves OpenSolaris&#8230; I&#8217;ll let you know how I get on.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What people misunderstand about Google Wave</title>
		<link>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html</link>
		<comments>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html#comments</comments>
		<pubDate>Wed, 10 Jun 2009 09:34:18 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Wave]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=136</guid>
		<description><![CDATA[I had heard about Google Wave, had a quick look at their UI, thought &#8220;shiny&#8221; and not really paid it much attention. Then I was reminded of it again recently and so I had another look, watched the Keynote Speech that they gave at the Google I/O 2009 and had a bit of a look [...]]]></description>
			<content:encoded><![CDATA[<p>I had heard about Google Wave, had a quick look at their UI, thought &#8220;shiny&#8221; and not really paid it much attention. Then I was reminded of it again recently and so I had another look, watched the Keynote Speech that they gave at the Google I/O 2009 and had a bit of a look around the web for related articles.</p>
<p>And I got really excited and really angry.</p>
<p>I got angry, because most people weren&#8217;t excited for the right reasons, or were dismissive / &#8220;anti&#8221; because they didn&#8217;t really see what Google has done.</p>
<p>But because I am so excited about Wave (not just Google Wave), I thought I&#8217;d post this to help you understand what Google Wave actually is and what it isn&#8217;t.</p>
<h3>What Google Wave isn&#8217;t</h3>
<p><strong>Google Wave isn&#8217;t Wave.</strong></p>
<p> <span id="more-136"></span></p>
<p><em>Wait a second! Why have you dropped the &#8220;Google&#8221;, what&#8217;s &#8220;Wave&#8221; all about?</em></p>
<p>Firstly let&#8217;s take an analogy, with something you are no doubt familiar with. Consider the statement: </p>
<blockquote><p>Google Mail is not email.</p></blockquote>
<p>Imagine that email didn&#8217;t exist and Google showcased Google Mail. People might think that email <strong>was</strong> Google Mail, but we all know that isn&#8217;t the case. </p>
<p>The same for Wave. Google have designed a messaging system which can be run by anyone. They have designed the protocols it will use which anyone can implement. This messaging system is not Google Wave, but Wave itself.</p>
<h3>What Google Wave is</h3>
<p>Google have designed a UI for Wave, which is Google Wave. </p>
<p>Don&#8217;t get me wrong, I like their interface. It is written in HTML5 using the Google Web Toolkit and it is super slick. </p>
<p>However, the Wave itself is far more exciting.</p>
<h3>What Wave is</h3>
<p>Wave is email redesigned for the 21st century. Email was born before the internet and has been flogged and flogged into how we use it now. It is inefficient, single one-way message based, bad with files, incosistent with rich styling, non-collaborative and basically just way past it&#8217;s &#8220;sell by date&#8221;. </p>
<p>With Wave we no longer deal in single messages, but conversations; where content evolves over time and can be &#8220;played back&#8221; to provide the user with context. Everything email and IM can do and more. They have designed the system to be extensible and so can communicate with other systems. They also designed it to work over a federated networks model, so many people running their own Wave servers can communicate in the same rich way as if they were communicating with their people on their own server.</p>
<p>Amazing really, and provided we can bridge the backwards compatibility gap<sup><a id='footnote-1-link' href='#footnote-1' title='go to footnote'>*</a></sup> (which we can, remember Wave is extensible!) then I see Wave replacing email altogether.</p>
<p>When Google Wave goes live, Google will also be releasing the server for anyone to run, learn, enjoy and stop using email with. I am looking forward it immensely. </p>
<p><strong><a href='#footnote-1-link' id='footnote-1' title='return to text'>[update 2009-08-06]</a></strong> Further developments have shown that yes &#8220;gateways&#8221; have been designed in, so Wave can replace email and any other messaging/collaboration protocols/tools if someone creates a &#8220;gateway&#8221; for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fantastic Contraption</title>
		<link>http://thechriswalker.net/2009-03/fantastic-contraption.html</link>
		<comments>http://thechriswalker.net/2009-03/fantastic-contraption.html#comments</comments>
		<pubDate>Sun, 29 Mar 2009 22:14:29 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Not Code]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=132</guid>
		<description><![CDATA[Oh my god. I can&#8217;t believe how addictive this game is. http://fantasticcontraption.com/. The simplicity of it really appeals to me. The idea is to move a pink block from one area on the course to another, and you do so by building a contraption from wheels and connectors. that&#8217;s pretty much it!
Doesn&#8217;t sound like much, [...]]]></description>
			<content:encoded><![CDATA[<p>Oh my god. I can&#8217;t believe how addictive this game is. http://fantasticcontraption.com/. The simplicity of it really appeals to me. The idea is to move a pink block from one area on the course to another, and you do so by building a contraption from wheels and connectors. that&#8217;s pretty much it!</p>
<p>Doesn&#8217;t sound like much, but if you are like me, you&#8217;ll not only want to finish all the levels but also go back and experiment with loads of other different ways to finish in the vain hope of finding the perfect solution. A solution that excels by being so simple, or so elegant. So unusual, or so complex. I could play for hours. But I won&#8217;t go on for hours.</p>
<p>I will leave you with some of the best contraptions I have managed to come up with, and the first one you should really vote as amazing, because (and I know this sounds a bit arrogant) is ingenious!</p>
<ul>
<li><a href='http://FantasticContraption.com/?designId=7000201'>unusual technique!</a> See if you can guess how it works before you start it!</li>
<li><a href='http://FantasticContraption.com/?designId=7001467'>Minimalistic elegance, perfect timing.</a></li>
<li><a href='http://FantasticContraption.com/?designId=6999805'>I saw a solution with more than one spinny thing, but this seemed a cooler solution (notice the pole to slow down the last ball slightly&#8230;)</a></li>
<li><a href='http://FantasticContraption.com/?designId=6981893'>A cool way to do &#8220;The Ball&#8221;</a></li>
</ul>
<p>That&#8217;s all for the moment, but I&#8217;m sure I&#8217;ll post more contraptions in the future&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-03/fantastic-contraption.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
