<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:admin="http://webns.net/mvcb/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel>
    <title>till's blog</title>
    <link>http://till.klampaeckel.de/blog/</link>
    <description>OMG -- it's not vox.com</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.4-beta1 - http://www.s9y.org/</generator>
    
    

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/till" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
    <title>CouchDB: checkpointing on view building</title>
    <link>http://feedproxy.google.com/~r/till/~3/fdis_Jxnw5U/76-CouchDB-checkpointing-on-view-building.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/76-CouchDB-checkpointing-on-view-building.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=76</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=76</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p><em>I'm posting about this tidbit because Google seemed to know nothing about it.</em></p>

<p>Anyway, during the view building process, we may see the following in the <code>couchdb.log</code> (<code>level = info</code>, at least, in <code>local.ini</code>):</p>

<pre><code>[...] [info] [...] checkpointing view update at seq 78163851 for citations _design/erlang
[...] [debug] [...] New task status for citations _design/erlang: Processed 17844590 of 107444308 changes (16%)
[...] [debug] [...] New task status for citations _design/erlang: Processed 17848060 of 107444308 changes (16%)
[...] [debug] [...] New task status for citations _design/erlang: Processed 17850878 of 107444308 changes (16%)
[...] [info] [...] checkpointing view update at seq 78170348 for citations _design/erlang
[...] [debug] [...] New task status for citations _design/erlang: Processed 17851087 of 107444308 changes (16%)
</code></pre>

<p>The above tells us, that CouchDB saved the current process during indexing and allows us to resume in case we decide to restart the CouchDB and interrupt the indexing process. I've tried it myself a couple times with CouchDB <code>0.10.0</code> &mdash; I also had not noticed this feature prior to it.</p>

<p>And why is this useful in particular? The biggest use for this is upgrading computing power (e.g. on AWS EC2) when we realize we need <em>MOAR</em> and then we are still able to resume when we <em>boot into</em> more resources.</p>

<p><strong>Sidenote:</strong> <em>Checkpointing</em> will not help if indexing is stopped <strong>and the view is adjusted/changed</strong>. Or when the indexing stopped due to an error, such as a <em>crash</em>.</p>

<p>That's all, kids.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=fdis_Jxnw5U:mP3IaOnMipc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=fdis_Jxnw5U:mP3IaOnMipc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=fdis_Jxnw5U:mP3IaOnMipc:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=fdis_Jxnw5U:mP3IaOnMipc:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=fdis_Jxnw5U:mP3IaOnMipc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=fdis_Jxnw5U:mP3IaOnMipc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/fdis_Jxnw5U" height="1" width="1"/>]]></content:encoded>

    <pubDate>Wed, 04 Nov 2009 19:50:00 +0100</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/76-guid.html</guid>
    <category>couchdb</category>
<category>documentation</category>
<category>performance</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/76-CouchDB-checkpointing-on-view-building.html</feedburner:origLink></item>
<item>
    <title>PHP: So you'd like to migrate from MySQL to CouchDB? - Part I</title>
    <link>http://feedproxy.google.com/~r/till/~3/7KxIzlVfCg0/74-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-I.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/74-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-I.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=74</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=74</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>This is the first part of a series. I'll start off by introducing CouchDB &mdash; from a PHP side, then I'll demo a couple basic use cases and I later on, I'll dive into migrations from MySQL.</p>

<p>My idea is to introduce CouchDB to a world where database-driven development generally refers to MySQL. By no means, this is meant to be disrespectful to MySQL, or SQL-databases in general. However, I'm a firm believer in <em>using the right tool for the job</em>.</p>

<h2>First things first!</h2>

<p>First off, before using CouchDB and maybe eventually replacing MySQL with it, we need to ask ourself the <strong>"Why?"</strong>-question.</p>

<p>And in order to be capable of more than a well-educated guess we need to familiarize ourselves with the CouchDB basics.</p>

<h3>Basics</h3>

<ul>
<li>Document-oriented and schema-less storage.</li>
<li>Erlang (for rock-solid-scaling-goodness).</li>
<li>RESTful HTTP-API (we'll get to that).</li>
<li>Everything is JSON - request data, storage, response!</li>
</ul>

<h4>Document-oriented</h4>

<p>In a document-oriented as to opposed to a relational store, the data is not stored in table, where data is usually broken down into fields. In a document-oriented store each record is stored along side and can have its own characteristics &mdash; properties of any kind.</p>

<p>As an example, consider these two records:</p>

<pre><code>Till Klampaeckel, Berlin
Till Klampaeckel, till@php.net, Berlin, Germany
</code></pre>

<p>In a relational store, we would attempt to break down, or normalize, the data. Which means that we would probably create a table with the columns name, email, city and country.</p>

<p>Consider adding another record:</p>

<pre><code>Till Klampaeckel, +49110, till@some.jabber
</code></pre>

<p>(<strong>Just fyi &mdash; this is not my real phone number!</strong>)</p>

<p>Looking for an intersection in the records, the name is the only thing this record has in common with the previous two. With a relational database, we would either have to add a column for phone number and <em>chat</em>, or we would start splitting off the data into multiple tables (e.g. a table called phone and one called chat) in order to get grip.</p>

<p>With a document-oriented database &mdash; such as CouchDB &mdash; this is not an issue.</p>

<p>We can store any data, constraints do not apply.</p>

<h4>Erlang</h4>

<p>Erlang was invented a while ago, by Ericsson, when it was still sans Sony. In a nutshell, Erlang's true strength is reliability and stability. It also manages to really utilize all the resources modern hardware has to offer since it's a master of parallelization.</p>

<p>CouchDB is written in Erlang, and also accepts view code written in Erlang. More on views later.</p>

<h4>RESTful HTTP-API</h4>

<p>For starters, a lot of HTTP-APIs claim to be RESTful, most of them are not. HTTP has so called request verbs (<code>DELETE</code>, <code>GET</code>, <code>HEAD</code>, <code>POST</code>, <code>PUT</code> among them) and a lot of APIs don't use them to the fullest extend, or rather not all.</p>

<p>Instead, most APIs are limited <code>GET</code> and maybe use a little <code>POST</code>. An example of such an API is the Flickr API.</p>

<p>Most of us are familiar with <code>GET</code> and <code>POST</code> already. For example, when you opened the web page to this blog entry, the browser made a <code>GET</code>-request. If you decide to <em>post</em> a comment later on &mdash; you guessed it, that's a <code>POST</code>-request.</p>

<p>Aside from its basic yet powerful nature, HTTP is interesting in particular because it is the least common multiple in many programming language. Whatever you use &mdash; C#, PHP, Python, Ruby &mdash; these languages know how to <em>talk</em> HTTP. And even better &mdash; most of them ship pretty comfortable wrappers.</p>

<h4>JSON</h4>

<p>JSON &mdash; it's godsend for those of us who never liked XML.</p>

<p>It's very lightweight, yet we able to represent lists and objects, integers, strings &mdash; most data types you would want to use. A clear disadvantage of JSON is that it lacks validation (think DTD), and of course comments &mdash; ha, ha!</p>

<h3>Why, oh why?</h3>

<p>So along with "Why?", we should consider the following:</p>

<ul>
<li>Does it make sense?</li>
<li>Is CouchDB (really) the better fit for my application?</li>
<li>What is my #1 problem in MySQL, and how does CouchDB solve it?</li>
</ul>

<p>And if we are still convinced to migrate all of our data, we'll need to decide on an access wrapper.</p>

<h2>It's all HTTP, right?</h2>

<p>By now, everyone has heard that CouchDB has a RESTful HTTP-API. But what does that imply?</p>

<p>It means, that we won't need to build a new extension in PHP to be able to use it. There's already either <code>ext/socket</code> or <code>ext/curl</code> &mdash; often both &mdash; in 99% of all PHP installs out there. Which means that PHP is more than ready to talk to CouchDB &mdash; right out of the box.</p>

<p>Since I mentioned JSON before &mdash; today <code>ext/json</code> is available in most PHP installs as well. If however we happen to be one of the few unfortunates who don't have and cannot get this extension, we should use <a href="http://pear.php.net/pepr/pepr-proposal-show.php?id=198"><code>Services_JSON</code></a> instead.</p>

<h2>Install it!</h2>

<p>CouchDB installations are available in most Linux and Unix distributions. On MacOSX, get <a href="http://janl.github.com/couchdbx/">CouchDBX</a> &mdash; <em>the one-click CouchDB package</em>, and there's a work in process for <a href="http://people.apache.org/~mhammond/dist/0.10.0/">Windows</a> as well. Especially interesting for those who run Ubuntu 9.10 (which has been released a few days ago), there's already a CouchDB install included.</p>

<p>Ubuntu/Debian:</p>

<pre><code>apt-get install couchdb
</code></pre>

<p>FreeBSD:</p>

<pre><code>cd /usr/ports/databases/couchdb &amp;&amp; make install clean
</code></pre>
 <br /><a href="http://till.klampaeckel.de/blog/archives/74-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-I.html#extended">Continue reading "PHP: So you'd like to migrate from MySQL to CouchDB? - Part I"</a>
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=7KxIzlVfCg0:Ve2qktRYLeo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=7KxIzlVfCg0:Ve2qktRYLeo:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=7KxIzlVfCg0:Ve2qktRYLeo:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=7KxIzlVfCg0:Ve2qktRYLeo:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=7KxIzlVfCg0:Ve2qktRYLeo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=7KxIzlVfCg0:Ve2qktRYLeo:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/7KxIzlVfCg0" height="1" width="1"/>]]></content:encoded>

    <pubDate>Sat, 31 Oct 2009 11:59:00 +0100</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/74-guid.html</guid>
    <category>couchdb</category>
<category>database</category>
<category>mysql</category>
<category>pear</category>
<category>php</category>
<category>zend-framework</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/74-PHP-So-youd-like-to-migrate-from-MySQL-to-CouchDB-Part-I.html</feedburner:origLink></item>
<item>
    <title>Dear Wordpress'rs, or, What is GPL?</title>
    <link>http://feedproxy.google.com/~r/till/~3/s3v8h6ZJAx4/73-Dear-Wordpressrs,-or,-What-is-GPL.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/73-Dear-Wordpressrs,-or,-What-is-GPL.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=73</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=73</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>Not sure if anyone has watched this yet, but <a href="http://ma.tt/2009/10/matt-qa-wordpress-gpl/">Matt's latest video</a> contains important misconceptions about the GPL.</p>

<p>Matt says (5:22):</p>

<p><em><blockquote>
So a common misconception about the GPL is that, like let's say, I'm hired to make a theme for a client.
Does that theme fall under the GPL? And the answer is, no!
Because it's not being distributed.
Uhm, when something is distributed it's available for download to the public, you're selling it in a store, you know, it's sort of mass-distribution.
When you do something for one site, or just for yourself, like for example, the theme on my blog, it's just for one site. It's not being distributed in any way.
The GPL doesn't kick in.
</blockquote></em></p>

<h2>But the GPL kicks in.</h2>

<p>First off, whenever you base your work on GPL code it becomes GPL. Matt also agrees on that (if you watch the entire video).</p>

<p>The questionable part is:</p>

<ul>
<li><strong>Is distribution really a requirement?</strong> Or is it GPL right from the start?</li>
<li>How do you define distribution?</li>
</ul>

<p>First off, I could not figure out the distribution requirement, but if in doubt, I think it is not a requirement for your code to become GPL. This is indeed what a lot of people describe as a loophole in the GPL and this is why the AGPL was invented.</p>

<p>Furthermore, what <strong>Matt</strong> thinks distribution is ("available for download to the public, you're selling it in a store"), <strong>is wrong</strong>. It does not matter if the code is <strike>distributed</strike> given to a friend, client, your grandmother or someone riding the subway with you. It's always GPL.</p>

<p>What I agree on is, that the GPL does not force anyone to distribute their code, or changes to GPL code.</p>

<p>In the end, the bottom line is: When the code is <em>given away</em>, it is GPL &mdash; the license applies!</p>

<h2>AGPL vs GPL</h2>

<p>I've previously blogged about the differences of the GPL to <a href="http://till.klampaeckel.de/blog/archives/50-Forced-contribution.html">AGPL</a>. The fundamental difference is that when GPL code allowed anyone to make changes and they could keep the changes to themselves, the AGPL requires them to contribute those changes to the project. In today's world, and with the nature of most of the software and its environment, it's virtually impossible (or illegal) to not contribute them back.</p>

<h2>Conclusion</h2>

<p></p>

<p>The GPL really means that whenever Matt <strong>decides</strong> to give his theme away (<em>for money</em>, or <em>for free</em>), he will have to provide the full sources of it, etc.. So for example, Matt couldn't use an encoder to hide his secret PHP code and then offer it for download.</p>

<p>And that is all.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=s3v8h6ZJAx4:eoq6t5Fyat8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=s3v8h6ZJAx4:eoq6t5Fyat8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=s3v8h6ZJAx4:eoq6t5Fyat8:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=s3v8h6ZJAx4:eoq6t5Fyat8:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=s3v8h6ZJAx4:eoq6t5Fyat8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=s3v8h6ZJAx4:eoq6t5Fyat8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/s3v8h6ZJAx4" height="1" width="1"/>]]></content:encoded>

    <pubDate>Thu, 29 Oct 2009 20:07:00 +0100</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/73-guid.html</guid>
    <category>affero</category>
<category>gpl</category>
<category>license</category>
<category>php</category>
<category>wordpress</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/73-Dear-Wordpressrs,-or,-What-is-GPL.html</feedburner:origLink></item>
<item>
    <title>Introducing TillStore</title>
    <link>http://feedproxy.google.com/~r/till/~3/kZ9CGGwDkBg/72-Introducing-TillStore.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/72-Introducing-TillStore.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=72</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=72</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p><strong>Update, 2009-10-24:</strong> <em>Fixed a bug, and committed a couple other improvements &mdash; TillStore 0.2.0 is released!</em></p>

<p>I went to <a href="http://nosqlberlin.de/">nosqlberlin</a> last week and I got inspired. I listened to a lot of interesting talks &mdash; most notably about Redis, CouchDB, Riak and MongoDB (<em>I'm omitting two talks, which of course were not less awesome than the rest!</em>) Due to an unfortunate circumstance I had six hours to hack on stuff from Thursday to Friday.</p>

<p>And here it is &mdash; I'm proud to present my very own approach to key-value stores: <strong>TillStore</strong>!</p>

<h2>What is a key-value store?</h2>

<p>In a nutshell, a key-value store is a database for values (Doh!). There are no duplicates, it's always a key mapped to a value. No bells and whistles &mdash; most just want to be fast. Eventually consistent is another attribute which most of them like to claim for themselves. The value term (in key-value store) is very flexible. Some key-value stores only support certain types, TillStore supports them all through JSON. ;-)</p>

<p>Other examples for key-value stores include <a href="http://riak.basho.com/">Riak</a>, <a href="http://code.google.com/p/redis/">Redis</a>, <a href="http://incubator.apache.org/cassandra/">Cassandra</a> and <a href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a>.</p>

<h2>TillStore?</h2>

<p>So vain, right? Well, in the beginning TillStore was an inside joke with a colleague. And to be honest, TillStore was nothing more but the following:</p>

<pre><code>&lt;?php
$tillStore = array();
?&gt;
</code></pre>

<p>However, when I had time to hack away on Thursday night, I took it a slightly higher level. ;-)</p>
 <br /><a href="http://till.klampaeckel.de/blog/archives/72-Introducing-TillStore.html#extended">Continue reading "Introducing TillStore"</a>
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=kZ9CGGwDkBg:mt-9jtW0rhk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=kZ9CGGwDkBg:mt-9jtW0rhk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=kZ9CGGwDkBg:mt-9jtW0rhk:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=kZ9CGGwDkBg:mt-9jtW0rhk:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=kZ9CGGwDkBg:mt-9jtW0rhk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=kZ9CGGwDkBg:mt-9jtW0rhk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/kZ9CGGwDkBg" height="1" width="1"/>]]></content:encoded>

    <pubDate>Sat, 24 Oct 2009 04:35:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/72-guid.html</guid>
    <category>database</category>
<category>performance</category>
<category>php</category>
<category>tillstore</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/72-Introducing-TillStore.html</feedburner:origLink></item>
<item>
    <title>Small notes on CouchDB's views</title>
    <link>http://feedproxy.google.com/~r/till/~3/_rnWIA-8kf4/61-Small-notes-on-CouchDBs-views.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/61-Small-notes-on-CouchDBs-views.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=61</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=61</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>I've been wrestling with a couple views in CouchDB currently. This blog post serves as mental note to myself, and hopefully to others. As I write this, i'm using <code>0.9.1</code> and <code>0.10.0</code> in a production setup.</p>

<p>Here's the environment:</p>

<ul>
<li>Amazon AWS L Instance (<a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1951&amp;categoryID=101">ami-eef61587</a>)</li>
<li>Ubuntu <code>9.04</code> (<em>Jaunty</em>)</li>
<li>CouchDB <code>0.9.1</code> and <code>0.10.0</code></li>
<li>database size: <code>199.8 GB</code></li>
<li>documents: <code>157408793</code></li>
</ul>

<h2>On to the tips</h2>

<p>These are some small pointers which I gathered by reading different sources (<a href="http://wiki.apache.org/couchdb/">wiki</a>, mailing list, IRC, <a href="http://planet.couchdb.org/">blog posts</a>, <a href="http://jan.prima.de/plok/">Jan</a> ...). All those revolve around views and what not with a relatively large data set.</p>

<h3>Do you want <em>the</em> speed?</h3>

<p>Building a view on a database of this magnitude will take a while.</p>

<p>In the beginning I estimated about week and a half. And it really took that long.</p>

<p>Things to consider, always:</p>

<ul>
<li>upgrade to trunk ;-) (or e.g. to <code>0.10.x</code>)</li>
<li>view building is CPU-bound which leads us to <em>MOAR</em> hardware &mdash; a larger instance</li>
</ul>

<p>The bottom line is, "Patience (really) is a virtue!". :-)</p>

<p><em>A side-note on upgrading: Double-check that upgrading doesn't require you to rebuild the views. That is, unless you got time.</em></p>

<h3>View basics</h3>

<p>When we initially tested if CouchDB was made for us we started off with a bunch off <code>emit(doc.foo, doc)</code>-like map functions in (sometimes) temporary views. On the production data, there are a few gotcha's.</p>

<p>First off &mdash; the obvious: temporary views are slow.</p>

<h4>Back to JavaScript</h4>

<p>Emitting the complete document will force CouchDB to duplicate data in the index which in return needs more space and also makes view building a little slower. Instead it's suggested to always <code>emit(doc.foo, null)</code> and then <code>POST</code> with multiple keys in the body to retrieve the documents.</p>

<p>Reads are cheap, and if not, get a cache.</p>

<h4>doc._id</h4>

<p>In case you wonder why I don't do <code>emit(doc.foo, doc._id)</code>? Well, that's because CouchDB is already kind enough to retrieve the document's ID anyway. (Sweet, no?)</p>

<h4>include_docs</h4>

<p>Sort of related, CouchDB has a <code>?include_docs=true</code> parameter.</p>

<p>This is really convenient &mdash; especially when you develop the application.</p>

<p>I gathered from various sources that using them bears a performance penalty. The reason is that <code>include_docs</code> issues another b-tree lookup for every row returned in the initial result. Especially with larger sets, this may turn into a bottleneck, while it can be considered <em>OK</em> with smaller result sets.</p>

<p>As always &mdash; don't forget that <code>HTTP</code> itself is relatively cheap and a single <code>POST</code> request with multiple keys (e.g. document IDs) in the body is likely not <strong>the</strong> bottleneck of your operation &mdash; compared to everything else.</p>

<p>And if you really need to optimize that part, there's always caching. :-)</p>

<h4>Need a little more?</h4>

<p>Especially when documents of different types are stored into the same database (Oh, the beauty of document oriented storage!), one should consider the following map-example:</p>

<pre><code>if (doc.foo) {
    emit(doc.foo, null)
}
</code></pre>

<p><code>.foo</code> is obviously an attribute in the document.</p>

<h4>JavaScript vs. Erlang</h4>

<p><code>sum()</code>, I haven't found too many of these &mdash; but with version 0.10+, the CouchDB folks implemented a couple JavaScript functions in Erlang, which is an easy replacement and adds a little speed on top. :-) So in this case, use <code>_sum</code>.</p>

<h3>Compact</h3>

<p>Compact, I learned, knows how to resume. So even if you kill the process, it'll manage to resume where it left off before.</p>

<p>When you populate a database through bulk writes, the gain from a compact is relatively small and is probably neglectable. Especially because compacting a database takes a long while. Keep in mind that compaction is disk-bound, which is often one of the final and inevitable bottlenecks in many environments. Unless hardware is designed ground up, this will most likely suck.</p>

<p>Compaction can have a larger impact when documents are written one by one to a database, or a lot of updates have been committed on the set.</p>

<p>I remember that when I build another set with 20 million documents one by one, I ended up with a database size of 60 GB. After I compacted the database, the size dropped to 20 GB. I don't have the numbers on read speed and what not, but it also <em>felt</em> more speedy. ;-)</p>

<h2>Fin</h2>

<p>That'd be it. More next time!</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=_rnWIA-8kf4:qH5lFx2SIoc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=_rnWIA-8kf4:qH5lFx2SIoc:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=_rnWIA-8kf4:qH5lFx2SIoc:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=_rnWIA-8kf4:qH5lFx2SIoc:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=_rnWIA-8kf4:qH5lFx2SIoc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=_rnWIA-8kf4:qH5lFx2SIoc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/_rnWIA-8kf4" height="1" width="1"/>]]></content:encoded>

    <pubDate>Wed, 21 Oct 2009 21:05:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/61-guid.html</guid>
    <category>aws</category>
<category>couchdb</category>
<category>development</category>
<category>documentation</category>
<category>performance</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/61-Small-notes-on-CouchDBs-views.html</feedburner:origLink></item>
<item>
    <title>Thoughts on RightScale</title>
    <link>http://feedproxy.google.com/~r/till/~3/gquXOvm44wE/64-Thoughts-on-RightScale.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/64-Thoughts-on-RightScale.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=64</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=64</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>RightScale provides all kinds of things &mdash; from a pre-configured MySQL master-slave setup (with automatic EBS/s3 backups), to a full LAMP stack, Rails app servers, virtually all kinds of <em>other</em> pre-configured server templates to a nifty auto-scaling feature.</p>

<p><em>We</em> decided to leverage RightScale when we planned our move to <acronym title="Amazon Web Services">AWS</acronym> a couple months ago in order to not have to build everything ourselves. I've been writing this blog entry for the past five weeks and here are some observations, thoughts and tips.</p>

<h2>RightScale</h2>

<p>First off, whatever you think, and do, or have done so far, let me assure you, there's <em>always</em> a RightScale way of doing things. For (maybe) general sanity (and definitely your own), I suggest you don't do it their way &mdash; always.</p>

<p>One example for <em>the</em> RightScale way is, that all the so-called RightScripts will attempt to start services on reboot for you, instead of registering them with the init system (e.g., on Ubuntu, <code>update-rc.d foo defaults</code>) when they are set up.</p>

<p>You may argue that RightScale's attempt will provide you with a maybe more detailed protocol of what happened during the boot sequence, but at the same time it provides more potential for errors and introduces another layer around what the operating system provides, and what generally works pretty well already.</p>

<h2>PHP <em>and</em> RightScale</h2>

<p>RightScale's sales team knows how to <em>charm</em> people, and when I say <em>charm</em>, <strong>I do not mean scam</strong> (just for clarity)! :-)</p>

<p>The demos are very impressive and the client show cases not any less. Where they really need to excel though are PHP-related demos because not everyone in the world runs Ruby on Rails yet. No, really &mdash; there's still us PHP people and also folks who run Python, Java and so on.</p>

<p>Coming from the sales pitch, I felt disappointed a little because a standard PHP setup on RightScale is as standard as you would think three years ago. <code>mod_php</code>, Apache2 and so on. The configuration itself is a downer as well, a lot of unnecessary settings and generally not so speedy choices. Then remember that <a href="http://till.klampaeckel.de/blog/archives/55-CouchDB-on-Ubuntu-on-AWS.html">neither CentOS nor Ubuntu are exactly up to date on packages</a> and add another constraint to the mix &mdash; Ubuntu is on 8.04 which is <strong>one and half years</strong> in the past as I write this entry.</p>

<p>And even though I can relate to RighScale's position &mdash; in terms of that supporting customers with all kinds of different software is a burden and messy to say the least &mdash; I am also not a fan.</p>

<h3>Scaling up</h3>

<p>The largest advantage when you select a service provider such as RightScale is, that they turn <em>raw</em> EC2 instances into usable servers out of the box. So far example setting up a lamp stack yourself requires time, while it's still a trivial task for many. With RightScale, it's a matter of a couple clicks &mdash; select image, start, provide input variables and done.</p>

<p>Aside from enhanced AMIs RightScale's advantage is auto-scaling. Auto-scaling has been done a couple times before. There are more than one service provider which leverages EC2 and provides <em>scalability</em> on top. Then take a look at <a href="http://code.google.com/p/scalr/">Scalr</a>, which is open source, and then recently Amazon themselves added their own Elastic Load Balancer.</p>

<p>In general, I think auto-scaling is something everyone gets, and wants, but of course it's not that dead simple to implement. And especially when you move to a new platform, it's a perfect trade off to sacrifice a flexibility and money for a warm and fuzzy "works out of the box" feeling.</p>
 <br /><a href="http://till.klampaeckel.de/blog/archives/64-Thoughts-on-RightScale.html#extended">Continue reading "Thoughts on RightScale"</a>
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=gquXOvm44wE:qRnYT1_oXYw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=gquXOvm44wE:qRnYT1_oXYw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=gquXOvm44wE:qRnYT1_oXYw:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=gquXOvm44wE:qRnYT1_oXYw:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=gquXOvm44wE:qRnYT1_oXYw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=gquXOvm44wE:qRnYT1_oXYw:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/gquXOvm44wE" height="1" width="1"/>]]></content:encoded>

    <pubDate>Tue, 20 Oct 2009 03:40:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/64-guid.html</guid>
    <category>aws</category>
<category>cloud computing</category>
<category>deployment</category>
<category>php</category>
<category>rightscale</category>
<category>setup</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/64-Thoughts-on-RightScale.html</feedburner:origLink></item>
<item>
    <title>Fan Error</title>
    <link>http://feedproxy.google.com/~r/till/~3/SmX1Tju4hPM/70-Fan-Error.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/70-Fan-Error.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=70</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=70</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>A <em>Fan Error</em> in this case is not when your Facebook fan page is down. I received this message after my Lenovo X61s notebook decided to quit and I restarted it. The screen said "Fan Error", and the notebook refused to continue to the boot process.</p>

<h2>A rescue party</h2>

<p>Of course this is the last thing you want on a Sunday evening, but in true <acronym title="Getting Things Done">GTD</acronym> fashion, I wanted to fix it right away. Here's how.</p>

<h3>Precaution</h3>

<p>In order to not electrocute myself, I removed the battery and unplugged the notebook.</p>

<h3>Get in there!</h3>

<p>I basically <em>unscrewed</em> every screw there is at the bottom of the notebook, until it would let me remove the upper part of the casing and keyboard.</p>

<p><a href="http://www.flickr.com/photos/till/4023969528/" title="FAN ERROR by illtillwillkillbill, on Flickr"><img src="http://farm3.static.flickr.com/2461/4023969528_3ff641aa0a.jpg" width="500" height="294" alt="FAN ERROR" /></a></p>

<p>Then I tried to carefully clean the inner of my notebook from dust and dirt that accumulated over the past 14 months since I purchased it. I think had dust (and what not) from North America, Europe and South America in there. <strike>It was kinda gross.</strike> It really didn't look pretty. And that is despite all efforts to not eat and drink near it.</p>

<h3>Fan</h3>

<p>When I got to the fan, it wouldn't really move. Hence the <em>fan error</em>!</p>

<p>I forced it a little and white dust came out of it. So I decided to take more drastic measures and sucked it clean using my <a href="http://www.amazon.de/Dyson-DC19-Origin-Staubsauger-Beutel/dp/B000PH4E82/ref=pd_ys_iyr_img?ie=UTF8&amp;coliid=I8FNFN7E13DMV&amp;colid=2RAPQ0AOQL6XX">Dyson</a>. In the beginning it wouldn't really move, but it took only a minute to resolve that. (<strong>Word of advice:</strong> If you are not super careful, the Dyson will try to suck in whatever it gets. So make sure to <strong>not</strong> vacuum the insides of your notebook. ;-))</p>

<h3>Reassembly</h3>

<p>Reassembly is pretty simple. The case clicks, and then you <em>fill in the screws</em>. IBM/Lenovo were smart enough to only use screws of the same type. There was a total of ten (or maybe nine), and they are all gone. So that must have worked.</p>

<h2>Conclusion</h2>

<p>Don't try this, unless you have to. And know what you are doing. This blog entry comes with no guarantees or extended warranty. <strong>Being able to <em>fix</em> little things yourself, feels good though.</strong></p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=SmX1Tju4hPM:kEu0lPqfwuw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=SmX1Tju4hPM:kEu0lPqfwuw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=SmX1Tju4hPM:kEu0lPqfwuw:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=SmX1Tju4hPM:kEu0lPqfwuw:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=SmX1Tju4hPM:kEu0lPqfwuw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=SmX1Tju4hPM:kEu0lPqfwuw:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/SmX1Tju4hPM" height="1" width="1"/>]]></content:encoded>

    <pubDate>Mon, 19 Oct 2009 00:05:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/70-guid.html</guid>
    <category>error</category>
<category>fan</category>
<category>howto</category>
<category>ibm</category>
<category>laptop</category>
<category>lenovo</category>
<category>notebook</category>
<category>x61s</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/70-Fan-Error.html</feedburner:origLink></item>
<item>
    <title>AddressLimitExceeded: Too many addresses allocated</title>
    <link>http://feedproxy.google.com/~r/till/~3/KyetJ2w8IX0/68-AddressLimitExceeded-Too-many-addresses-allocated.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/68-AddressLimitExceeded-Too-many-addresses-allocated.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=68</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=68</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>I got this error message tonight when I tried to allocate another <acronym title="Elastic IP">EIP</acronym> from within RightScale's dashboard. So it turns out there is a maximum of 5 (E)IPs on all AWS accounts, but there's <a href="http://aws.amazon.com/contact-us/eip_limit_request/">a contact form to request more</a>. Meh.</p>

<p>I wish AWS would make this part <em>slightly</em> easier, e.g. by announcing a customer's own IP space.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=KyetJ2w8IX0:pGCH2mAutMg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KyetJ2w8IX0:pGCH2mAutMg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KyetJ2w8IX0:pGCH2mAutMg:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=KyetJ2w8IX0:pGCH2mAutMg:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KyetJ2w8IX0:pGCH2mAutMg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=KyetJ2w8IX0:pGCH2mAutMg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/KyetJ2w8IX0" height="1" width="1"/>]]></content:encoded>

    <pubDate>Tue, 13 Oct 2009 20:10:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/68-guid.html</guid>
    <category>aws</category>
<category>random</category>
<category>rightscale</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/68-AddressLimitExceeded-Too-many-addresses-allocated.html</feedburner:origLink></item>
<item>
    <title>DevHouseBerlin aftermath!</title>
    <link>http://feedproxy.google.com/~r/till/~3/C3d-vZr4eVg/67-DevHouseBerlin-aftermath!.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/67-DevHouseBerlin-aftermath!.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=67</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=67</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>This year's <a href="http://devhouseberlin.de">DevHouseBerlin</a> is almost over, and this is what I managed to do.</p>

<h2>Planet-PHP</h2>

<p>Planet-PHP's code has been opensourced for a while and when I started setting up a planet for <a href="http://pear.php.net/">PEAR</a> I wasn't exactly happy with what it did. Aside from the obvious PHP4 vs. PHP5 issues, the unfortunate lack of documentation, I don't understand why anyone wants to transform an XSL with PHP, to generate PHP. And the bottom line, it didn't work <em>always</em> and I didn't want to debug it any longer.</p>

<p>The notable features include:</p>

<ul>
<li>Restructured the code to only expose what is necessary in the document root.</li>
<li>Fixed/improved configuration handling.</li>
<li>Extended/improved templating.</li>
<li>Code cleanup, where <em>possible</em>.</li>
<li>Fancy URLs and front controller pattern using Net_URL_Mapper! :-)</li>
<li>Webbased admin to add and remove feeds to the planet.</li>
</ul>

<p>Long story short &mdash; the code is on <a href="http://github.com/till/planet-php">github</a>. It's semi-complete, on the list of things to do are removing the libraries which became obsolete, a (new) submit form, a cache and maybe re-writing the importer/aggregate script.</p>

<p>Also, kudus to <a href="http://cweiske.de/">Christian Weiske</a> for contributing the admin and generally helping out. :-)</p>

<h2>Scr.im</h2>

<p>scr.im is a nifty service which allows you to spam protect your email address. So, for example, instead of display <code>name@example.org</code> on your website, you'd provide a link where people enter a captcha to see your email address. I know this is not compliant with the German law and what not, but I wrote a service wrapper for their API anyway. <strike>I'll put it online when I find time.</strike> The code is on <a href="http://github.com/till/Services_Scrim">Github</a>, check the README for an example.</p>

<h2>Net_URL_Mapper</h2>

<p>I never had a chance to explore <a href="http://pear.php.net/package/Net_URL_Mapper">Net_Url_Mapper</a> before and I must say, this is definitately one of the (many) raw diamonds in PEAR. <em>Raw</em> because its lack of documentation is not exactly helpful when it comes to adoption. Since I spent some time with the package on the Planet-PHP rewrite, I decided to contribute documentation. If you're anxious to check it out, follow this <a href="http://ucommbieber.unl.edu/peardoc/build/en/pear_manual_en/package.networking.net-url-mapper.html">link</a>, or wait until next week when the manual on the official website is updated.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=C3d-vZr4eVg:nMbttpe1h1o:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=C3d-vZr4eVg:nMbttpe1h1o:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=C3d-vZr4eVg:nMbttpe1h1o:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=C3d-vZr4eVg:nMbttpe1h1o:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=C3d-vZr4eVg:nMbttpe1h1o:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=C3d-vZr4eVg:nMbttpe1h1o:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/C3d-vZr4eVg" height="1" width="1"/>]]></content:encoded>

    <pubDate>Sun, 04 Oct 2009 18:02:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/67-guid.html</guid>
    <category>berlin</category>
<category>devhouseberlin</category>
<category>pear</category>
<category>php</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/67-DevHouseBerlin-aftermath!.html</feedburner:origLink></item>
<item>
    <title>Mobilcom-Debitel-Spass</title>
    <link>http://feedproxy.google.com/~r/till/~3/IibvGDoUtNI/65-Mobilcom-Debitel-Spass.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/65-Mobilcom-Debitel-Spass.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=65</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=65</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p><em>[English: German content ahead. ;-)]</em></p>

<p>Habe eben bemerkt, dass der Mobilfunkanbieter meines Vertrauens (die Mobilcom) jetzt zu Debitel geh&ouml;rt, oder anders herum. Auf jeden Fall hat sich im Zuge dieser gro&szlig;artigen Fusion der Kundenbereich der Login grundlegend ge&auml;ndert &mdash; <strike>anscheinend habe ich jetzt einen Benutzername</strike>ich muss mich mit meinem Benutzername einloggen.</p>

<h2>Auf zum Benutzernamen</h2>

<p>Der theoretische Weg zum Benutzernamen (und neuem Passwort) ist wie folgt:</p>

<ul>
<li>Ich gebe meine Telefonnummer in ein Formular ein und bekomme daf&uuml;r die Kundennummer per Email zugeschickt. <strike>Wohin weiss ich nicht.</strike> Zum Gl&uuml;ck hatte ich da bereits eine Emailadresse hinterlegt.</li>
<li>Danach gebe ich die Kundennummer und meine Telefonnummer in das n&auml;chste Formular ein und bekomme danach meinen Benutzername zugeschickt.</li>
<li>Dann gebe ich meine meine Kundennummer und meine Telefonnummer in das n&auml;chste Formular ein um ein neues Passwort per SMS zugesendet zu bekommen.</li>
</ul>

<p>Und dann kann ich mich schon einloggen!</p>

<h2>&Auml;h, ja.</h2>

<p>Die Fragen die sich zu diesem Vorgang stellen sind:</p>

<ul>
<li>Warum habe ich jetzt einen Benutzernamen?</li>
<li>Sind Telefonnummern nicht eindeutig genug?</li>
<li>Wof&uuml;r brauche ich eigentlich eine Kundennummer?</li>
<li>Wieso kommen alle Daten nicht per Email oder per SMS?</li>
</ul>

<p>Spontan ergibt sich sich hier die eine oder andere kleine Rationalisierungsma&szlig;nahme.</p>

<h2>Und sonst?</h2>

<p>Ich bin bereits im zweiten Schritt gescheitert &mdash; der Benutzername hat sein Ziel nie erreicht. Au&szlig;erdem gab's auch noch zuf&auml;llig jene Meldung:</p>

<div align="center"><a href="http://www.flickr.com/photos/till/3975491090/" title="mobilcom-debitel-spass by illtillwillkillbill, on Flickr"><img src="http://farm4.static.flickr.com/3428/3975491090_5f247cf28d.jpg" width="500" height="254" alt="mobilcom-debitel-spass" /></a></div>

<p><em>Danke!</em></p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=IibvGDoUtNI:ZTEXeXWZnLA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=IibvGDoUtNI:ZTEXeXWZnLA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=IibvGDoUtNI:ZTEXeXWZnLA:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=IibvGDoUtNI:ZTEXeXWZnLA:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=IibvGDoUtNI:ZTEXeXWZnLA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=IibvGDoUtNI:ZTEXeXWZnLA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/IibvGDoUtNI" height="1" width="1"/>]]></content:encoded>

    <pubDate>Fri, 02 Oct 2009 22:48:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/65-guid.html</guid>
    <category>debitel</category>
<category>mobilcom</category>
<category>random</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/65-Mobilcom-Debitel-Spass.html</feedburner:origLink></item>
<item>
    <title>Snow Leopard and WIFI</title>
    <link>http://feedproxy.google.com/~r/till/~3/ZJYTv1jV43o/62-Snow-Leopard-and-WIFI.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/62-Snow-Leopard-and-WIFI.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=62</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=62</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>I updated my mother's Mac Mini from Tiger to Snow Leopard last night and I did not enounter <em>many</em> issues during the one-hour-long installation (or update) process.</p>

<p>In advance &mdash; in order to be save than sorry &mdash; we had bought an external hard drive and did a backup of her home folder (6 GB &mdash; I wish my own backup was that size ;-)).</p>

<p>The one thing I ran into was that after the installation finished, I tried to reconnect to our wifi &mdash; but if failed. It wouldn't even show the network.</p>

<p>Since I knew that hooking up the Mini using a cable required me to move everything from her desk in one room to another room, I gave up last night and had myself a beer instead.</p>

<h2>A solution</h2>

<p>This morning, I briefly researched the issue on Google and found <a href="http://discussions.apple.com/thread.jspa?threadID=2138705&amp;tstart=0">a thread on apple.com</a> where people suggested to do the following:</p>

<ul>
<li>Go into System preferences > Network</li>
<li>Click on Airport</li>
<li>Delete the "Automatic location" profile</li>
<li>Add your own</li>
<li>Disable/enable Airport</li>
<li>Done</li>
</ul>

<p>Well, that almost worked for me.</p>

<p>I also re-added our wifi to the preferred network list and we were instantly reconnected.</p>

<h2>Anything else?</h2>

<p>Aside from the wifi issues almost everything migrated without issues.</p>

<p>This is still a pre-Intel Mac Mini. All her email, pictures and documents are in place. The only thing I need to reinstall is something called <em>Kodak Easy Share</em> since whatever she has installed doesn't seem to work right now.</p>

<p>And as a bonus, Snow Leopard feels faster even on this aging little piece of technology.</p>

<p>Anyway, I just thought I'd share.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=ZJYTv1jV43o:7ElfD0UxXS0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=ZJYTv1jV43o:7ElfD0UxXS0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=ZJYTv1jV43o:7ElfD0UxXS0:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=ZJYTv1jV43o:7ElfD0UxXS0:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=ZJYTv1jV43o:7ElfD0UxXS0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=ZJYTv1jV43o:7ElfD0UxXS0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/ZJYTv1jV43o" height="1" width="1"/>]]></content:encoded>

    <pubDate>Sun, 27 Sep 2009 15:22:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/62-guid.html</guid>
    <category>apple</category>
<category>installation</category>
<category>snow leopard</category>
<category>wifi</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/62-Snow-Leopard-and-WIFI.html</feedburner:origLink></item>
<item>
    <title>A case for PEAR and PHP4 (Or, why BC is important!)</title>
    <link>http://feedproxy.google.com/~r/till/~3/JynpECatCo0/60-A-case-for-PEAR-and-PHP4-Or,-why-BC-is-important!.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/60-A-case-for-PEAR-and-PHP4-Or,-why-BC-is-important!.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=60</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=60</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>Every once in someone likes to argue that PEAR is all <em>fugly</em> PHP4 code and why you should not use it, and instead go and use another framework or component library. Most of those people also say that they looked at or used PEAR  <em>x years ago</em> and then act all surprised when someone else disagrees.</p>

<p>In related (BC) news, most people probably read my blog because of Zend Framework, and I remember that one of the reasons I <em>sold</em> my clients on Zend Framework was a supposedly backward compatibility and clean API. Well, a couple years later one knows <em>it's not all that</em> and since another BC break was argued today on one of the mailing lists <strong>and</strong> the project lead said <a href="http://twitter.com/weierophinney/status/4177024376">I spread</a> <acronym title="fear, uncertainty, doubt">fud</acronym>, I felt l needed to write something on the topic. </p>

<p>Facts first.</p>

<h2>A small history of PEAR.</h2>

<p>I don't know how old exactly PEAR is, but the manual is copyrighted since 2001 and none of the other current frameworks have been around eight &mdash; almost nine &mdash; years.</p>

<p>Because PEAR has been around much longer, we also have more older code than any of those PHP5-only frameworks. In comparison, Zend Framework's first stable was release in June, 2007, almost six years later.</p>

<h2>Major versus minor releases.</h2>

<p>A package' version consists of <strong>x.y.z</strong>.</p>

<p>The rules are as follow:</p>

<ul>
<li>A BC break (see below) &mdash; increment <strong>x</strong>, and set <strong>y</strong> and <strong>z</strong> to 0.</li>
<li>Adding a new feature &mdash; keep <strong>x</strong>, increment <strong>y</strong> and set <strong>z</strong> to 0.</li>
<li>Fixing a bug &mdash; keep <strong>x</strong> and <strong>y</strong>, but increment <strong>z</strong>.</li>
</ul>

<p>When someone refers to a major release in PEAR's context (and a lot of other projects such as Zend Framework, Solar and ezComponents follow this), it's one with a change in <strong>x</strong>. :-)</p>

<h2>What is backward compatibility?</h2>

<p>Backward compatibility, or BC, describes that a component, package or library preserves compatibility with an older versions.</p>

<p>Because programming itself and developers tend to evolve, PEAR tries to keep BC in all minor versions, but allows you to break compatibility to an earlier version with a new major release.</p>

<p>The exception to the rule is that you may break BC during <em>alpha</em> and <em>beta</em> releases <strong>before</strong> the package reaches a stable 1.0.0.  Once a 1.0.0 is reached, BC may not be broken &mdash; for whatever reason.</p>

<h2>PHP4?</h2>

<p>Because PEAR aims to provide BC all the way, BC includes the PHP version when the package was first released. Which in turn means that of course you may make the code compatible to a later PHP release, but not without breaking compatibility to the initial release.</p>

<p>If you followed the above, you understand the reason why for example there is a <code>Mail_Queue</code> and (a soon to be) <code>Mail_Queue2</code>, or more importantly: why the <code>Mail_Queue</code> release in 2009 is still compatible to PHP4. Even though PHP4 <acronym title="end of life">EOL'd</acronym> a while ago.</p>

<p>The first <code>Mail_Queue</code> package was released in September of 2002, the 1.0.0 stable release followed in December of the same year. Because its <code>1.0.0</code> was compatible with PHP4, we keep it backwards compatible with PHP4 until we release <code>Mail_Queue2-0.1.0</code>.</p>

<h2>A principal</h2>

<p>A lot of people argue that with the official end of life of PHP4, one should break BC anyway. But here is why you should not.</p>

<ul>
<li><p>Even though we all love to use PHP5, there is still a lot of PHP4 in the enterprise. And like it or not, many of those apps use PEAR, and not <em>your funky PHP5 framework</em>.</p></li>
<li><p>How do you keep so-called necessary and unnecessary BC breaks apart? From another point of you (which is not your own), there is always a necessary BC break to <strike>fix</strike> implement something else.</p></li>
<li><p>Because there is no such thing as small or acceptable BC breaks. There are BC breaks or there are none, it's one of those things that is black and white.</p></li>
</ul>

<h2>BC in other frameworks</h2>

<p>I know for a fact that ezComponents is very strict on BC. I cannot comment on Solar or Symfony, but at least in Solar's case, I'm assuming that adhere to BC as well since a some former PEAR developers are active and they also follow the PEAR Coding Standard in many respects.</p>

<h2>Zend Framework?</h2>

<p>A friend of mine said that if Zend Framework really kept BC, we would at <code>10.0.0</code> and not on <code>1.9.3</code>.</p>

<p>Reasons why Zend Framework likes to break BC, even though it advertises full BC:</p>

<ul>
<li><p>No versioning per components but per framework.</p></li>
<li><p>Missing peer review and QA leads to unstable code in a so-called stable release. (Which in turn also fakes the stability of the entire framework since it suggests that a component that was added a couple weeks ago is as stable as a component added in 2007.)</p></li>
<li><p>Because it fixes an "issue". (Biggest WTF of them all.)</p></li>
</ul>

<p>The issue in question, I'm not even sure what they were trying to fix. Supposedly some developers found it too hard or did not understand how to write an adapter for <code>Zend_Db</code> and someone committed a fix in the 1.9 tree/branch and apparently it was OK to break BC because it was the easier way out.</p>

<p>I haven't updated some projects since late 1.8.x because of these BC breaks because no one can tell me what the issue is and I don't have a day to debug my application to figure out where and how it breaks. This is annoying as hell, especially since they are supposed to be tailored to the business.</p>

<p>On a side-note, I know of a couple components (e.g. <code>Zend_Session</code>) which really deserve (!) a BC break and don't get one until 2.0. And I totally get why, but why is it OK in some cases? All BC breaks fix issues!</p>

<p>(Btw, as I finish this post, I see an email to <code>zf-contributor@</code> in my inbox where <em>someone</em> considers pulling the 1.9.3 release (because it obviously breaks BC). Guess I didn't spread that much FUD after all.)</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=JynpECatCo0:PT-SDH6DyuU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=JynpECatCo0:PT-SDH6DyuU:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=JynpECatCo0:PT-SDH6DyuU:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=JynpECatCo0:PT-SDH6DyuU:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=JynpECatCo0:PT-SDH6DyuU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=JynpECatCo0:PT-SDH6DyuU:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/JynpECatCo0" height="1" width="1"/>]]></content:encoded>

    <pubDate>Tue, 22 Sep 2009 20:48:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/60-guid.html</guid>
    <category>development</category>
<category>open-source</category>
<category>pear</category>
<category>php</category>
<category>qa</category>
<category>zend-framework</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/60-A-case-for-PEAR-and-PHP4-Or,-why-BC-is-important!.html</feedburner:origLink></item>
<item>
    <title>My first PHP Unconfernce</title>
    <link>http://feedproxy.google.com/~r/till/~3/KPTmyx3reiQ/59-My-first-PHP-Unconfernce.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/59-My-first-PHP-Unconfernce.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=59</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=59</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>I went to Hamburg last weekend to visit the <a href="http://www.php-unconference.de/">PHP Unconference</a>, which was probably my first conference ever. I've been to a couple barcamps and other smaller events, but anyway, this felt more like a <em>real</em> conference to me. That is, if I exclude <a href="http://www.ala.org/">ALA</a> and the various ad:tech's I had to go to.</p>

<p>The reasons why I usually avoid tech conferences include foremost the price tag (working for myself, I can technically label it as an expense, but I still have to pay for it), doubts that it'll be worth it in terms of <em>knowledge gained</em> and probably time. I tend to catch up with people outside of conferences (when they are in Berlin :-)) and that has worked well for me.</p>

<p>I'm glad I set all these things aside for Hamburg (and it was all too easy). A lot of people expressed how much they liked their (often 3rd) PHP Unconference, and I can second, or third that &mdash; job really well done. Ulf Wendel took it one step further, blogged and asked, <a href="http://blog.ulf-wendel.de/?p=266">"Is perfect too boring?"</a>, because everything worked out so well. I guess I would say, "No, it's not boring", and I'm inclined to add, "Thanks, it really felt like having a weekend off, yet I still learned something and met a ton of nice people (or connected online nicknames to real faces)!".</p>

<p>I can definitely see why people visit the PHP Unconference each year, and I'll be one of them next year! ;-)</p>

<p>As I said, I had a great time, both my topics were accepted too. One was merged with another PHP performance talk which was overbooked with PHP VIPs which is why I decided to listen to <a href="http://kore-nordmann.de/">Kore Nordmann's</a> talk on <a href="http://kore-nordmann.de/talks/09_09_couchdb_phpillow.pdf">CouchDB</a> instead, and the other one ("Deployment") &mdash; I <em>kind of</em> overslept. And I'm sorry about that! I'll make sure to avoid party, party Hamburg next year.</p>

<p><a href="http://docs.google.com/present/view?id=acnqdvn8rf7r_62fv7vpkfj">Here are the slides for my Zend Framework (performance) talk</a>, I hope you find them interesting:</p>

<iframe src="http://docs.google.com/present/embed?id=acnqdvn8rf7r_62fv7vpkfj&amp;size=m" frameborder="0" width="555" height="451"></iframe>

<p>The slides and speaker-notes contain&hellip;</p>

<ul>
<li>a small intro as of why I think it's worth while to get into the ring with it</li>
<li>hints and pointers on general PHP optimization</li>
<li>I detail on a couple components (e.g. things to look out for and how to overcome them)</li>
</ul>

<p>Make sure to check the speaker notes (using <a href="http://docs.google.com/present/view?id=acnqdvn8rf7r_62fv7vpkfj">this link</a>) &mdash; I didn't put everything in there, but a lot.</p>

<p>(The deployment slides will be up later this weekend.)</p>

<p><em><strong>This also reminds me to improve my presentation-fu. I need something as kickass as keynote, but for Windows (currently). If anyone has a pointer, let me know. ;-)</strong></em></p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=KPTmyx3reiQ:8cw6pPPhcIA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KPTmyx3reiQ:8cw6pPPhcIA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KPTmyx3reiQ:8cw6pPPhcIA:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=KPTmyx3reiQ:8cw6pPPhcIA:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=KPTmyx3reiQ:8cw6pPPhcIA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=KPTmyx3reiQ:8cw6pPPhcIA:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/KPTmyx3reiQ" height="1" width="1"/>]]></content:encoded>

    <pubDate>Fri, 18 Sep 2009 16:55:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/59-guid.html</guid>
    <category>performance</category>
<category>php</category>
<category>phpunconf</category>
<category>zend-framework</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/59-My-first-PHP-Unconfernce.html</feedburner:origLink></item>
<item>
    <title>Managing software deployments of your PHP applications II</title>
    <link>http://feedproxy.google.com/~r/till/~3/N20_L0v4j8A/53-Managing-software-deployments-of-your-PHP-applications-II.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/53-Managing-software-deployments-of-your-PHP-applications-II.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=53</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=53</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>This is not (really a part) two of my series, but an <em><a href="http://en.wikipedia.org/wiki/Intermezzo">Intermezzo</a> (<a href="http://www.youtube.com/watch?v=crrxk6ptsFc">1</a>)</em> between Part I and Part III &mdash; because I have no time to finish Part III.</p>

<p>In <a href="http://till.klampaeckel.de/blog/archives/11-Managing-software-deployments-of-your-PHP-applications-I.html">Part I</a>, I talked about my approach to deploying a website and I offered pear and subversion as solutions to the <em>problem</em>. To briefly elaborate on my subversion part, I want to share the following Capistrano recipe with you.</p>

<h2>Capistrano, isn't that Ruby?</h2>

<p>Yes it is! <a href="http://www.capify.org/index.php/Capistrano">Capistrano</a> is a nifty piece of software. Not because it's so super-duper complex, but because it's pretty robust and works really well.</p>

<p>I am sure everyone heard of the "the right tool for the job" theory and this is along those lines. Please don't be afraid of a little Ruby to ease the deployment process. (They don't deserve your fear anyway. ;-))</p>

<h3>Installation</h3>

<p>On FreeBSD:</p>

<pre><code>cd /usr/ports/devel/rubygem-capistrano &amp;&amp; make install clean
</code></pre>

<p>On Debilian/Ubuntu:</p>

<pre><code>apt-get install rubygems
gem install capistrano
</code></pre>

<p>Go on and create a <code>capfile</code> in <code>$HOME</code>, and this is where we'll keep our tasks.</p>
 <br /><a href="http://till.klampaeckel.de/blog/archives/53-Managing-software-deployments-of-your-PHP-applications-II.html#extended">Continue reading "Managing software deployments of your PHP applications II"</a>
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=N20_L0v4j8A:qeVOvp3dTx8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=N20_L0v4j8A:qeVOvp3dTx8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=N20_L0v4j8A:qeVOvp3dTx8:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=N20_L0v4j8A:qeVOvp3dTx8:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=N20_L0v4j8A:qeVOvp3dTx8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=N20_L0v4j8A:qeVOvp3dTx8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/N20_L0v4j8A" height="1" width="1"/>]]></content:encoded>

    <pubDate>Wed, 09 Sep 2009 17:20:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/53-guid.html</guid>
    <category>capistrano</category>
<category>deployment</category>
<category>howto</category>
<category>php</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/53-Managing-software-deployments-of-your-PHP-applications-II.html</feedburner:origLink></item>
<item>
    <title>Forced contribution</title>
    <link>http://feedproxy.google.com/~r/till/~3/z7qB0jgpRY0/50-Forced-contribution.html</link>
    
    <comments>http://till.klampaeckel.de/blog/archives/50-Forced-contribution.html#comments</comments>
    <wfw:comment>http://till.klampaeckel.de/blog/wfwcomment.php?cid=50</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://till.klampaeckel.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=50</wfw:commentRss>
    

    <author>nospam@example.com (Till Klampaeckel)</author>
    <content:encoded><![CDATA[
    <p>I'm not exactly neutral when it comes to anything remotely related to the GPL license. Personally, there's a bit of a GPL scare when I see code that's released under that license and I usually try to avoid it.</p>

<p>But (primarily) due to <a href="http://www.roundcube.net/">RoundCube</a> being licensed under the GPL, I think I do know what it entails to release code using this license. In addition to that I have read a lot about the license, I even <strike>wasted</strike> spent three hours one night to listen to <em>RMS</em>.</p>

<p>In the end &mdash; the GPL just did not grow on me, or made me happy.</p>

<h2>Open source</h2>

<p>I am a firm believer in open source. I release code for <em>free</em>. Whenever I have the choice, my free contributions include the freedom to really do whatever you want with my code. Because if I did not meant it, I would either sell the code, or not share it at all.</p>

<p>I recently read <a href="http://zedshaw.com/blog/2009-07-13.html">Zed Shaw's reasoning why he believes in the [A,L]GPL</a> and that same day I walked into yet another license discussion on <a href="http://pear.php.net/">PEAR</a>'s IRC channel (#pear@efnet), and I felt like I need to write it all out.</p>

<h2>The GPLs</h2>

<h3>GPL in a nutshell</h3>

<ul>
<li>The GPL means that whenever I use code that is licensed under it in my code, my code automatically becomes GPL too.</li>
<li>The GPL requires me to release the source code of the software when I give it to others [<em>them</em>].</li>
<li>The GPL allows <em>them</em> to give it to other people as well, license still applies.</li>
<li>(Contrary to popular believe, ) The GPL also allows me to sell software. I'm not required to give it away for free.</li>
</ul>

<p>If you still do not understand what the above means, here's an example: Wordpress. Wordpress is GPL and therefor all plugins written for Wordpress are GPL too. I realize some people may think that there might not be too much that you can do in a plugin, but if you wanted to make money of your work (plugin), the options are pretty limited.</p>

<h3>LGPL in a nutshell</h3>

<p>The LGPL is basically the same as the GPL, <strong>but</strong> if I use LGPL software inside my software, my software does not become GPL.</p>

<h3>Affero (L)GPL</h3>

<p>Because web software is often not distributed (think of <acronym title="Software As A Service">SAAS</acronym>), the GPL people came up with an Affero clause.</p>

<p>This clause <strong>requires you</strong> to open source your changes to a software/library even if it's only accessible through the network. In <em>plain</em> English &mdash; if you do SAAS (Remember, <em>plain</em> English!), or a simple website, and do not directly distribute your source code to your customer, you will still have to open source your changes because your customers can <em>access</em> it anyway.</p>

<p>The Affero clause is currently available as AGPL, and soon as ALGPL.</p>

<h2>Non-restrictive licensing</h2>

<p>When I speak of non-restrictive (or liberal :-)) licenses, I think of the (new) BSD, MIT and Apache licenses. In a nutshell, they all allow you to really do whatever you want. Whatever, of course except for removing the copyright on the source code.</p>

<ul>
<li>They do not force you to open source your changes to the code.</li>
<li>They do not force a license on your own code just because you happen to use it.</li>
<li>The do not force you to release the source code to your customers.</li>
</ul>

<p>Reading the above, one would see that these licenses are very compatible with typical business interests. They all come in handy for frameworks such as <a href="http://ezcomponents.org/">ezComponents</a> or the <a href="http://framework.zend.com/">Zend Framework</a> &mdash; and many <a href="http://pear.php.net/">PEAR</a> components use them as well. They really bring freedom of use the user, without imposing any duties on the user, and the best of all: <strong>the user can contribute anyway</strong>.</p>

<h2>Impose</h2>

<p>For a lot of people the world is black and white. You see other people benefiting from your own work hiding everywhere. And it's all too easy to find a license to impose your own beliefs on others. Because if they do not get it, there is a way to make them.</p>

<p>This rather simplified approach to a pretty complicated topic is easier to comprehend and therefor popular. And I can't blame anyone. Think further &mdash; religion. People who convert or find <em>a thing</em> for themselves easily become outspoken about and start preaching their new found happiness to others.</p>

<p>It's very human. <strong>If it makes you happy, you want to share.</strong></p>

<p>This is of course meant with no offense to people like Zed Shaw who feel like they did not get their share of the cake (even though &mdash; Hey Zed! &mdash; a ton of people run your software (Mongrel)). I do understand Zed's point of view though. Visibility in the open source world does not pay your monthly bills. I'm not naive like that. On the other hand, there are more than a few examples from the the open source world where a company is build around an open source product and the company offers services &mdash; such as consulting and support &mdash; for said product.</p>

<p>The bottom line for myself is that I do not like to force people to do something. And no one does, right? (<em>Except when the motives allow it!</em>)</p>

<h2>Conclusion</h2>

<p>I believe that more people will contribute to open source because they believe in the cause. Not because some license forces them to do so. A lot of people get into open source because they use(d) open source software already and decided to <em>contribute to the community</em>. A lot of commercial entities fund open source development &mdash; heck, for whatever reason, even Microsoft does it.</p>

<p>If anything, the Affero clause will cause is to hinder the adoption rates of the software in question. And that is not just because <strong>all these licenses are written in English which requires a law degree</strong>, but because when you manage to understand them, they impose a threat on your own intellectual property.</p>
 
    <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/till?a=z7qB0jgpRY0:yDKler6eEGg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/till?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=z7qB0jgpRY0:yDKler6eEGg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/till?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=z7qB0jgpRY0:yDKler6eEGg:DTerMVx4NQQ"><img src="http://feeds.feedburner.com/~ff/till?i=z7qB0jgpRY0:yDKler6eEGg:DTerMVx4NQQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/till?a=z7qB0jgpRY0:yDKler6eEGg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/till?i=z7qB0jgpRY0:yDKler6eEGg:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/till/~4/z7qB0jgpRY0" height="1" width="1"/>]]></content:encoded>

    <pubDate>Mon, 07 Sep 2009 16:45:00 +0200</pubDate>
    <guid isPermaLink="false">http://till.klampaeckel.de/blog/archives/50-guid.html</guid>
    <category>affero</category>
<category>bsd</category>
<category>gpl</category>
<category>license</category>
<category>open-source</category>
<category>random</category>

<feedburner:origLink>http://till.klampaeckel.de/blog/archives/50-Forced-contribution.html</feedburner:origLink></item>

</channel>
</rss>
