<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title>rubyonrails-ug.de Planet</title>
	<link rel="self" href="http://planet.rubyonrails-ug.de/atom.xml"/>
	<link href="http://planet.rubyonrails-ug.de"/>
	<id>http://planet.rubyonrails-ug.de/atom.xml</id>
	<updated>2012-02-05T12:20:31+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<entry xml:lang="en">
		<title type="html">We @ Wroc_❤.rb and we ❤ Vention Dention</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/Ol3dEtTj-6A/"/>
		<id>http://blog.railslove.com/?p=1222</id>
		<updated>2012-01-31T08:21:52+00:00</updated>
		<content type="html">&lt;p&gt;We&amp;#8217;re proud to announce &lt;a href=&quot;http://wrocloverb.com/&quot;&gt;wroc_love.rb 2012&lt;/a&gt;. The very first of such conferences in a beautiful city of Wrocław. What is this conference about?&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A fresh Ruby conference organized by thriving local Ruby community. We&amp;#8217;re keen on experimenting, value original ideas and diversity of opinions &amp;#8211; as long as they&amp;#8217;re backed with valid arguments.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;You can meet : &lt;a href=&quot;http://twitter.com/killerg&quot;&gt;Georg&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/bumi&quot;&gt;Bumi&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/holek_&quot;&gt;Mike&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/ralph&quot;&gt;Ralph&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/koos&quot;&gt;myself&lt;/a&gt; and our friend &lt;a href=&quot;http://twitter.com/apotnick&quot;&gt;Nick&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;We&amp;#8217;re giving a talk&lt;/h2&gt;
&lt;p&gt;What is our talk about? About.. &lt;em&gt;&amp;#8220;Pit .. Brad Pit..Pit&amp;#8217;s..ahhr! Just get out of the trap!!!&amp;#8221;&lt;/em&gt; In our talk we will share some of the most interesting, absurd, or funny moments and insights we have experienced in past couple of years. As developers and business founders, we present the best of our own mistakes and show you how we got out of the pits we fell into. Believe us, we’ve been there as well and, hopefully, attending our talk will help you not make our mistakes. ;) It will be a serious fun! The talk will cover both technical and other subjects. Each mistake will get a 2-3 min coverage. Read more about us and our talk at &lt;a href=&quot;http://wrocloverb.com/&quot;&gt;the conference page&lt;/a&gt; and on their &lt;a href=&quot;http://blog.wrocloverb.com/post/16577304388/railslove-salesking&quot;&gt;blog&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;We love punk rock&lt;/h2&gt;
&lt;p&gt;Did you know we have our own band? No? Ok&amp;#8230; now you know it! We&amp;#8217;re proud to indroduce you to&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;&lt;center&gt;Vention Dention&lt;/center&gt;&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Oh yeah. Vention Dention is on tour again&amp;#8230; and we&amp;#8217;re with them all the time. So the next gig&amp;#8217;s are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wroc_love.rb, 10.-11. March 2012, Wrocław, Instytut Informatyki, Uniwersytet Wrocławski&lt;/li&gt;
&lt;li&gt;Nodecamp.eu (Details coming soon)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;#8217;re planing some more gigs with them and everything will be announced on &lt;a href=&quot;http://vention-dention.de/&quot;&gt;their homepage&lt;/a&gt;, on &lt;a href=&quot;http://feeds.feedburner.com/vention-dention.railslove.com&quot;&gt;Railslove&amp;#8217;s Vention Dention Homepage&lt;/a&gt; and via &lt;a href=&quot;https://twitter.com/ventiondention&quot;&gt;Twitter (@ventiondention)&lt;/a&gt;. So stay tuned!&lt;/p&gt;
&lt;p&gt;For now, just for you&amp;#8230; Vention Dention:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div id=&quot;attachment_1230&quot; class=&quot;wp-caption aligncenter&quot;&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2012/01/vd.gif&quot;&gt;&lt;img src=&quot;http://blog.railslove.com/wp-content/uploads/2012/01/vd.gif&quot; alt=&quot;Vention Dention Logo Animated&quot; title=&quot;Vention Dention Logo Animated&quot; width=&quot;500&quot; class=&quot;size-full wp-image-1230&quot; /&gt;&lt;/a&gt;&lt;p class=&quot;wp-caption-text&quot;&gt;Vention Dention Logo Animated&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;See you @ wroc_love.rb!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ol3dEtTj-6A:zWysbXExqvU:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ol3dEtTj-6A:zWysbXExqvU:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ol3dEtTj-6A:zWysbXExqvU:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=Ol3dEtTj-6A:zWysbXExqvU:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">A Tour of Amazon's DynamoDB</title>
		<link href="http://www.paperplanes.de//2012/1/30/a-tour-of-amazons-dynamodb.html"/>
		<id>http://www.paperplanes.de//2012/1/30/a-tour-of-amazons-dynamodb.html</id>
		<updated>2012-01-30T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Amazon's &lt;a href=&quot;http://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html&quot;&gt;recent
release&lt;/a&gt; of
DynamoDB, a database whose name is inspired by &lt;a href=&quot;http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html&quot;&gt;Dynamo, the key-value
database&lt;/a&gt; the
distributed datastore they've been running in production for a good five to six
years now. I think it's great they've finally done it, though from my
obverservations, there's little resemblance of what the original Dynamo paper
describes, but I'm getting ahead of myself. Traditionally Amazon hasn't been
very open about how they implement their services, so some of what I'm stating
here may be nothing more than an educated guess. Either way, the result is
pretty neat.&lt;/p&gt;

&lt;p&gt;Time to take a good look at what it has to offer, how that works out in code,
and to make some wild guesses as to what's happening under the covers. I'm using
&lt;a href=&quot;http://github.com/fog/fog&quot;&gt;fog&lt;/a&gt;'s master to talk to DynamoDB in the examples
below, but the &lt;a href=&quot;http://aws.amazon.com/sdkforruby/&quot;&gt;official Ruby SDK&lt;/a&gt; also
works. Fog is closer to the bare API metal though, which works out well for our
purposes.&lt;/p&gt;

&lt;p&gt;My goal is not to outline the entire API and its full set of options, but to dig
into the bits most interesting to me and to show some examples. A lot of the
focus in other posts is on performance, scalability and operational ease.  I
think that's a great feature of DynamoDB, but it's pretty much the same with all
of their web services. So instead I'm focusing on the effects DynamoDB has on
you, the user. We'll look at API, general usage, data model and what DynamoDB's
feature generally entails.&lt;/p&gt;

&lt;h3&gt;The Basics&lt;/h3&gt;

&lt;p&gt;DynamoDB is a distributed database in the cloud, no surprises, it's not the
first such thing Amazon has in its portfolio. &lt;a href=&quot;http://aws.amazon.com/s3/&quot;&gt;S3&lt;/a&gt;,
&lt;a href=&quot;http://aws.amazon.com/simpledb/&quot;&gt;SimpleDB&lt;/a&gt;, &lt;a href=&quot;http://aws.amazon.com/rds/&quot;&gt;RDS&lt;/a&gt;
and &lt;a href=&quot;http://aws.amazon.com/dynamodb/&quot;&gt;DynamoDB&lt;/a&gt; all provide redudant ways to
store different types of data in Amazon's datacenters. Currently, DynamoDB
only supports the us-east region.&lt;/p&gt;

&lt;p&gt;An important difference is that data stored in DynamoDB is officially stored on
SSDs, which has (or at least should have) the benefit of offering predictable
performance and greatly reduced latency across the board. The question that
remains is, of course: when can I hook up SSDs to my EC2 instances?&lt;/p&gt;

&lt;p&gt;The other big deal is that the read and write capacity available to you is
configurable. You can tell Amazon how much capacity, in read and write units per
second, you expect for your application, and they make sure that capacity is
available to you as long as you need it (and pay for it).&lt;/p&gt;

&lt;h3&gt;Data Model&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/DataModel.html&quot;&gt;Data in DynamoDB&lt;/a&gt;
is stored in tables, a logical separation of data if you will. Table names are
only unique on a per-user basis, not globally like S3 buckets.&lt;/p&gt;

&lt;p&gt;Tables store items, think rows of data or documents. Items have attributes and
values, similar to SimpleDB. Think of it as a JSON document where you can read
and write attributes independent of the entire document. Every row can have
different attributes and values, but every item needs to have a uniquely
identifying key whose name you decide on upfront, when you create the table.&lt;/p&gt;

&lt;p&gt;Let's create a table first, but make sure you wear protection, as this is yet
another of Amazon's gross-looking APIs. The relevant API action is
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_CreateTable.html&quot;&gt;&lt;code&gt;CreateTable&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo = Fog::AWS::DynamoDB.new(aws_access_key_id: &quot;YOUR KEY&quot;,
  aws_secret_access_key: &quot;YOUR SECRET&quot;)

dynamo.create_table(&quot;people&quot;,
  {HashKeyElement: {AttributeName: &quot;username&quot;, AttributeType: &quot;S&quot;}},
  {ReadCapacityUnits: 5, WriteCapacityUnits: 5})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This creates a table called &lt;code&gt;&quot;people&quot;&lt;/code&gt; with an attribute &lt;code&gt;&quot;username&quot;&lt;/code&gt; as the
indexing key. This is the key you're using to reference a row, sorry, an item,
in a table. The key is of type string, hence the S, you can alternatively
specify an N for numeric values. This pattern will come up with every attribute
and value pair you store, you always need to tell DynamoDB if it's a string or a
number. You also specify initial values for expected read and write capacity,
where 5 is the minimum.&lt;/p&gt;

&lt;p&gt;You have to provide a proper value for a key, DynamoDB doesn't offer any
automatic generation of keys for you, so choose them wisely to ensure a good
distribution. A key, that has a lot of data behind it, and that's accessed much
more frequently than others will not benefit you. Keep your data simple and
store it with multiple keys if you can.&lt;/p&gt;

&lt;p&gt;Anyhoo, to insert an item, you can use the
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_PutItem.html&quot;&gt;&lt;code&gt;PutItem&lt;/code&gt;&lt;/a&gt;
API action, to which you issue a HTTP POST (go figure). The DynamoDB API already
gives me headache, but more on that later. Thankfully, a good client library
hides the terrible interface from us, only leaving us with the hash structures
sent to DynamoDB.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.put_item(&quot;people&quot;, {username: {&quot;S&quot; =&amp;gt; &quot;roidrage&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Specify multiple attributes as separate hash entries, each pointing to a
separate hash specifying data type and value. I'll leave it to you to think
about how backwards this is, though it must be said that JavaScript is also to
blame here, not handling 64 bit integers very well.&lt;/p&gt;

&lt;p&gt;You can store lists (or rather sets of data) too, using SS as the datatype.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.put_item(&quot;people&quot;, {username: {S: &quot;roidrage&quot;},
                               tags: {SS: [&quot;nosql&quot;, &quot;cloud&quot;]}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that you can use &lt;code&gt;PutItem&lt;/code&gt; on existing items, but you'll always replace all
existing attributes and values.&lt;/p&gt;

&lt;h3&gt;Conflicts and Conditional Writes&lt;/h3&gt;

&lt;p&gt;All writes can include optional conditions to check before updating an item.
That way you can ensure the item you're writing is still in the same state as
your local copy of the data. Think: read, update some attribute, then write,
expecting and ensuring to not have any conflicting updates from other clients in
between.&lt;/p&gt;

&lt;p&gt;This is a pretty neat feature, you can base updates on one attributes based on
whether another attribute exists or has a certain value.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.put_item(&quot;people&quot;,
    {username: {S: &quot;roidrage&quot;}, fullname: {S: &quot;Mathias Meyer&quot;}},
    {Expected: {fullname: {Exists: false}}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This operation is only executed if the item as currently stored in DynamoDB
doesn't have the attribute the attribute &lt;code&gt;fullname&lt;/code&gt; yet. On a subsequent
&lt;code&gt;PutItem&lt;/code&gt; call, you could also check if the item's &lt;code&gt;fullname&lt;/code&gt; attribute still
has the same value, e.g. when updating the full name of user &quot;roidrage&quot;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.put_item(&quot;people&quot;,
    {username: {S: &quot;roidrage&quot;}, fullname: {S: &quot;Mathias Meyer&quot;}},
    {Expected: {fullname: {Value: {S: &quot;Mathias Meyer&quot;}}}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's not the greatest syntax for sure, but it does the job. Which brings me to
some musings about consistency. If the condition fails, Amazon returns a 400
response, just like with every other possible error you could cause.&lt;/p&gt;

&lt;p&gt;To make proper use of conditional updates in your application and to actually
prevent conflicting writes and lost updates, you should use the &lt;code&gt;UpdateItem&lt;/code&gt;
action instead and only update single attributes, as &lt;code&gt;PutItem&lt;/code&gt; always replaces
the entire item in the database. But even then, make sure to always reference
the right attributes in an update. You could even implement some sort of
versioning scheme on top of this, for instance to emulate multi-version
concurrency control.&lt;/p&gt;

&lt;p&gt;Updating single or multiple attributes is done with the
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_UpdateItem.html&quot;&gt;&lt;code&gt;UpdateItem&lt;/code&gt;&lt;/a&gt; action.
You can update attributes without affecting others and add new attributes as you
see fit. To add a new attribute &lt;code&gt;street&lt;/code&gt;, here's the slightly more verbose code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
    {street: {Value: {S: &quot;Gabriel-Max-Str. 3&quot;}}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are more options involved than with &lt;code&gt;PutItem&lt;/code&gt;, and there are several more
available for &lt;code&gt;UpdateItem&lt;/code&gt;. But they'll have to wait for just a couple of
sentences.&lt;/p&gt;

&lt;h3&gt;Consistency on Writes&lt;/h3&gt;

&lt;p&gt;Conditional updates are the first hint that DynamoDB is not like Dynamo at all,
as they assume some sort of semi-transactional semantics. Wherein a set of nodes
agree on a state (the conditional expression) and then all apply the update. The
same is true for atomic counters, which we'll look at in just a minute.&lt;/p&gt;

&lt;p&gt;From the documentation it's not fully clear how writes without a condition or
without an atomic counter increment are handled, or what happens when two
clients update the same attribute at the same time, and who wins based on which
condition. Facing the user, there is no mechanism to detect conflicting writes.
So I can only assume DynamoDB either lets the last write win or has a scheme
similar to BigTable, using timestamps for each attribute.&lt;/p&gt;

&lt;p&gt;Writes don't allow you to specify something like a quorum, telling DynamoDB how
consistent you'd like the write to be, it seems to be up to the system to decide
when and how quickly replication to other datacenters is done. &lt;a href=&quot;http://nosql.mypopescu.com/post/16064274863/notes-about-amazon-dynamodb&quot;&gt;Alex Popescu's
summary&lt;/a&gt;
on DynamoDB and &lt;a href=&quot;http://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html&quot;&gt;Werner Vogels' introduction&lt;/a&gt;
suggest that writes are replicated across data centers synchronously, but
doesn't say to how many. On a wild guess, two data centers would make the write
durable enough, leaving the others to asynchronous replication.&lt;/p&gt;

&lt;h3&gt;Consistency on Reads&lt;/h3&gt;

&lt;p&gt;For reads on the other hand, you can tell DynamoDB if stale data is acceptable
to you, resulting in an eventually consistent read. If you prefer strongly
consistent reads, you can specify that on a per-operation basis. What works out
well for Amazon is the fact that strongly consistent reads cost twice as much as
eventually consistent reads, as more coordination and more I/O are involved.
From a strictly calculating view, strongly consistent write take up twice as
much capacity as eventually consistent writes.&lt;/p&gt;

&lt;p&gt;From this I can only assume that writes, unless conditional will usually be at
least partially eventually consistent or at least not immediately spread out to
all replicas. On reads on the other hand, you can tell DynamoDB to involve more
than just one or two nodes and reconcile outdated replicas before returning it
to you.&lt;/p&gt;

&lt;h3&gt;Reading Data&lt;/h3&gt;

&lt;p&gt;There's not much to reading single items. The action
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_GetItem.html&quot;&gt;&lt;code&gt;GetItem&lt;/code&gt;&lt;/a&gt; allows you to
read entire items or select single attributes to read.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.get_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Optionally, add the consistency option to get strong consistency, with eventual
consistency being the default.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.get_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                          {ConsistentRead: true})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A read without any more options always returns all data, but you can select
specific attributes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.get_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                          {AttributesToGet: [&quot;street&quot;]})
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Atomic Counters&lt;/h3&gt;

&lt;p&gt;Atomic counters are a pretty big deal. This is what users want out of pretty
much every distributed database. Some say they're using it wrong, but I think
they're right to ask for it. Distributed counters are hard, but not impossible.&lt;/p&gt;

&lt;p&gt;Counters need to be numerical fields, and you can increment and decrement them
using the &lt;code&gt;UpdateItem&lt;/code&gt; action. To increment a field by a value, specify a numerical
attribute, the value to be incremented by, and use the action &lt;code&gt;ADD&lt;/code&gt;. Note that
the increment value needs to be a string.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                             {logins: {Value: {N: &quot;1&quot;}, Action: &quot;ADD&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the counter attribute doesn't exist yet, it's created for you and set to 1.
You can also decrement values by specifying a negative value.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                             {logins: {Value: {N: &quot;-1&quot;}, Action: &quot;ADD&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Can't tell you how cool I think this feature is. Even though we keep telling
people that atomic counters in distributed system are hard, as they involve
coordination and increase vulnerability to failure of a node involved in an
operation, systems like Cassandra and HBase show that it's possible to do.&lt;/p&gt;

&lt;h3&gt;Storing Data in Sets&lt;/h3&gt;

&lt;p&gt;Other than numerical (which need to be specified as strings nonetheless) and
string data types, you can store sets of both too. One member can only exist
once in an attribute set. The neat part is that you can atomically add new
members to sets using the &lt;code&gt;UpdateItem&lt;/code&gt; action. In the JSON format sent to the
server, you always reference even just single members to add as a list of items.
Here's an example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                             {tags: {Value: {SS: [&quot;nosql&quot;]}}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That always replaces the existing attribute though. To add a member you need to
specify an action. If the member already exists, nothing happens, but the
request still succeeds.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                             {tags: {Value: {SS: [&quot;cloud&quot;]}, Action: &quot;ADD&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can delete elements in a similar fashion, by using the action &lt;code&gt;DELETE&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.update_item(&quot;people&quot;, {HashKeyElement: {S: &quot;roidrage&quot;}},
                             {tags: {Value: {SS: [&quot;cloud&quot;]}, Action: &quot;DELETE&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The default action is &lt;code&gt;PUT&lt;/code&gt;, which replaces the listed attributes with the
values specified. If you run &lt;code&gt;PUT&lt;/code&gt; or &lt;code&gt;ADD&lt;/code&gt; on a key that doesn't exist yet, the
item will be automatically created. This little feature and handling of sets and
counters in general sounds a lot like things that made MongoDB so popular, as
you can atomically push items onto lists and increment counters.&lt;/p&gt;

&lt;p&gt;This is another feature that's got me thinking about whether DynamoDB even
includes the tiniest bit of the original Dynamo. You could model counters and
sets based on something like Dynamo for sure, based on the ideas behind
&lt;a href=&quot;http://hal.inria.fr/docs/00/55/55/88/PDF/techreport.pdf&quot;&gt;Commutative Replicated Data
Types&lt;/a&gt;. But I do wonder
if Amazon actually did go through all the trouble building that system on top of
the traditional Dynamo, or if they implemented something entirely new for this
purpose. There is no doubt that operations like these is what a lot of
users want even from distributed databases, so either way, they've clearly hit a
nerve.&lt;/p&gt;

&lt;h3&gt;Column Store in Disguise?&lt;/h3&gt;

&lt;p&gt;The fact that you can fetch and update single attributes with consistency
guarantees makes me think that DynamoDB is actually more like a wide column
store like Cassandra, HBase or, gasp, Google's BigTable. There doesn't seem to
be anything left from the original, content-agnostic idea of the Dynamo data
store, whose name DynamoDB so nicely piggybacks on.&lt;/p&gt;

&lt;p&gt;The bottom line is there's always a schema of attributes and values for a
particular item you store. What you store in an attribute is up to you, but
there's a limit of 64KB per item.&lt;/p&gt;

&lt;p&gt;DynamoDB assumes there's always some structure in the data you're storing. If
you need something content-agnostic to store data but with similar benefits
(replication, redundancy, fault-tolerance), use S3 and CloudFront. Nothing's
keeping you from using several services obviously. If I used DynamoDB for
something it'd probably not be my main datastore, but an add-on for data I need
to have highly available and stored in a fault-tolerant fashion, but that's a
matter of taste.&lt;/p&gt;

&lt;h3&gt;A Word on Throughput Capacity&lt;/h3&gt;

&lt;p&gt;Whereas you had to dynamically add capacity in self-hosting database systems,
always keeping an eye on current capacity limits, you can add more capacity to
handle more DynamoDB request per second simply by issuing an API call.&lt;/p&gt;

&lt;p&gt;Higher capacity means paying more. To save money, You could even adjust the
capacity for a specific time of day basis, growing up and down with your
traffic. If you go beyond your configured throughput capacity, operations may be
throttled.&lt;/p&gt;

&lt;p&gt;Throughput capacity is based on size of items you read and the number of reads
and writes per second. Reading one item with a size of 1 KB corresponds to one
read capacity unit. Add more required capacity units with increased size and
number of operations per second.&lt;/p&gt;

&lt;p&gt;This is the metric you always need to keep an eye on and constantly measure from
your app, not just to validate invoice Amazon sends you at the end of the month,
but also to track your capacity needs at all times. Luckily you can track this
using CloudWatch and trigger alerts. Amazon can trigger predefined alerts when
capacity crosses a certain threshold. Plus, every response to a read includes
the consumed read capacity, and the same is true for writes.&lt;/p&gt;

&lt;p&gt;Throughput capacity pricing is pretty ingenious on Amazon's end. You pay for
what you reserve, not for what you actually use. As you always have to have more
capacity available as you currently need, you always need to reserve more in
DynamoDB. But if you think about it, this is exactly how you'd work with your
own hosted, distributed database. You'll never want to work very close to
capacity, unless you're some crazy person.&lt;/p&gt;

&lt;p&gt;Of course you can only scale down throughput capacity once per day, but scale up
as much as you like, and increases need to be done at least 10%. I applaud you
for exploiting every possible opportunity to make money, Amazon!&lt;/p&gt;

&lt;h3&gt;Data Partitioning&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/BestPractices.html&quot;&gt;Amazon's
documentation&lt;/a&gt;
suggests that Amazon doesn't use random partitioning to spread data across
partitions, partitioning is instead done per table. Partitions are created as
you add data and as you increase capacity, suggesting either some sort of
composite key scheme or a tablet like partitioning scheme, again, similar to
what HBase or BigTable do. This is more fiction than fact, it's an assumption on
my part. A tablet-like approach certainly would make distributing and splitting
up partitions easier than having a fixed partitioning scheme upfront like in
Dynamo.&lt;/p&gt;

&lt;p&gt;The odd part is that Amazon actually makes you worry about partitions but
doesn't seem to offer any way of telling you about them or how your data is
partitioned. Amazon seems to handle partitioning mostly automatically and
increases capacity by spreading out your data across more partitions as you
scale capacity demand up.&lt;/p&gt;

&lt;h3&gt;Range Keys&lt;/h3&gt;

&lt;p&gt;Keys can be single values or based on a key-attribute combination. This is a
pretty big deal as it effectively gives you composite keys in a distributed
database, think Cassandra's data model. This effectively gives you a time series
database in the cloud, allowing you to store sorted data.&lt;/p&gt;

&lt;p&gt;You can specify a secondary key on which you can query by a range, and which
Amazon automatically indexes for you. This is yet another feature that makes
DynamoDB closer to a wide column store than the traditional Dynamo data store.&lt;/p&gt;

&lt;p&gt;The value of the range key could be an increasing counter (though you'd have to
take care of this yourself), a timestamp, or a time based UUID. Of course it
could be anything else and unique entirely, but time series data is just a nice
example for range keys. The neat part is that this way you can extract data for
specific time ranges, e.g. for logging or activity feeds.&lt;/p&gt;

&lt;p&gt;We already looked at how you define a normal hash key, let's look at an example
with a more complex key combining a hash key and a range key, using a numerical
type to denote a timestamp.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.create_table(&quot;activities&quot;, {
      HashKeyElement: {AttributeName: &quot;username&quot;, AttributeType: &quot;S&quot;},
      RangeKeyElement: {AttributeName: &quot;created_at&quot;, AttributeType: &quot;N&quot;}},
    {ReadCapacityUnits: 5, WriteCapacityUnits: 5})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can insert new items based on both the hash key and a range key. Just
specify at least both attributes in a request.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo.put_item(&quot;activities&quot;, {
    username: {S: &quot;roidrage&quot;}, 
    created_at: {N: Time.now.tv_sec.to_s},
    activity: {S: &quot;Logged in&quot;}})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The idea is simple, it's a timestamp-based activity feed per user, indexed by
the time of the activity. Using the
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_Query.html&quot;&gt;&lt;code&gt;Query&lt;/code&gt;&lt;/a&gt; action, we can fetch a range of
activities, e.g. for the last 24 hours. Just using &lt;code&gt;get_item&lt;/code&gt;, you always have
to specify a specific combination of hash and range key.&lt;/p&gt;

&lt;p&gt;To fetch a range, I'll have to resort to using Amazon's Ruby SDK, as fog hasn't
implemented the &lt;code&gt;Query&lt;/code&gt; action yet. That way you won't see the dirty API stuff
for now, but maybe that's a good thing.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dynamo = AWS::DynamoDB.new(access_key_id: &quot;YOUR KEY&quot;,
                           secret_access_key: &quot;YOUR SECRET&quot;)
activites = dynamo[&quot;activities&quot;]

items = activities.items.query(
    hash_key: &quot;roidrage&quot;,
    range_greater_than: (Time.now - 85600).tv_sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This fetches all activity items for the last 24 hours. You can also fetch more
historic items by specifying ranges. This example fetches all items for the last
seven days.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;items = activities.items.query(
    hash_key: &quot;roidrage&quot;,
    range_greater_than: (Time.now - 7.days.ago).tv_sec,
    range_less_than: Time.now.tv_sec)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that the &lt;code&gt;Query&lt;/code&gt; action is only available for tables with composite keys. If
you don't specify a range key, DynamoDB will return all items matching the hash
key.&lt;/p&gt;

&lt;h3&gt;Queries using Filters&lt;/h3&gt;

&lt;p&gt;The only things that's missing now is a way to do richer queries, which DynamoDB
offers by way of the
&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/API_Scan.html&quot;&gt;&lt;code&gt;Scan&lt;/code&gt;&lt;/a&gt;
action. fog doesn't have an implementation for this yet, so we once again turn
to the AWS Ruby SDK.&lt;/p&gt;

&lt;p&gt;Scanning allows you to specify a filter, which can be an arbitrary number of
attribute and value matches. Once again the Ruby SDK abstracts the ugliness of
the API underneath into something more readable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;activities.items.where(:activity).begins_with(&quot;Logged&quot;).each do |item|
  p item.attributes.to_h
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can include more than one attribute and build arbitrarily complex queries,
in this example to fetch only items related to the user &quot;roidrage&quot; and him
logging in.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;activities.items.where(:activity).equals(&quot;Logged in&quot;).
          and(:username).equals(&quot;roidrage&quot;).each do |item|
  p item.attributes.to_h
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can query for ranges as well, combining the above with getting only items
for the last seven days.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;activities.items.where(:activity).equals(&quot;Logged in&quot;).
    and(:username).equals(&quot;mathias&quot;).
    and(:created_at).between(7.days.ago.tv_sec, Time.now.tv_sec).each {|item|
  p item.attributes.to_h
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Filters fetch a maximum of 1 MB of data. As soon as that's accumulated, the scan
returns, but also includes the last item evaluated, so you can continue where
the query left off. Interestingly, you also get the number of items remaining.
Something like paginating results dynamically comes to mind. Running a filter is
very similar to running a full table scan, though it's rather efficient thanks
to SSDs. But don't expect single digit millisecond responses here. As scans
heavily affect your capacity throughput, you're better off resorting to their
use only for ad-hoc queries, not as a general part of your application's
workflow.&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;Query&lt;/code&gt; and &lt;code&gt;GetItem&lt;/code&gt;, the &lt;code&gt;Scan&lt;/code&gt; action doesn't guarantee strong
consistency, and there's no flag to explicitly request it.&lt;/p&gt;

&lt;h3&gt;The API&lt;/h3&gt;

&lt;p&gt;DynamoDB's HTTP API has got to be the worst ever built at Amazon, you could even
think it's the first API every designed at Amazon. You do POST requests even to
GET data. The request and response can include conditions and validations and
their respective errors, the proper Java class name of an error and other crap.
Not to mention that every error caused by any kind of input on your end always
causes a 400.&lt;/p&gt;

&lt;p&gt;Here's an example of a simplified request header:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;POST / HTTP/1.1
Content-Type: application/x-amz-json-1.0
x-amz-target: DynamoDB_20111205.GetItem
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here's a response body from an erroneous request:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{&quot;__type&quot;:&quot;com.amazon.coral.validate#ValidationException&quot;,
&quot;message&quot;:&quot;One or more parameter values were invalid:
The provided key size does not match with that of the schema&quot;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Lovely! At least there's a proper error message, though it's not always telling
you what the real error is. Given that Amazon's documentation is still filled with
syntactical errors, this is a bit inconvenient.&lt;/p&gt;

&lt;p&gt;The API is some bastard child of SOAP, but with JSON instead of XML. Even using
a pretty low level library like fog doesn't hide all the crap from you. Which
worked out well in this case, as you see enough of the API to get an idea about
its basic workings.&lt;/p&gt;

&lt;p&gt;The code examples above don't read very Ruby like as I'm sure you'll agree.
Though I gotta say, the Ruby SDK provided by AWS feels a lot more like Ruby in
its
&lt;a href=&quot;http://docs.amazonwebservices.com/AWSRubySDK/latest/frames.html&quot;&gt;interface&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I don't have very high hopes to see improvements on Amazon's end, but who knows.
S3, for example, got a pretty decent REST API eventually. &lt;/p&gt;

&lt;h3&gt;Pricing&lt;/h3&gt;

&lt;p&gt;Pricing is done (aside from throughput capacity) per GB stored. If you store
millions of items, and they all exceed size of just a few KB, expect to pay
Amazon a ton of money, storage pricing trumps throughput pricing by a lot. Keep
data stored in an item small. If you only store a few large items, it works too,
but you may end up being better off choosing one of Amazon's other storage
options. You do the math. Pricing for storage and the maximum size for a single
item always includes attribute names, just like with SimpleDB.&lt;/p&gt;

&lt;p&gt;To give you an idea how pricing works out, here's a simple calculation. 100 GB
of data, 1000 reads per second, 200 writes per second, item size is 4 KB on
average. That's $1253.15 every month, not including traffic. Add 10 GB of data the
second month and you're at $1263.15. You get the idea. Pricing is much more
affected by read and write operations vs. item size. Make your items 6 KB in
size, and you're already at $1827.68.&lt;/p&gt;

&lt;h3&gt;Bottom Line&lt;/h3&gt;

&lt;p&gt;Though Amazon is doing a pretty good job at squeezing the last drop of money out
of their customers using DynamoDB, think about what you're getting in return. No
operations, no hosting facilities, let alone in three different datacenters,
conditional writes and atomic counters, and a database that (I assume) has years
of experience in production forged into it.&lt;/p&gt;

&lt;p&gt;As usually the case with Amazon's Web Services, using something like DynamoDB is
a financial tradeoff. You get a data store that scales up and down with your
demand without you having to worry about the details of hardware, operations,
replication and data performance. In turn you pay for every aspect of the
system. The price for storage is likely to go down eventually, making it a more
attractive alternative to hosting an open source NoSQL database system yourself.
Whether this is an option for your specific use case, only you're able to make
that decision.&lt;/p&gt;

&lt;p&gt;If you store terrabytes of data, and that data is worth tens of thousands of
dollars per month in return for not having to care about hosting, by all means,
go for DynamoDB. But at that size, just one or two months of hosting on Amazon
pays off buying servers and SSDs for several data centers. That obviously
doesn't cover operational costs and personell, but it's just something to think
about.&lt;/p&gt;

&lt;h3&gt;Closing Thoughts&lt;/h3&gt;

&lt;p&gt;Sorted range keys, conditional updates, atomic counters, structured data and
multi-valued data types, fetching and updating single attributes, strong
consistency, and no explicit way to handle and resolve conflicts other than
conditions. A lot of features DynamoDB has to offer remind me of everything
that's great about wide column stores like Cassandra, but even more so of HBase.
This is great in my opinion, as Dynamo would probably not be well-suited for a
customer-facing system. And indeed, Werner Vogel's post on DynamoDB seems to suggest
DynamoDB is a bastard child of Dynamo and SimpleDB, though with lots of sugar
sprinkled on top.&lt;/p&gt;

&lt;p&gt;Note that it's certainly possible and may actually be the case that Amazon has
built all of the above on top of the basic Dynamo ingredients, Cassandra living
proof that it's possible. But if Amazon did reuse a lot of the existing Dynamo
code base, they hid it really well. All the evidence points to at least heavy
usage of a sorted storage system under the covers, which works very well with
SSDs, as they make sequential writes and reads nice and fast.&lt;/p&gt;

&lt;p&gt;No matter what it is, Amazon has done something pretty great here. They hide
most of the complexity of a distributed system from the user. The only option
you as a user worry about is whether or not you prefer strong consistency.
No quorum, no thinking about just how consistent you want a specific write
or read operation to be.&lt;/p&gt;

&lt;p&gt;I'm looking forward to seeing how DynamoDB evolves. Only time will tell how big
of an impact Amazon's entering the NoSQL market is going to have. Give it &lt;a href=&quot;http://aws.amazon.com/dynamodb/&quot;&gt;a
whirl&lt;/a&gt; to find out more about it.&lt;/p&gt;

&lt;p&gt;Want to know how the original Dynamo system works? Have a look at the &lt;a href=&quot;http://riakhandbook.com/?pp&quot;&gt;Riak
Handbook&lt;/a&gt;, a comprehensive guide to Riak a
distributed database that implements the ideas of Dynamo and adds lots of sugar
on top.&lt;/p&gt;

&lt;p&gt;I'm happy to be proven wrong or told otherwise about some of my assumptions
here, so feel free to get in &lt;a href=&quot;mailto:meyer@paperplanes.de&quot;&gt;touch&lt;/a&gt;!&lt;/p&gt;

&lt;h3&gt;Resources&lt;/h3&gt;

&lt;p&gt;Be sure to read &lt;a href=&quot;http://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html&quot;&gt;Werner Vogels' announcement&lt;/a&gt; of DynamoDB, and
&lt;a href=&quot;http://perfcap.blogspot.com/2012/01/thoughts-on-simpledb-dynamodb-and.html&quot;&gt;Adrian Cockcroft's comments&lt;/a&gt;
have some good insights on the evolution of data storage at Netflix and how
Cassandra, SimpleDB and DynamoDB compare.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/dynamodb/&quot;&gt;DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/dynamodb/faqs/&quot;&gt;DynamoDB FAQs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html&quot;&gt;Werner Vogels: Amazon DynamoDB - A Fast and Scalable NoSQL Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://aws.typepad.com/aws/2012/01/amazon-dynamodb-internet-scale-data-storage-the-nosql-way.html&quot;&gt;Amazon DynamoDB - Internet-Scale Data Storage the NoSQL Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://perfcap.blogspot.com/2012/01/thoughts-on-simpledb-dynamodb-and.html&quot;&gt;Adrian Cockcroft: Thoughts on SimpleDB, DynamoDB and Cassandra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://aws.amazon.com/sdkforruby/&quot;&gt;AWS SDK for Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://nosql.mypopescu.com/post/16064274863/notes-about-amazon-dynamodb&quot;&gt;Alex Popescu: Notes about Amazon DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/&quot;&gt;DynamoDB Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jed/dynamo&quot;&gt;Dynamo, a Node.js library for DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/SemanticSugar/dinerl&quot;&gt;dinerl, an Erlang client for DynamoDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/CAKf7a-waJ0&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Seeds for different environments</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/0u9cxZoW4oI/seeds-for-different-environments"/>
		<id>http://dennisreimann.de/blog/seeds-for-different-environments</id>
		<updated>2012-01-25T12:59:00+00:00</updated>
		<content type="html">&lt;p&gt;Here’s a little Rails tip for splitting up seed data for various environments:
            Create the folder &lt;code&gt;db/seeds/&lt;/code&gt;. For each environment you want to seed put a file in there named after the env. Your general seeds are put into &lt;code&gt;db/seeds/all.rb&lt;/code&gt;. Here’s what it might look like:&lt;/p&gt;
            
            &lt;pre&gt;&lt;code&gt;|___seeds
            | |___all.rb
            | |___development.rb
            | |___staging.rb
            | |___production.rb
            |___seeds.rb
            &lt;/code&gt;&lt;/pre&gt;
            
            &lt;p&gt;Change the content of your &lt;code&gt;db/seeds.rb&lt;/code&gt; to something like this:&lt;/p&gt;
            
            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'all'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/db/seeds/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.rb&quot;&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*** Loading &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; seed data&quot;&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seed_file&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
            &lt;/pre&gt;
            &lt;/div&gt;
            
            
            &lt;p&gt;Running &lt;code&gt;rake db:seed&lt;/code&gt; will now load up the seed data defined in &lt;code&gt;db/seeds/all.rb&lt;/code&gt; and the current environment.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">My Publishing Tool Chain</title>
		<link href="http://www.paperplanes.de//2012/1/12/my-publishing-tool-chain.html"/>
		<id>http://www.paperplanes.de//2012/1/12/my-publishing-tool-chain.html</id>
		<updated>2012-01-12T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Update: Added paragraph on the &lt;a href=&quot;http://feeds.feedburner.com/Paperplanes#fulfillment&quot;&gt;e-commerce platform&lt;/a&gt; I'm using.&lt;/p&gt;

&lt;p&gt;Several people have asked me about the publishing tool chain I'm using for the
&lt;a href=&quot;http://riakhandbook.com/?pp&quot;&gt;Riak Handbook&lt;/a&gt; and the &lt;a href=&quot;http://nosqlhandbook.com/&quot;&gt;NoSQL
Handbook&lt;/a&gt;. As &lt;a href=&quot;http://avdi.org/devblog/2012/01/12/my-authoring-tools/&quot;&gt;Avdi just published
his&lt;/a&gt;, now's as good a
good time as any to throw in mine too. After all, it's always nice to know all
the options you have.&lt;/p&gt;

&lt;p&gt;All text is written in Markdown. I started out with Textile, but just didn't
like Textile's way of breaking down single lines into separate paragraphs, so I
switched to Markdown later on. Not a painless process, but sufficiently easy
thanks to Pandoc.&lt;/p&gt;

&lt;p&gt;The Markdown files, one per chapter, are bundled together into a big file and
then fed into GitHub's &lt;a href=&quot;https://github.com/tanoku/redcarpet&quot;&gt;Redcarpet&lt;/a&gt; library.
I use &lt;a href=&quot;https://github.com/github/albino&quot;&gt;Albino&lt;/a&gt; and
&lt;a href=&quot;http://pygments.org/&quot;&gt;Pygments&lt;/a&gt; for syntax highlighting, embedded into a custom
renderer for Redcarpet. See the Redcarpet
&lt;a href=&quot;https://github.com/tanoku/redcarpet/blob/master/README.markdown&quot;&gt;README&lt;/a&gt; for an
example. Redcarpet also has some MultiMarkdown extensions for tables and other
things, so that comes in pretty handy.&lt;/p&gt;

&lt;p&gt;To generate the PDF I'm using &lt;a href=&quot;http://princexml.com/&quot;&gt;Prince&lt;/a&gt;, a neat little
tool that takes HTML and a bunch of CSS and generates a nice PDF. It's a
commercial tool, and costs some $500 for a single license. That was what threw
me off a tiny bit, but luckily there's a handy service called
&lt;a href=&quot;http://docraptor.com/&quot;&gt;DocRaptor&lt;/a&gt; which is basically a pretty API around Prince,
but much much cheaper.&lt;/p&gt;

&lt;p&gt;You can use Prince locally to generate infinite test PDFs, and then use
DocRaptor to generate the final result. Which is what I do. Before generating
the PDF through DocRaptor I upload the generated HTML, which includes all the
CSS, to S3, to avoid some issues I've had with Unicode characters in the HTML,
and tell DocRaptor to fetch it from a URL instead.&lt;/p&gt;

&lt;p&gt;You can use web fonts easily, I went for fonts from Google Web Fonts, which are
easily embeddable with Prince and DocRaptor. Prince also allows you to do some
customizations specific, stuff like page titles, page numbers, custom settings
for left and right pages, footnotes, and the like. See the
&lt;a href=&quot;http://princexml.com/doc/8.0/&quot;&gt;documentation&lt;/a&gt; for a full list.&lt;/p&gt;

&lt;p&gt;For ePub generation I generate a stripped-down version of the HTML, not
including syntax highlighting, because iBooks doesn't like custom-styled &lt;code&gt;pre&lt;/code&gt; or
&lt;code&gt;code&lt;/code&gt; elements, if you style them iBooks chooses to ignore any font setting and
use the default font, which is usually not monospaced.&lt;/p&gt;

&lt;p&gt;The HTML then goes through &lt;a href=&quot;http://calibre-ebook.com/&quot;&gt;Calibre&lt;/a&gt; to generate the
ePub file, and then I use
&lt;a href=&quot;http://www.amazon.com/gp/feature.html/ref=amb_link_357613502_1?ie=UTF8&amp;docId=1000765211&quot;&gt;kindlegen&lt;/a&gt;
to generate a Kindle file from that. Calibre has a pretty ugly user interface,
but it comes with a set of command line tools you can use to automatically
convert ebooks from one format to another.&lt;/p&gt;

&lt;p&gt;All of the above is wrapped into a Rakefile and some small Ruby classes. I'll be
sure to put it up for your perusal soon, but this list should get you started.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;fulfillment&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make the book available for purchase I'm using
&lt;a href=&quot;http://www.fastspring.com/&quot;&gt;FastSpring&lt;/a&gt;. They're not my favorite choice, as
they make things like customizing your shop fairly hard, but I chose them
because their way of payout (monthly or bi-monthly), and the fact that they take
care of VAT, were both reasons important to me, especially being in Europe,
where tax laws throw a lot of stones at you for wanting to try and sell things
internationally. Unfortunately FastSpring doesn't have any means of updating
products and allowing and notifying users of the updates being available, so I
built a small Sinatra app to capture orders and take care of sending out the
updates. Not pretty, but it's a small sacrifice compared to the tax hassle I'd
have with any other fulfillment provider.&lt;/p&gt;

&lt;p&gt;Curious about the result? You should &lt;a href=&quot;http://riakhandbook.com/?pp&quot;&gt;buy the book&lt;/a&gt;!&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/E8ZNE6jg06Y&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">DRUG #25</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/YzxtK81m4yA/"/>
		<id>http://blog.railslove.com/?p=1208</id>
		<updated>2012-01-11T17:03:20+00:00</updated>
		<content type="html">&lt;p&gt;During my leave in beautiful &lt;a href=&quot;http://enwp.org/Wroc%C5%82aw&quot;&gt;Wrocław&lt;/a&gt;, I had a chance to attend &lt;a href=&quot;http://drug.org.pl/spotkania/drug-25&quot;&gt;DRUG #25&lt;/a&gt; meet-up. DRUG (Dolnośląska Grupa Użytkowników Ruby) is Lower Silesian Ruby user group, and their meetings usually take place once a month.&lt;/p&gt;
&lt;p&gt;Andrzej Krzywda &lt;a href=&quot;https://twitter.com/andrzejkrzywda/status/148152712909963264&quot;&gt;introduced me&lt;/a&gt; to a non-written rule of DRUG, which states &amp;#8220;[i]f it&amp;#8217;s your first time then you are presenting a talk&amp;#8221;. I presented &lt;a href=&quot;https://github.com/Holek/travis-talk-2011-wroclaw&quot;&gt;a quick talk&lt;/a&gt; about &lt;a href=&quot;http://travis-ci.org&quot;&gt;Travis CI&lt;/a&gt;. While it came as no surprise, that everybody knew the topic, it was especially nice to see people asking more detailed questions about current state, the future and sharing what they have done with Travis.&lt;/p&gt;
&lt;p&gt;The people I met are tremendous and I will be happy to see them again on &lt;a href=&quot;http://wrocloverb.com&quot;&gt;Wroclove.rb&lt;/a&gt;! Big thanks to all attending and especially to &lt;a href=&quot;http://twitter.com/kolarzowski&quot;&gt;@kolarzowski&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/piterniel&quot;&gt;@piterniel&lt;/a&gt; for having me at their office during my leave. See you all soon!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=YzxtK81m4yA:iRnWY_mz22k:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=YzxtK81m4yA:iRnWY_mz22k:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=YzxtK81m4yA:iRnWY_mz22k:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=YzxtK81m4yA:iRnWY_mz22k:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Railslove at war</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/ypQytQWfWTE/"/>
		<id>http://blog.railslove.com/?p=1205</id>
		<updated>2012-01-11T16:44:20+00:00</updated>
		<content type="html">&lt;p&gt;Today, January 11th, 2012 &amp;#8211; a date which will live in infamy &amp;#8211; &lt;a href=&quot;http://railslove.com&quot;&gt;Railslove&lt;/a&gt; was suddenly and deliberately attacked by the dark forces of &lt;a href=&quot;http://9elements.com&quot;&gt;9elements&lt;/a&gt;.&lt;br /&gt;
Railslove was at peace with that nation and looking toward the maintenance of peace. In a brutal attack 9elements took one of the Railslove team members as hostage while being on a friendly mission visiting their headquarters.&lt;br /&gt;
It will be recorded that the visit of the Railslove member took place on solicitation of 9elements &amp;#8211; it is obvious that the attack was deliberately planned many days or even weeks ago.&lt;br /&gt;
Because of this circumstances we are forced to protect ourselves and have to free our team member.&lt;br /&gt;
I ask that Railslove declare that since the unprovoked and dastardly attack by 9elements on January 11th, 2012, a state of war has existed between &lt;a href=&quot;http://railslove.com&quot;&gt;Railslove&lt;/a&gt; and &lt;a href=&quot;http://9elements.com&quot;&gt;9elements&lt;/a&gt;.&lt;br /&gt;
&lt;strong&gt;Let &lt;a href=&quot;http://www.paintball-borken.de/&quot;&gt;Paintball Borken&lt;/a&gt; be our battleground for this gigantomachia!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;proof:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2012/01/Twitter.png&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-1206&quot; title=&quot;9elements declares war&quot; src=&quot;http://blog.railslove.com/wp-content/uploads/2012/01/Twitter.png&quot; alt=&quot;&quot; width=&quot;570&quot; height=&quot;548&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ypQytQWfWTE:ae9uTqGgWL4:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ypQytQWfWTE:ae9uTqGgWL4:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ypQytQWfWTE:ae9uTqGgWL4:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=ypQytQWfWTE:ae9uTqGgWL4:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The only constant is change</title>
		<link href="http://feedproxy.google.com/~r/jankrutisch/rss/~3/pBoRWBHNZD0/"/>
		<id>http://jan.krutisch.de/en/2012/01/08/the-only-constant-is-change.html/</id>
		<updated>2012-01-07T23:00:00+00:00</updated>
		<content type="html">&lt;p&gt;This blogpost had a loooong, long way to go, and I&amp;#8217;m immensely glad I am finally able to write it, but also quite anxious about it - Not about the post as such, but about the implications of my acts that lead up to this post.&lt;/p&gt;

&lt;p&gt;I am relatively risk-averse. I think many of us are, and I think we germans are especially good at it. Change is frowned upon.&lt;/p&gt;

&lt;p&gt;That being said, sometimes change is just inevitable. For me, it has been since at least the before-last end-of-year, where I almost broke up with my girlfriend and, by the time the year was done, both of us lived, after 7 years of living together, in our own flats again. We&amp;#8217;re happy together, with the usual highs and lows, but the separate living spaces give us shelter when things are rough, which, you know, also inevitably happens.&lt;/p&gt;

&lt;p&gt;So, that&amp;#8217;s change on a totally personal level and that&amp;#8217;s totally not what I was going to write about - Nevertheless, with someone who doesn&amp;#8217;t draw very distinct lines between personal and professional life, it plays an important part.&lt;/p&gt;

&lt;p&gt;From that time on, a lot of things started to happen at once. First of all, although I loved (and still do) working at &lt;a href=&quot;http://mindmatters.de/&quot;&gt;mindmatters&lt;/a&gt;, I started to look for alternatives - I wanted to, so to speak, level-up my work life. Which is actually not that easy, especially at an awesome place like mindmatters. So, I only have had two valid ideas back then: Founding a startup (and maybe applying for something like HACKFWD) or going freelance. Now, I&amp;#8217;ve been doing freelance work before (during my studies) and I always hated the overhead of writing invoices, making sure that people pay me, etc, etc. Also, what we do at mindmatters is mostly client work, and going freelance would basically mean doing the same thing, with less security, less awesome colleagues and bosses, less project management support and slightly higher pay.&lt;/p&gt;

&lt;p&gt;Then Florian, my colleague and foodie inspiration number one, convinced our founders (at mindmatters, that is) to open an office in london - I won&amp;#8217;t go into the details why we think that this is a brilliant idea - that&amp;#8217;s a whole different blog post and not one I should write, but of course I was keen to look at it and in the beginning I was quite sure that I would end up in London at the beginning of 2012.&lt;/p&gt;

&lt;p&gt;Then I spent my summer vacation in San Francisco, 3 weeks of awesomeness in the Haight and in the Mission (Home and Work) and of course I fell in love with it. I was hoping to be able to write a blog post about SF as well, but somehow I never managed. Well, I hope to be back this year for a few weeks - We&amp;#8217;ll see how that goes. What SF did to me, though, was giving me thoughts on a pretty much existential scale. What I learned there was that there are a lot of awesome places to live all around the world. But what I also learned there is how much I love my little, totally behind and totally mismanaged, not-having-a-super-awesome-tech-scene, Hamburg. My hometown. I&amp;#8217;ve been born here, in a blue-collar neighbourhood called Barmbek before my parents and me moved to what people probably would call the outskirts of northeastern Hamburg. I basically lived there until 2010, when I moved much closer to the city centre, to lovely Eimsbüttel. Ironically, as a side note, my girlfriend now lives a few blocks away from the place my parents and my grandmother (who died in 2011, may Jutta Krutisch rest in peace) and I lived until the late 70s.&lt;/p&gt;

&lt;p&gt;This feeling of home was, unfortunately, only amplified when I spent three weeks in London after coming back from SF, working on a project there for mindmatters, so-to-speak paving the way for &lt;a href=&quot;http://mindmatters.co.uk&quot;&gt;mindmatters.co.uk&lt;/a&gt; and getting a good feeling for how it is to live there. Don&amp;#8217;t get me wrong, I love London. I love the food options as much as Florian (although not as fiercely, maybe), I love the vibrant tech scene, I love the openness of an english pub, I love that I instantly found a place that sells me american IPA&amp;#8217;s, an addiction I formed in SF, I love all of that.&lt;/p&gt;

&lt;p&gt;But I also very much love the quietness of Hamburg. And I started to hate everything that&amp;#8217;s connected to Air traffic. The easyJet connection to London is okay-ish and bearable if everything&amp;#8217;s fine. One little thing and it turns into this nightmarish hour long wait at the gate which the converts into a situation where the BorisBike from London Bridge to Kings Cross (where I was staying at the time) is actually the sane way to go home an 1:30 on a monday morning.&lt;/p&gt;

&lt;p&gt;So even if I am able to tuck away my environmentalist heart (which bled quite heavily in 2011 due to all the flights I took) for a second, moving to london would have meant either giving up my relationship (which, as I wrote, just recovered from what I would call an existential crisis) or spending way too much time and nerves on my carbondioxide budget.&lt;/p&gt;

&lt;p&gt;Additionally to that, having a long-distance relationship may be fine, as long as you are already rooted in the place you live, but having one from a city where you actually just moved to also probably prevents you from actually growing any roots in that new city.&lt;/p&gt;

&lt;p&gt;In the end, I wasn&amp;#8217;t able to make any clear commitments to Florian and the mindmatters peeps that I would go over with him in the beginning of 2012.&lt;/p&gt;

&lt;p&gt;What I had sworn to myself, though, somewhere in the process, was that I would not simply go back to business as usual when not going to London, but finally, finally, make sure that I also change course professionally.&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s what&amp;#8217;s going to happen with me, starting Feb 2012. I&amp;#8217;ll reduce my work for mindmatters to 20% of a normal contract (meaning about a day a week on average) and I will start freelancing for the rest of the time.&lt;/p&gt;

&lt;p&gt;So why stay on the 20%? First of all, I love mindmatters. I am one of their first full time employees, starting in 2007 (which also means that I will be able to celebrate my 5 years of mindmatters in April, something I very much look forward to). I think the way Frank and Wolfgang steer their little company sets an example on transparency, accountability and humanity. This sounds huge, but I mean it. Most companies I know of don&amp;#8217;t openly discuss their business goals, even their business model, their finance status and various other things openly in a company meeting &lt;strong&gt;every four weeks&lt;/strong&gt;. Most companies I know would not work in a way where I as an employee can come up to my CEO and say &amp;#8220;BTW, I&amp;#8217;m planning to leave over the course of the next half a year, let&amp;#8217;s talk how we can make this as smooth as possible&amp;#8221;. Don&amp;#8217;t get me wrong, it&amp;#8217;s not all flowers and fluffy pink clouds in mindmatters-land - There are disagreements, there are arguments, there are misunderstandings, heck, after all, this is not a democratic parliament, this is a privately held company with business- and other goals. But I have never, ever before seen owners try so hard to keep up their vision (even through hard times and tough winds) on how to run a company and realign this vision with the help of every employee over and over again, iterating and iterating, and thus becoming, if the word would not be almost meaningless by 2012, a truly agile company.&lt;/p&gt;

&lt;p&gt;So, I want to be part of that for as long as possible. I want to play my own part in keeping up that spirit, helping with my experience, my wit and my bad puns.&lt;/p&gt;

&lt;p&gt;Regarding my work as a freelancer, although I have not signed any contracts by now, I am most probably already booked out for 2-3 days per week in the first quarter, which should at least give me a base on which to ponder what to do next.&lt;/p&gt;

&lt;p&gt;It is actually not my goal to spend the rest of 2012 doing freelance work, but to try out various ideas, of some of which you hopefully will hear about &amp;#8220;very soon now&amp;#8221;, although, if you have something interesting for me, &lt;a href=&quot;mailto:jan@krutisch.de&quot;&gt;hit me&lt;/a&gt; with it, because I can&amp;#8217;t look much further than a few months right now and actually everything beyond the start of February is still quite cloudy right now.&lt;/p&gt;

&lt;p&gt;Which gives me the creeps, but also makes me quite happy. I am, for once, completely on my own, without being alone in it.&lt;/p&gt;

&lt;p&gt;Happy new year, everyone&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/jankrutisch/rss/~4/pBoRWBHNZD0&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>jan.krutisch.de</name>
			<uri>http://jan.krutisch.de</uri>
		</author>
		<source>
			<title type="html">jan.krutisch.de</title>
			<subtitle type="html">An ongoing conversation between Jan Krutisch and the Interwebs on nothing in particular.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/jankrutisch/rss/"/>
			<id>http://feeds.feedburner.com/jankrutisch/rss/</id>
			<updated>2012-01-15T22:20:31+00:00</updated>
			<rights type="html">Copyright 2004-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">a very Merry Christmas</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/4OpVLrdGtkk/"/>
		<id>http://blog.railslove.com/?p=1190</id>
		<updated>2011-12-23T13:41:05+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/12/weihnachtskarte_thumb1.jpg&quot;&gt;&lt;br /&gt;
&lt;img class=&quot;aligncenter size-full wp-image-1196&quot; title=&quot;Merry Christmas&quot; src=&quot;http://blog.railslove.com/wp-content/uploads/2011/12/weihnachtskarte_thumb1.jpg&quot; alt=&quot;Merry Christmas&quot; width=&quot;495&quot; height=&quot;347&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We wish you all a wonderful christmas time!&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=4OpVLrdGtkk:ij1OfFnOUPE:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=4OpVLrdGtkk:ij1OfFnOUPE:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=4OpVLrdGtkk:ij1OfFnOUPE:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=4OpVLrdGtkk:ij1OfFnOUPE:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Holiday Reading List</title>
		<link href="http://www.paperplanes.de//2011/12/22/holiday-reading-list.html"/>
		<id>http://www.paperplanes.de//2011/12/22/holiday-reading-list.html</id>
		<updated>2011-12-22T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Here's a list of things I've been reading lately or that I'm about to read, and
that I found to be worth sharing.  If you're looking for something to read over
the holidays, I'm happy to give you some suggestions. Books, papers, articles,
and videos, something for everyone.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://scalabilityrules.com/&quot;&gt;&lt;strong&gt;Scalability Rules&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A list of 50 rules related to scalability, in an easy to read recipe style.
They leave some stuff to the imagination, and I don't agree with every single
rule, especially not with the one that demands software should always be easy
to rollback, but they give you good food for thought for your own
applications. &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://research.microsoft.com/en-us/um/people/lamport/pubs/time-clocks.pdf&quot;&gt;&lt;strong&gt;Time, Clocks, and the Ordering of Events in a Distributed System&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The earliest paper (1978!) to mention the notion of clocks as a means to track
ordering of events in distributed systems, the predecessor to vector clocks,
if you will. A must read.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://radlab.cs.berkeley.edu/people/fox/static/pubs/pdf/c18.pdf&quot;&gt;&lt;strong&gt;Harvest, Yield, and Scalable Tolerant Systems&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A recap of CAP, making the whole notion of it a bit more flexible by adding
tuning knobs for graceful degradation. Hat tip to Coda Hale and his article
&lt;a href=&quot;http://codahale.com/you-cant-sacrifice-partition-tolerance/&quot;&gt;&quot;You can't sacrifice partition tolerance&quot;&lt;/a&gt; for pointing me to this.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://dbmsmusings.blogspot.com/2010/04/problems-with-cap-and-yahoos-little.html&quot;&gt;&lt;strong&gt;Problems with CAP, and Yahoo's little known NoSQL system&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also related to CAP, this article introduces the notion of PACELC, which
basically adds latency to the CAP equation. CAP has been criticized quite a few
times for being too strict in this regard, and while the name PACELC is a bit
odd, the added notion of latency makes a lot of sense.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://dbmsmusings.blogspot.com/2011/12/replication-and-latency-consistency.html&quot;&gt;&lt;strong&gt;Replication and the latency-consistency tradeoff&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another one from Daniel Abadi, another one related to CAP, this time talking
about replication, consistency, and latency.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://rescomp.stanford.edu/~cheshire/rants/Latency.html&quot;&gt;&lt;strong&gt;It's the latency, stupid!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going further back in time, this paper talks about latency in all its glory.
Sure, it talks about modem speed connections, but extrapolate that into today's
network bandwidth and you still have latency. Or you can read the next posts
too.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.edgeblog.net/2007/its-still-the-latency-stupid/&quot;&gt;&lt;strong&gt;It's Still The Latency, Stupid...pt. 1&lt;/strong&gt;&lt;/a&gt; and &lt;a href=&quot;http://www.edgeblog.net/2007/its-still-the-latency-stupid-pt2/&quot;&gt;&lt;strong&gt;It's Still The Latency, Stupid...pt. 2&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A more recent update on latency, because it still matters more than bandwidth.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.usenix.org/events/hotos03/tech/candea.html&quot;&gt;&lt;strong&gt;Crash-only Software&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been pondering fault-tolerant and cloud-ready systems for a while now,
here's one related to the topic, software that crashes as a means to make it
more fault-tolerant.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Systems-that-Never-Stop-Joe-Armstrong&quot;&gt;&lt;strong&gt;Systems that Never Stop (video)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great talk by Joe Armstrong, inventor of Erlang, laying down six laws for
fault-tolerant systems. All laws lead to Erlang obviously, but it all makes a
lot of sense.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.hpl.hp.com/techreports/tandem/TR-85.7.html&quot;&gt;&lt;strong&gt;Why Do Computers Stop and What Can Be Done About It?&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Related to Joe's talk, this paper discusses hardware reduncancy and reliable
storage by means of process pairs, modularity and transactions. Have yet to read
this one, but going to be interesting thinking about how these ideas, stemming
from hardware, apply to software and have been implemented by Erlang.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://workingwithunixprocesses.com/&quot;&gt;&lt;strong&gt;Working With Unix Processes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A little indie-published ebook on handling Unix processes. Code is focused on
Ruby, but most if not all of the book is easily applicable to any other language
or a basic Unix environment.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.eecs.harvard.edu/~mdw/papers/seda-sosp01.pdf&quot;&gt;&lt;strong&gt;SEDA: An Architecture for Well-Conditioned, Scalable Internet Services&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SEDA was an idea for web and application server concurrency based on using
queues to condition and handle requests. While the idea has not exactly made it
through, I found the model to be strikingly similar to the actor model, in a
different way, but still very similar.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://matt-welsh.blogspot.com/2010/07/retrospective-on-seda.html&quot;&gt;&lt;strong&gt;A Retrospective on SEDA&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SEDA, ten years later, by the author of the original paper. I gotta say, he
talks a lot what they got wrong, but I for one think SEDA had a pretty big
impact on the bigger picture of web application architecture. Probably something
worth discussing in a separate post.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.usenix.org/events/hotos03/tech/full_papers/vonbehren/vonbehren_html/index.html&quot;&gt;&lt;strong&gt;Why Events Are A Bad Idea&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A paper comparing threads and events for highly concurrent servers. I'd
recommend taking this with a grain of salt. A lot has changed since this paper
was written, but what I like about reading papers like this is that it gives you
a historic perspective, same for SEDA.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.redhat.com/magazine/001nov04/features/vm/&quot;&gt;&lt;strong&gt;Understanding Virtual Memory&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice summary of how virtual memory works on Linux.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.eecs.berkeley.edu/Pubs/TechRpts/2010/EECS-2010-90.pdf&quot;&gt;&lt;strong&gt;The Declarative Imperative: Experiences and Conjectures in Distributed Logic&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be honest, this is a slightly confusing paper. It starts out modeling things
in an oscure language called Datalog, but then dives into making some
conjectures about distributed logic, which was to me the more interesting part.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://betathoughts.blogspot.com/2007/06/brief-history-of-consensus-2pc-and.html&quot;&gt;&lt;strong&gt;A brief history of Consensus, 2PC and Transaction Commit&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is full of gold. An extraordinarily compact view on the topic, but
with an abundance of links to papers to dive deeper.&lt;/p&gt;

&lt;p&gt;Going to keep posting reading lists like this in the future. So much good stuff
to read out there. Lots of great knowledge collected in papers.&lt;/p&gt;

&lt;p&gt;Last but not least, why not add the &lt;a href=&quot;http://riakhandbook.com/?pp&quot;&gt;Riak Handbook&lt;/a&gt;
to your reading list as well?&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/gHDJ8VL_5bY&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Storing User Timelines in Riak</title>
		<link href="http://www.paperplanes.de//2011/12/15/storing-timelines-in-riak.html"/>
		<id>http://www.paperplanes.de//2011/12/15/storing-timelines-in-riak.html</id>
		<updated>2011-12-15T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;The idea of building and storing user timelines (think Twitter) in Riak confused
me at first. It sounds like such a spot-on case for time series databases. Yet
&lt;a href=&quot;http://basho.com/blog/technical/2011/03/28/Riak-and-Scala-at-Yammer/&quot;&gt;Yammer&lt;/a&gt;
managed to make the idea pretty popular. The whole thing lacked implementation
though, because they kept their to themselves, which I don't blame them for at
all.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111215-kyt2di6kbkwrb1trsquudhy7xa.png&quot; alt=&quot;Apple Mac Timeline&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So let's have a look at how simple it is to build one. You can see a timeline of
all Apple Macintosh products above, but that's not what we want to build.&lt;/p&gt;

&lt;p&gt;Instead we want to build something like the Twitter timeline. A user follows
many other users, and wants to look at a feed built from their activities, so
something like the timeline shown below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111215-qwnywuamtahh356qi9ri3yt9ae.png&quot; alt=&quot;Twitter timeline&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;How do you model a timeline in Riak?&lt;/h3&gt;

&lt;p&gt;For every user we store one object in Riak. Every timeline contains a list of
tweet ids, or whatever activity you're referencing, or it can contain the whole
tweets. Something like this should work:&lt;/p&gt;



&lt;p&gt;If you want to store more data, turn the list into an array of hashes containing
whatever information is necessary to rebuild the timeline later. &lt;/p&gt;



&lt;h3&gt;Adding entries to the timeline&lt;/h3&gt;

&lt;p&gt;To add new entries to a timeline, prepend them to the existing list of
entries, here's some Ruby code to show how it's done.&lt;/p&gt;



&lt;p&gt;The code assumes you take care of followership somewhere else. You can store
that data in Riak too, but the code is oblivious to its whereabouts.&lt;/p&gt;

&lt;h3&gt;Conflicts, siblings, oh my!&lt;/h3&gt;

&lt;p&gt;The fun starts when two clients update the same timeline, you get a conflict
and siblings. The strength of a simple data structure like the example above is
that they're easy to merge together while still keeping ordering based on the
ids. The ids are ordered only in this example, Twitter somewhat makes sure they
are.&lt;/p&gt;

&lt;p&gt;When you get a conflict, a smart Riak library like
&lt;a href=&quot;https://github.com/seancribbs/ripple&quot;&gt;Ripple&lt;/a&gt; helps you find out about it. To
add on the earlier example, here's a version of &lt;code&gt;add&lt;/code&gt; that detects conflicts.&lt;/p&gt;



&lt;p&gt;Suddenly you have two or more objects instead of one, each containing a different timeline. To
turn them into a single list, you merge all of them together, discard the
duplicates, and restore order based on the id. Here's some Ruby to do that.&lt;/p&gt;



&lt;p&gt;You iterate over all timeline objects and keep adding unique activities to a new
list, returning that when done.&lt;/p&gt;

&lt;h3&gt;Sort, and done!&lt;/h3&gt;

&lt;p&gt;All that's left to do is sort the result.&lt;/p&gt;



&lt;p&gt;&lt;a href=&quot;http://riakhandbook.com&quot;&gt;&lt;img src=&quot;https://img.skitch.com/20111213-jks6gqhww79y172qcdsdwpgbgu.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's the whole code. To spare you the pain of having to write your own
library, all this is bundled into a gem called
&lt;a href=&quot;https://github.com/mattmatt/riaktivity&quot;&gt;riaktivity&lt;/a&gt;. If you're doing Python,
the Brett Hoerner has got you covered with
&lt;a href=&quot;https://github.com/bretthoerner/timak&quot;&gt;timak&lt;/a&gt;. Be sure to watch the original
talk by
&lt;a href=&quot;http://basho.com/blog/technical/2011/03/28/Riak-and-Scala-at-Yammer/&quot;&gt;Yammer&lt;/a&gt;,
it's well worth it.&lt;/p&gt;

&lt;p&gt;There's ups and downs to this approach, and things that need to be taken care
of. More on that and modeling data for Riak in general is covered in the &lt;a href=&quot;http://riakhandbook.com/&quot;&gt;Riak
Handbook&lt;/a&gt;, the definitive guide on Riak.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/3YsVItB-lmE&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">List All of the Riak Keys</title>
		<link href="http://www.paperplanes.de//2011/12/13/list-all-of-the-riak-keys.html"/>
		<id>http://www.paperplanes.de//2011/12/13/list-all-of-the-riak-keys.html</id>
		<updated>2011-12-13T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111213-tkydhksqa79dwhc5ikb9n9g14j.png&quot; alt=&quot;Key rack&quot; /&gt;&lt;/p&gt;

&lt;p&gt;One of the most common questions to ask about Riak is: how do I get a list of all
the keys in my bucket, in the cluster, or that have an attribute that matches my
query using MapReduce?&lt;/p&gt;

&lt;p&gt;The motivation behind it is simple: you want to delete all the keys in a bucket,
count the amount of keys stored in your cluster entirely, you want to clear out your
cluster or you want to run ad-hoc queries on the data stored in a bucket.&lt;/p&gt;

&lt;p&gt;All valid in their own right.&lt;/p&gt;

&lt;p&gt;But things are not so simple with Riak. To understand why, let's take a quick
look under the covers.&lt;/p&gt;

&lt;h3&gt;What's in a bucket?&lt;/h3&gt;

&lt;p&gt;A bucket is a namespace in Riak. It's not a physically distinctive entity like a
table in a relational database. You can set some properties on it, things like
replication levels, commit hooks, quorum, but that's it. Those are stored in the
cluster's configuration which is gossiped around the cluster just like the data
that identifies what partition goes on which machine.&lt;/p&gt;

&lt;p&gt;In fact, when you specify a bucket and a key to fetch or write some data,
they're stuck together to find the location in the cluster. Consider a
bucket-key combination like &lt;code&gt;users/roidrage&lt;/code&gt;. To find the location, Riak hashes
both, not just the key. Both bucket and key uniquely identify a piece of data,
allowing you to have multiple object with the same key, but in different
buckets.&lt;/p&gt;

&lt;p&gt;When an object is stored in Riak's storage backends, it uses both bucket and key
name to identify it. What you get as a result are files that contain an
abundance of different bucket-key combinations and their respective objects,
sometimes not even in any order. The only physical distinction Riak has for data
on disk is the partition they belong to. Everything else is up to the storage
backend. There's no distinction between buckets on disk.&lt;/p&gt;

&lt;p&gt;One reason for this is consistent hashing. If you remember the &lt;a href=&quot;http://feeds.feedburner.com/2011/12/9/the-magic-of-consistent-hashing.html&quot;&gt;last installment
of this series&lt;/a&gt;, I mentioned
that consistent hashing's downside is that you lose key ordering. Keys are
randomly spread out through the cluster. Some ordering still exists depending on
the backend, but in general, ordering is lost.&lt;/p&gt;

&lt;h3&gt;Listing all of the keys&lt;/h3&gt;

&lt;p&gt;So to list keys in a bucket, Riak has to go through all of the keys in every
partition, and I mean ALL OF THEM. Here's a picture of keys and an impersonation
of Riak, having to take care of all of them.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://img.skitch.com/20111213-g2ju8pdeefu4ns5q6j7m8smdr1.png&quot; width=&quot;540&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No big deal, right? Unless of course, you store millions and millions of them,
and want to find about all the keys from say, the bucket &lt;code&gt;users&lt;/code&gt;, which may not
even have to be more than 1000. To do that, Riak goes through every partition,
every partition loads the keys either from memory (Bitcask) or disk (LevelDB)
and sifts through them, finding the ones belonging to the &lt;code&gt;users&lt;/code&gt; bucket.&lt;/p&gt;

&lt;p&gt;All that said, it's certainly not impossible to do, if you have some time to
wait, depending on the amount of data stored.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl 'localhost:8098/buckets/users/keys?keys=true'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But wait, don't do that. Do this instead, streaming the keys instead of waiting
for them all to arrive and then having them dumped at once.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl 'localhost:8098/buckets/users/keys?keys=stream'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's much better.&lt;/p&gt;

&lt;p&gt;Listing keys has an impact on your Riak nodes, so if you can avoid it, don't do
it!&lt;/p&gt;

&lt;h3&gt;So how do I really get all of the keys?&lt;/h3&gt;

&lt;p&gt;If &lt;code&gt;select * from riak&lt;/code&gt; is not a great option, then what is?&lt;/p&gt;

&lt;p&gt;Instead of relying on Riak, build an index on the keys. Thanks to &lt;a href=&quot;http://wiki.basho.com/Secondary-Indexes.html&quot;&gt;Riak 2i
(Secondary Indexes)&lt;/a&gt;, this is
easy. In fact, you get indexing of keys for free when using the LevelDB backend,
just use the index &lt;code&gt;$key&lt;/code&gt;. This takes advantage of LevelDB's sorted file
structure. Neat!&lt;/p&gt;

&lt;p&gt;But, and here's the kicker, you can only fetch ranges of keys. So instead of
asking for all the keys, you ask for a range large enough to fit all the keys.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl 'localhost:8098/buckets/users/index/$key/0/zzzz'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This finds all the keys that start with something lexicographically larger than
&lt;code&gt;0&lt;/code&gt; and less than &lt;code&gt;zzzz&lt;/code&gt; and returns them to you in a list. Now there's a slim
chance you'll get users with names like that, but I'll leave that exercise, or
proper validations, up to you.&lt;/p&gt;

&lt;p&gt;Using that list, you can count the number of keys in that bucket, or you can
delete them one by one.&lt;/p&gt;

&lt;h3&gt;Ideally...&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://riakhandbook.com&quot;&gt;&lt;img src=&quot;https://img.skitch.com/20111213-jks6gqhww79y172qcdsdwpgbgu.png&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an ideal world, listing keys in a bucket would be possible and not an
expensive operation. Riak could for example allow users to store buckets in
separate files. The downside is that with a lot of buckets, you'll hit the
limits of open file descriptors in no time, a bit of a bummer. But until
something better comes along, secondary indexes are a nice tool to at least
avoid resorting to listing all of the keys.&lt;/p&gt;

&lt;p&gt;Curious about other ways to index and query data in Riak? You'll like the &lt;a href=&quot;http://riakhandbook.com&quot;&gt;Riak
Handbook&lt;/a&gt;, which will be published later this
week. Covers Riak's secondary indexes and other strategies to query, inspect and
analyze data.&lt;/p&gt;

&lt;p&gt;Check back in tomorrow for an introduction on storing timelines in Riak.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/oNsxRV8xJB8&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The Simple Magic of Consistent Hashing</title>
		<link href="http://www.paperplanes.de//2011/12/9/the-magic-of-consistent-hashing.html"/>
		<id>http://www.paperplanes.de//2011/12/9/the-magic-of-consistent-hashing.html</id>
		<updated>2011-12-09T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;The simplicity of consistent hashing is pretty mind-blowing. Here you have a
number of nodes in a cluster of databases, or in a cluster of web caches. How do
you figure out where the data for a particular key goes in that cluster?&lt;/p&gt;

&lt;p&gt;You apply a hash function to the key. That's it?  Yeah, that's the whole deal of
consistent hashing. It's in the name, isn't it?&lt;/p&gt;

&lt;p&gt;The same key will always return the same hash code (hopefully), so once you've
figured out how you spread out a range of keys across the nodes available, you
can always find the right node by looking at the hash code for a key.&lt;/p&gt;

&lt;p&gt;It's pretty ingenious, if you ask me. It was cooked up in the lab chambers at
Akamai, back in the late nineties. You should go and &lt;a href=&quot;http://www.akamai.com/dl/technical_publications/ConsistenHashingandRandomTreesDistributedCachingprotocolsforrelievingHotSpotsontheworldwideweb.pdf&quot; title=&quot;Akamai - Consistent Hashing and Random Trees&quot;&gt;read the original paper
right after we're done here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Consistent hashing solves the problem people desperately tried to apply sharding
to pretty nicely and elegantly. I'm not going to bore you with the details on
how exactly consistent hashing works. &lt;a href=&quot;http://www.mikeperham.com/2009/01/14/consistent-hashing-in-memcache-client/&quot; title=&quot;Mike Perham - Consistent Hashing in memcache-client&quot;&gt;Mike Perham&lt;/a&gt; does a pretty good job at
that already, and there are &lt;a href=&quot;http://www.tomkleinpeter.com/2008/03/17/programmers-toolbox-part-3-consistent-hashing/&quot; title=&quot;Tom Peter - Programmer’s Toolbox Part 3: Consistent Hashing&quot;&gt;many more blog posts&lt;/a&gt; explaining
&lt;a href=&quot;http://www.lexemetech.com/2007/11/consistent-hashing.html&quot; title=&quot;Tom White - Consistent Hashing&quot;&gt;implementations&lt;/a&gt; and &lt;a href=&quot;http://michaelnielsen.org/blog/consistent-hashing/&quot; title=&quot;Michael Nielsen - Consistent Hashing&quot;&gt;theory behind it&lt;/a&gt;. Also, that &lt;a href=&quot;http://twitter.com/riakhandbook&quot;&gt;little upcoming
book&lt;/a&gt; of mine has a full-length explanation
too. Here's a graphic showing the basic idea of consistent hashing, courtesy of
Basho.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://paperplanes-assets.s3.amazonaws.com/consistent-hashing.png&quot; alt=&quot;Consistent Hashing&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Instead I want to look at the practical implications of consistent hashing in
distributed databases and cache farms.&lt;/p&gt;

&lt;h3&gt;Easier to Avoid Hotspots&lt;/h3&gt;

&lt;p&gt;When you put data on nodes based on a random result, which is what the hash
function calculates, a value that's a lot more random than the key it's based
on, it's easier to avoid hotspots. Why?&lt;/p&gt;

&lt;p&gt;Assume a key based on an increasing value, or a simple range of keys, based on
the hour of the day, like &lt;code&gt;2011-12-11-13&lt;/code&gt;. You add new hours and therefore new
data as time passes, and keys are stored based on the range they fall in. For
example, the keys &lt;code&gt;2011-12-11-18&lt;/code&gt; until &lt;code&gt;2011-12-11-23&lt;/code&gt; are stored on the same
node, with the rest of the keys stored on other nodes, just because the ranges
or the partitioning scheme happen to be set up this way.&lt;/p&gt;

&lt;p&gt;For a consumer-facing site, the evening hours are usually the busiest time of
the day. They create more data, more writes, and possibly more reads too. For
the hours between 18:00 and 23:00, all the load goes to the single node that
carries all the relevant data.&lt;/p&gt;

&lt;p&gt;But when you determine the location in the cluster based solely on the hash of
the key, chances are much higher that two keys lexicographically close to each
other end up on different nodes. Thus, the load is shared more evenly. The
disadvantage is that you lose the order of keys.&lt;/p&gt;

&lt;p&gt;There are partitioning schemes that can work around this, even with a
range-based key location. HBase (and Google's BigTable, for that matter) stores
ranges of data in separate tablets. As tablets grow beyond their maximum size,
they're split up and the remaining parts re-distributed. The advantage of this
is that the original range is kept, even as you scale up.&lt;/p&gt;

&lt;h3&gt;Consistent Hashing Enables Partitioning&lt;/h3&gt;

&lt;p&gt;When you have a consistent hash, everything looks like a partition. The idea is
simple. Consistent hashing forms a keyspace, which is also called continuum, as
presented in the illustration. As a node joins the cluster, it picks a random
number, and that number determines the data it's going to be responsible for.
Everything between this number and one that's next in the ring and that has
been picked by a different node previously, is now belong to this node. The
resulting partition could be of any size theoretically. It could be a tiny
slice, or a large one.&lt;/p&gt;

&lt;p&gt;First implementations of consistent hashing still had the problem that a node
picking a random range of keys resulted in one node potentially carrying a
larger keyspace than others, therefore still creating hotspots.&lt;/p&gt;

&lt;p&gt;But the improvement was as simple as it was ingenious. A hash function has a
maximum result set, a SHA-1 function has a bit space of 2^160. You do the
math. Instead of picking a random key, a node could choose from a fixed set of
partitions, like equally size pizza slices. But instead of picking the one with
the most cheese on, everyone gets an equally large slice. The number of
partitions is picked up front, and practically never changes over the lifetime
of the cluster.&lt;/p&gt;

&lt;p&gt;For good measure, here's a picture of a sliced pizza.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://paperplanes-assets.s3.amazonaws.com/consistent-pizza.jpg&quot; alt=&quot;Consistent Pizza&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Partitioning Makes Scaling Up and Down More Predictable&lt;/h3&gt;

&lt;p&gt;With a fixed number of partitions of the same size, adding new nodes becomes
even less of a burden than with just consistent hashing. With the former, it was
still unpredictable how much data had to be moved around to transfer ownership
of all the data in the range of the new node. One thing's for sure, it already
involved a lot less work than previous methods of sharding data.&lt;/p&gt;

&lt;p&gt;With partitioning, a node simply claims partitions, and either explicitly or
implicitly asks the current owners to hand off the data to them. As a partition
can only contain so many keys, and randomness ensures a somewhat even spread of
data, there's a lot less unpredictability about the data that needs to be
transferred.&lt;/p&gt;

&lt;p&gt;If that partitions just so happens to carry the largest object by far in you
whole cluster, that's something even consistent hashing can't solve. It only
cares for keys.&lt;/p&gt;

&lt;p&gt;Going back to HBase, it cares for keys and the size of the tablet the data is
stored in, as it breaks up tablets once they reach a threshold.  Breaking up and
reassigning a tablet requires coordination, which is not an easy thing to do in
a distributed system.&lt;/p&gt;

&lt;h3&gt;Consistent Hashing and Partitioning Enable Replication&lt;/h3&gt;

&lt;p&gt;Consistent hashing made one thing a lot easier: replicating data across several
nodes. The primary means for replication is to ensure data survives single or
multiple machine failures. The more replicas you have, the more likely is your
data to survive one or more hardware crashes. With three replicas, you can
afford to lose two nodes and still serve the data.&lt;/p&gt;

&lt;p&gt;With a fixed set of partitions, a new node can just pick the ones it's
responsible for, and another stack of partitions it's going to be a replica for.
When you really think about it, both processes are actually the same. The beauty
of consistent hashing is that there doesn't need to be master for any piece of
data. Every node is simply a replica of a number of partitions.&lt;/p&gt;

&lt;p&gt;But replication has another purpose besides ensuring data availability.&lt;/p&gt;

&lt;h3&gt;Replication Reduces Hotspots (Even More!!!)&lt;/h3&gt;

&lt;p&gt;Having more than one replica of a single piece of data means you can spread out
the request load even more. With three replicas of that data, residing on three
different nodes, you can now load-balance between them. Neat!&lt;/p&gt;

&lt;p&gt;With that, consistent hashing enables a pretty linear increase in capacity as you
add more nodes to a cluster.&lt;/p&gt;

&lt;h3&gt;Consistent Hashing Enables Scalability and Availability&lt;/h3&gt;

&lt;p&gt;Consistent hashing allows you to scale up and down easier, and makes ensuring
availability easier. Easier ways to replicate data allows for better
availability and fault-tolerance. Easier ways to reshuffle data when nodes come
and go means simpler ways to scale up and down.&lt;/p&gt;

&lt;p&gt;It's an ingenious invention, one that has had a great impact. Look at the likes
of &lt;a href=&quot;http://memcached.org/&quot; title=&quot;Memcached&quot;&gt;Memcached&lt;/a&gt;, &lt;a href=&quot;http://www.allthingsdistributed.com/2007/10/amazons_dynamo.html&quot; title=&quot;Amazon Dynamo&quot;&gt;Amazon's Dynamo&lt;/a&gt;, &lt;a href=&quot;http://cassandra.apache.org/&quot; title=&quot;Cassandra&quot;&gt;Cassandra&lt;/a&gt;, or &lt;a href=&quot;http://basho.com/products/riak-overview/&quot; title=&quot;Riak&quot;&gt;Riak&lt;/a&gt;. They all
adopted consistent hashing in one way or the other to ensure scalability and
availability.&lt;/p&gt;

&lt;p&gt;Want to know more about distributed databases in general and Riak in particular?
You'll like the &lt;a href=&quot;http://riakhandbook.com/&quot;&gt;Riak Handbook&lt;/a&gt;, a hands-on
guide full of practical examples and advice on how to use Riak to ensure
scalability and availability for your data.&lt;/p&gt;

&lt;p&gt;In the next installment we're looking at the consequences and implications of
losing key ordering in a Riak cluster.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/whiokV-c6Tg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Configuring Nginx for the Asset Pipeline</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/jFl3fNu-Mj0/configuring-nginx-for-the-asset-pipeline"/>
		<id>http://dennisreimann.de/blog/configuring-nginx-for-the-asset-pipeline</id>
		<updated>2011-12-07T14:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Following up on the series of posts about the Rails Asset Pipeline, here are some things to keep in mind when you are using Nginx as your webserver.&lt;/p&gt;
              
              &lt;h3&gt;Installation via Passenger&lt;/h3&gt;
              
              &lt;p&gt;When you are installing Nginx automatically with the script that comes with Passenger, you will not be able to serve the gzipped file variants that get precompiled. That’s because Passenger currently does not configure Nginx with the &lt;code&gt;http_gzip_static_module&lt;/code&gt; that would be necessary for including the directive &lt;code&gt;gzip_static on&lt;/code&gt;. I’ve opened a &lt;a href=&quot;https://github.com/dbloete/passenger/commit/db3a8de7cf3b644831471d2fc2167799c5291070&quot;&gt;pull request&lt;/a&gt; for that, but for now you’ll have to choose the manual installation, if that’s what you are after - and why wouldn’t you?&lt;/p&gt;
              
              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# download and untar nginx&lt;/span&gt;
              wget -O /tmp/nginx.tar.gz http://www.nginx.org/download/nginx-1.0.10.tar.gz
              tar xzvf /tmp/nginx.tar.gz
              rm /tmp/nginx.tar.gz
              
              &lt;span class=&quot;c&quot;&gt;# install nginx via passenger install script, already includes&lt;/span&gt;
              &lt;span class=&quot;c&quot;&gt;# --with-http_ssl_module&lt;/span&gt;
              &lt;span class=&quot;c&quot;&gt;# --add-module for passenger&lt;/span&gt;
              passenger-install-nginx-module --auto --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/opt/nginx'&lt;/span&gt; --nginx-source-dir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/tmp/nginx-1.0.10'&lt;/span&gt; --extra-configure-flags&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;--with-http_gzip_static_module&quot;&lt;/span&gt;
              &lt;/pre&gt;
              &lt;/div&gt;
              
              
              &lt;p&gt;You might want to change the version and prefix to fit your needs. Like mentioned in the comments you don’t have to take care of including the passenger or ssl module, because the installation script adds them automatically.&lt;/p&gt;
              
              &lt;h3&gt;Nginx configuration&lt;/h3&gt;
              
              &lt;p&gt;This is already part of the &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html#in-production&quot;&gt;Asset Pipeline Guide&lt;/a&gt;, but I’ll mention it here again, so that this article is complete - here are the directives for the assets location config:&lt;/p&gt;
              
              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;^/(assets)/&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kn&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;/path/to/site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;kn&quot;&gt;gzip_static&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;kn&quot;&gt;expires&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;kn&quot;&gt;add_header&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Cache-Control&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# access_log /dev/null;&lt;/span&gt;
              &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
              &lt;/pre&gt;
              &lt;/div&gt;
              
              
              &lt;p&gt;&lt;del&gt;I’ve also disabled access logging, so that asset requests do not clutter up the log.&lt;/del&gt;&lt;/p&gt;
              
              &lt;p&gt;Mathias &lt;a href=&quot;https://twitter.com/#!/roidrage/status/144335957158658048&quot;&gt;brought up a good point&lt;/a&gt;, why one might not want to do that.&lt;/p&gt;
              
              &lt;h3&gt;Sendfile Header&lt;/h3&gt;
              
              &lt;p&gt;In your app’s &lt;code&gt;production.rb&lt;/code&gt; you should uncomment to following line, to let Nginx send static files:&lt;/p&gt;
              
              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action_dispatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x_sendfile_header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'X-Accel-Redirect'&lt;/span&gt;
              &lt;/pre&gt;
              &lt;/div&gt;
              
              
              &lt;h3&gt;Verify that it’s working&lt;/h3&gt;
              
              &lt;p&gt;After deploying the changes, you can check if Nginx is now serving the gzipped compressed versions of your asset files. For that you can use tools like this
              &lt;a href=&quot;http://www.whatsmyip.org/http-compression-test/&quot;&gt;HTTP Compression Tester&lt;/a&gt; and enter the address of your &lt;code&gt;application.js&lt;/code&gt; and &lt;code&gt;application.css&lt;/code&gt;&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Referencing Rails Assets in CoffeeScript</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/wAssCUyFYG8/referencing-rails-assets-in-coffeescript"/>
		<id>http://dennisreimann.de/blog/referencing-rails-assets-in-coffeescript</id>
		<updated>2011-12-05T23:45:00+00:00</updated>
		<content type="html">&lt;p&gt;Sometimes you’ll want to refer to your image assets from inside of your CoffeeScript (or JavaScript). While we have &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html#coding-links-to-assets&quot;&gt;nice helpers for that in SASS&lt;/a&gt; (namely &lt;code&gt;image-path&lt;/code&gt; and &lt;code&gt;image-url&lt;/code&gt;), we would have to resort to appending .erb to every .js or .coffee file, we want to reference images in, so that we could use something like this in there:&lt;/p&gt;
                
                &lt;pre&gt;&lt;code&gt;icon = %= image_path('icon.png') %&gt;
                &lt;/code&gt;&lt;/pre&gt;
                
                &lt;p&gt;I didn’t like it that way, because ERB inside of CoffeeScript looks odd and having the file end with .erb messes up syntax highlighting. But we can circumvent this easily by adding this (admittedly not the most beautiful) piece of code to one single file that ends on .erb (i.e. &lt;code&gt;images.js.coffee.erb&lt;/code&gt;) and let it provide the helper method we need:&lt;/p&gt;
                
                &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;%&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
                &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/app/assets/images/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;**&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({})&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                &lt;span class=&quot;cp&quot;&gt;%&gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
                
                &lt;span class=&quot;x&quot;&gt;window.image_path = (name) -&gt;&lt;/span&gt;
                &lt;span class=&quot;x&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;%=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_json&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%&gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;[name]&lt;/span&gt;
                &lt;/pre&gt;
                &lt;/div&gt;
                
                
                &lt;p&gt;This adds up all images inside of &lt;code&gt;app/assets/images&lt;/code&gt; and makes them available via the global helper method &lt;code&gt;image_path&lt;/code&gt; - your milage may vary, but you get the idea. From there on it’s simply&lt;/p&gt;
                
                &lt;pre&gt;&lt;code&gt;icon = image_path('icon.png')
                &lt;/code&gt;&lt;/pre&gt;
                
                &lt;p&gt;inside of your CoffeeScript (or JavaScript) files and it also works in production as the returned filename contains the digest.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">reminder: Global Day of Coderetreat Cologne/Bonn 3rd Dez.</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/68BDJhhCEX4/"/>
		<id>http://blog.railslove.com/?p=1186</id>
		<updated>2011-12-01T13:32:14+00:00</updated>
		<content type="html">&lt;p&gt;The upcoming saturday (Dez. 3rd) is Global Day of Coderetreat. It’s a world-wide event celebrating passion and software craftsmanship.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Coderetreat is a day-long, intensive practice event, focusing on the fundamentals of software development and design.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;You can find more information about the &lt;a href=&quot;http://coderetreat.com/&quot;&gt;Coderetreat format&lt;/a&gt; and the &lt;a href=&quot;http://blog.coderetreat.com/global-day-of-coderetreat&quot;&gt;event&lt;/a&gt; on the official website. For cologne all the information is on a &lt;a href=&quot;https://github.com/coreyhaines/coderetreat/wiki/Cologne&quot;&gt;github wiki&lt;/a&gt; and you should follow the office &lt;a href=&quot;https://twitter.com/#!/CodeRetreatCGN&quot;&gt;twitter account&lt;/a&gt; for updates.&lt;/p&gt;
&lt;div&gt;The event will take place in our &lt;a href=&quot;http://coworkingcologne.de/&quot;&gt;office&lt;/a&gt; and starts at 8:30 in the morning.&lt;/div&gt;
&lt;div&gt;See you there!&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=68BDJhhCEX4:DtSmr8xzo04:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=68BDJhhCEX4:DtSmr8xzo04:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=68BDJhhCEX4:DtSmr8xzo04:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=68BDJhhCEX4:DtSmr8xzo04:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">OpenData Bremen</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/vNKC0XtPGfY/opendata-bremen"/>
		<id>http://dennisreimann.de/blog/opendata-bremen</id>
		<updated>2011-11-30T09:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Im Rahmen des OpenData-Wettbewerbs &lt;a href=&quot;http://apps4deutschland.de/&quot;&gt;Apps4Deutschland&lt;/a&gt; fand in Bremen am Freitag, den 11. November 2011 die Auftaktveranstaltung zu &lt;a href=&quot;http://daten.bremen.de/&quot;&gt;Apps4Bremen&lt;/a&gt; statt. Nach dem &lt;a href=&quot;http://daten.berlin.de/&quot;&gt;Vorbild Berlin&lt;/a&gt; macht nun auch das Land Bremen Teile der Daten staatlicher Stellen öffentlich und läd dazu ein, diese zu verwerten und sinnvoll aufzubereiten - auf der Apps4Deutschland-Website heißt es dazu:&lt;/p&gt;
                  
                  &lt;blockquote&gt;&lt;p&gt;Behörden in Deutschland erheben, speichern und verarbeiten viele interessante Daten. Dazu gehören Wetterdaten ebenso wie Informationen über die Luftqualität oder über die Verwendung der Steuergelder. Diese Daten sind von öffentlichem Interesse und bergen ein großes Potenzial für unsere Gesellschaft, weil sie Transparenz, Beteiligung, Innovationen und neue Dienstleistungen fördern.&lt;/p&gt;
                  
                  &lt;p&gt;Mit dem Wettbewerb „Apps für Deutschland“ laden wir Designer, Entwickler, Journalisten, Forscher und die breite Öffentlichkeit ein, Anwendungen zu schaffen, um diese Daten nutzbar zu machen.&lt;/p&gt;&lt;/blockquote&gt;
                  
                  &lt;p&gt;Da ich das Thema Open Government spannend finde und für sehr wichtig halte, war der Wettberwerb ein guter Anlass, um mir eine neue &lt;a href=&quot;http://bremen.innovated.de/&quot;&gt;Spielwiese für die offenen Daten Bremens&lt;/a&gt; zu schaffen. Das Projekt besteht aktuell nur aus einer &lt;a href=&quot;http://kitas-in-bremen.de&quot;&gt;Übersicht der Bremer Kindertagesstätten&lt;/a&gt;, lässt sich aber auf dem bisherigen Stand gut erweitern, da es bereits Beispiele für Datenimporter, Geokodierung und Darstellung von Orten auf einer Google Map enthält. Basis dafür sind Ruby on Rails und Backbone.js und der &lt;a href=&quot;https://github.com/dbloete/OpenData-Bremen&quot;&gt;Quelltext ist auf GitHub verfügbar&lt;/a&gt;, so dass das Projekt gerne erweitert werden kann. Gerne lasse ich mich auch &lt;a href=&quot;https://github.com/dbloete/OpenData-Bremen/issues&quot;&gt;auf Ideen, Verbesserungswünsche oder Fehler hinweisen&lt;/a&gt;.&lt;/p&gt;
                  
                  &lt;p&gt;Wer sich inspirieren lassen möchte, kann auch mal einen Blick in den &lt;a href=&quot;http://opendata-showroom.org/&quot;&gt;OpenData Showroom&lt;/a&gt; werfen, der Projekte aus aller Welt enthält, die sich offener Daten bedienen. Würde mich freuen, wenn sich viele weitere Leute finden, die mit den Daten was nettes auf die Beine stellen.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Precompiling Rails Assets for Development</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/w6LGO0h-oug/precompiling-rails-assets-for-development"/>
		<id>http://dennisreimann.de/blog/precompiling-rails-assets-for-development</id>
		<updated>2011-11-28T14:22:00+00:00</updated>
		<content type="html">&lt;p&gt;First off: I love Rails’ &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html&quot;&gt;asset pipeline&lt;/a&gt; from the bottom of my heart. It’s a great thing and makes frontend development such a lovely task. There are two little drawbacks though when using it in development: It slows down page reloads and clutters up the log output. Here I’ll show you how to get rid of that.&lt;/p&gt;
                    
                    &lt;p&gt;When you are mainly doing backend development or most of your apps frontend code doesn’t change too much do yourself a favor and precompile your assets for the development environment:&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;$ RAILS_ENV=development bundle exec rake assets:precompile
                    &lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;This really speeds up page reloads as Rails does not need to look up and precompile the asset files every time a request hits the app anymore.&lt;/p&gt;
                    
                    &lt;p&gt;Another change you might want to make is to set &lt;code&gt;config.assets.debug&lt;/code&gt; to false in your development environment. This makes Sprocket concatenate all your files (users.css, search.css, …) into one javascript and stylesheet file (application.css):&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;config.assets.debug = false
                    &lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;This also cleans up the noisy logging info concerning the asset files that were previously loaded one by one.&lt;/p&gt;
                    
                    &lt;p&gt;When you need to precompile additional assets that aren’t already referenced in you application.js or application.css you’ll want to move the &lt;code&gt;config.assets.precompile&lt;/code&gt; directive from production.rb to application.rb:&lt;/p&gt;
                    
                    &lt;pre&gt;&lt;code&gt;config.assets.precompile += %w( search.js )
                    &lt;/code&gt;&lt;/pre&gt;
                    
                    &lt;p&gt;This isn’t directly related but while you are at speeding up our development experience you might also want to have a look at the &lt;a href=&quot;https://github.com/wavii/rails-dev-tweaks&quot;&gt;rails-dev-tweaks&lt;/a&gt; gem. This gem defines rules for managing what files get reloaded on page requests in development.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Dear Cologne Rubyists: Your user group needs you!</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/QI8w-72uyDw/"/>
		<id>http://blog.railslove.com/?p=1183</id>
		<updated>2011-11-25T19:51:57+00:00</updated>
		<content type="html">&lt;p&gt;In November 2005 we&amp;#8217;ve started the first Ruby usergroup in cologne. Back then we&amp;#8217;ve been &lt;a href=&quot;http://www.flickr.com/photos/bumi/64761771/&quot;&gt;4 people who met for beers&lt;/a&gt;. This was nearly exactly 6 years ago.  Unfortunately the meetup has soon become inactive &amp;#8211; actually I can not remember when that was and how it happened.&lt;/p&gt;
&lt;p&gt;After that, I guess in 2007 the &lt;a href=&quot;http://rurug.de&quot;&gt;rurug.de&lt;/a&gt; started with greater success. It was a meetup which first took place in the rooms of the &lt;a href=&quot;http://koeln.ccc.de&quot;&gt;Chaos Computer Club Cologne&lt;/a&gt;. Sadly I haven&amp;#8217;t participated in that meetup very activly :( *bad bumi*&lt;/p&gt;
&lt;p&gt;Early this year the meetup then has moved to &lt;a href=&quot;http://cowoco.de&quot;&gt;cowoco&lt;/a&gt; and renewed itself with about 30+ people attending.  The following events had been awesome! Great talks and even better discussions.  Unfortunatelly, after summer we&amp;#8217;ve became very inactive again. Not many people participated on the mailing list and the event hasn&amp;#8217;t taken place in the last two months.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WE NEED TO CHANGE THIS!! &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And now is the time to rethink the meetup.&lt;br /&gt;
I know we have so many awesome ruby developers here in cologne, working on exciting projects!&lt;/p&gt;
&lt;p&gt;We need to connect, share, teach in our local ruby community!&lt;br /&gt;
&lt;strong&gt;Let&amp;#8217;s work together to bring back one of the best tech meetups in Cologne! &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To get this started again I propose the following things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;changing the mailing list to something that is more accessible. &lt;/strong&gt;&lt;br /&gt;
This is something I&amp;#8217;ve heard several times. The current mailinglist is kinda hard to follow and it&amp;#8217;s hard for people to get into the conversation. -this is especially the case for new people.&lt;br /&gt;
I also think the mailing list has some spam issues?!&lt;/li&gt;
&lt;li&gt;maybe using a google group for now. I do not really like google groups but it works for &lt;a href=&quot;http://colognejs.de&quot;&gt;cologneJS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;better organizations/archiving of the talk material&lt;/strong&gt; like slides etc. &amp;#8211; obviously ;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;inviting more speakers&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;http://speakerexchange.org/&quot;&gt; speakers exchange&lt;/a&gt; is a great. I herby invite &lt;a href=&quot;http://twitter.com/joshkalderimis&quot;&gt;@joshkalderimis&lt;/a&gt; from Amsterdam to tell us about &lt;a href=&quot;http://travis-ci&quot;&gt;travis-ci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;meetup for some delicious Glühwein on the christmas market to discuss these things&lt;/strong&gt;&lt;br /&gt;
Date: 14th Dez. 07:00pm at Heumarkt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What do you think? How do you feel about the cologne ruby meetup? Who joins me?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cologne.rb let&amp;#8217;s unite!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(&lt;a href=&quot;http://michaelbumann.com/post/13307859028/dear-rubyists-from-greater-cologne&quot;&gt;also posted on my blog&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=QI8w-72uyDw:_UvlTfc-gYM:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=QI8w-72uyDw:_UvlTfc-gYM:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=QI8w-72uyDw:_UvlTfc-gYM:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=QI8w-72uyDw:_UvlTfc-gYM:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Git autocomplete in bash on a Mac</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/qQxPr3cz7ck/"/>
		<id>http://blog.railslove.com/?p=1178</id>
		<updated>2011-11-25T09:24:44+00:00</updated>
		<content type="html">&lt;p&gt;I&amp;#8217;ve been using Linux and bash for great chunk of time for web development, and it always had great features like autocomplete, that I didn&amp;#8217;t get by default on a Mac.&lt;/p&gt;
&lt;p&gt;So, I&amp;#8217;ve decided to take matters into my on hands, and leave a post for all those, who are also bugged by no git autocomplete in bash on a Mac.&lt;/p&gt;
&lt;p&gt;Thankfully, git already &lt;a href=&quot;https://github.com/git/git/blob/master/contrib/completion/git-completion.bash&quot;&gt;has its autocomplete script&lt;/a&gt;, so it&amp;#8217;s a matter of just two commands:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;But I like to take it one step beyond. To save some keystrokes, I&amp;#8217;ve added some aliases to my &lt;tt&gt;~/.gitconfig&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now I can tab on &lt;tt&gt;git co &lt;/tt&gt; and everywhere else I was used to on my Linux machine.&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qQxPr3cz7ck:yIvF2Ggf6-Q:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qQxPr3cz7ck:yIvF2Ggf6-Q:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qQxPr3cz7ck:yIvF2Ggf6-Q:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=qQxPr3cz7ck:yIvF2Ggf6-Q:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">No magic behind it but everytime worth to remember</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/9EHKNjsmaSY/"/>
		<id>http://blog.railslove.com/?p=1160</id>
		<updated>2011-11-23T21:18:49+00:00</updated>
		<content type="html">&lt;h2&gt;Rspec Refactoring and Shared Example Groups&lt;/h2&gt;
&lt;p&gt;Today we had lightning talks about specs refactoring. Jan showed us some tricks based on his experiences from our latest open source project: &lt;a href=&quot;http://railsrunners.org&quot;&gt;railsrunners.org&lt;/a&gt; (&lt;a href=&quot;https://github.com/railslove/railsrunners&quot;&gt;Github&lt;/a&gt;):&lt;/p&gt;
&lt;h2&gt;Some simple spec principles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use clear descriptions for your specs in combination of using &amp;#8220;describe&amp;#8221;-, &amp;#8220;context&amp;#8221;-blocks&lt;/li&gt;
&lt;li&gt;Use contexts and descriptions properly, e.g.: &lt;code&gt; describe &quot;#edit&quot;; context &quot;with valid params&quot;; etc.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use the &amp;#8211;format documentation parameter to check your descriptions for specs, describes, and contexts. E.g.: &lt;code&gt;rspec spec/controllers/participants_controller_spec.rb --format documentation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Instead of manually creating associated models in your tests just to pass validations, FactoryGirl can automatically create them for you, e.g.:&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;Then instead of:&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;You&amp;#8217;d simply have:&lt;/li&gt;
&lt;p&gt;&lt;/p&gt;
&lt;li&gt;Write one assertion per test.&lt;/li&gt;
&lt;li&gt;Stub requests using FakeWeb (&lt;strong&gt;Update: or WebMock or any other Request-Mocking-Helper&lt;/strong&gt;), e.g.: FakeWeb.register_uri(:get, &amp;#8220;http://static-maps-generator.appspot.com/url?msid=#{@future_run.msid}&amp;#038;size=950&amp;#215;300&amp;#8243;, :body =&gt; response)&lt;/li&gt;
&lt;li&gt;Controller specs should only test the behaviour of your controller. Model specs test the behaviour of your model. Don&amp;#8217;t mix the two! E.g.: do not test after_ or before_ save callbacks in your controller tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take a look at the railsrunners Github repository: &lt;a href=&quot;https://github.com/railslove/railsrunners&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Shared example groups&lt;/h2&gt;
&lt;p&gt;Sometimes you want to test the same behaviour in various specs or contexts. To keep your code DRY, you can use RSpec&amp;#8217;s shared example groups:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If needed, you can move the shared example group to a spec helper and require that wherever you need to test for &amp;#8216;successful responses&amp;#8217;.&lt;/p&gt;
&lt;h2&gt;Further reading:&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/example-groups/shared-example-group&quot;&gt;https://www.relishapp.com/rspec/rspec-core/v/2-0/docs/example-groups/shared-example-group&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://rspec.info/documentation/&quot;&gt;http://rspec.info/documentation/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shared-example-groups-in-rspec-2/&quot;&gt;http://blog.davidchelimsky.net/2010/11/07/specifying-mixins-with-shared-example-groups-in-rspec-2/&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=9EHKNjsmaSY:cBi3Xds-rlo:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=9EHKNjsmaSY:cBi3Xds-rlo:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=9EHKNjsmaSY:cBi3Xds-rlo:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=9EHKNjsmaSY:cBi3Xds-rlo:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Setting up Ubuntu with Teleport</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/FgI_pfpLu6Q/setting-up-ubuntu-with-teleport"/>
		<id>http://dennisreimann.de/blog/setting-up-ubuntu-with-teleport</id>
		<updated>2011-11-15T13:15:00+00:00</updated>
		<content type="html">&lt;p&gt;Some time ago I came across &lt;a href=&quot;https://github.com/gurgeous/teleport&quot;&gt;Teleport&lt;/a&gt; which pitches itself as a lightweight way to set up Ubuntu machines. Having failed at mastering the steep learning curve that full-blown tools like &lt;a href=&quot;http://www.opscode.com/chef/&quot;&gt;Chef&lt;/a&gt; or &lt;a href=&quot;http://projects.puppetlabs.com/projects/puppet&quot;&gt;Puppet&lt;/a&gt; provide, I was willing to give Teleport a shot. Teleport stays simple by focusing on Ubuntu and providing just the right set of tools to set up the whole Ruby/Rails eco system. This makes it less powerful than the other aforemention tools, but in my case it’s just what I was looking for.&lt;/p&gt;
                      
                      &lt;h3&gt;Some facts: Teleport …&lt;/h3&gt;
                      
                      &lt;ul&gt;
                      &lt;li&gt;consists of a configuration (Telfile) plus files you want to be present on the target&lt;/li&gt;
                      &lt;li&gt;copies itself onto the target via ssh and then runs itself there (hence the name)&lt;/li&gt;
                      &lt;li&gt;works idempotently - run it over and over again without breaking the target&lt;/li&gt;
                      &lt;/ul&gt;
                      
                      
                      &lt;h3&gt;My setup&lt;/h3&gt;
                      
                      &lt;p&gt;For each project I store everything that belongs to Teleport in a specific &lt;code&gt;deployment&lt;/code&gt; folder. This folder might look something like this:&lt;/p&gt;
                      
                      &lt;pre&gt;&lt;code&gt;|____Telfile
                      |____recipes
                      | |____install_passenger_nginx.rb
                      |____files
                      | |____etc
                      | | |____gemrc
                      | | |____init.d
                      | | | |____nginx
                      | |____Gemfile
                      | |____Gemfile.lock
                      | |____opt
                      | | |____nginx
                      | | | |____conf
                      | | | | |____nginx.conf
                      &lt;/code&gt;&lt;/pre&gt;
                      
                      &lt;p&gt;The configuration is done inside the &lt;code&gt;Telfile&lt;/code&gt;:&lt;/p&gt;
                      
                      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deploy&quot;&lt;/span&gt;
                      &lt;span class=&quot;n&quot;&gt;ruby&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1.9.3&quot;&lt;/span&gt;
                      &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;my-own-vps&quot;&lt;/span&gt;
                      
                      &lt;span class=&quot;n&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;deb http://ppa.launchpad.net/chris-lea/node.js/ubuntu lucid main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;C7917B12&quot;&lt;/span&gt;
                      
                      &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(openssl libreadline5 libreadline5-dev curl&lt;/span&gt;
                      &lt;span class=&quot;sx&quot;&gt;  git-core libopenssl-ruby libcurl4-openssl-dev imagemagick&lt;/span&gt;
                      &lt;span class=&quot;sx&quot;&gt;  libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev&lt;/span&gt;
                      &lt;span class=&quot;sx&quot;&gt;  libmysqlclient-dev mysql-client mysql-server nodejs)&lt;/span&gt;
                      
                      &lt;span class=&quot;n&quot;&gt;recipes&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(&lt;/span&gt;
                      &lt;span class=&quot;sx&quot;&gt;  install_passenger_nginx.rb)&lt;/span&gt;
                      &lt;/pre&gt;
                      &lt;/div&gt;
                      
                      
                      &lt;p&gt;&lt;code&gt;user&lt;/code&gt; defines the name of the account you will later use to deploy your app. This user gets added to the sudoers and your ssh key is uploaded for password-less login. &lt;code&gt;ruby&lt;/code&gt; tells Teleport which version to install and &lt;code&gt;server&lt;/code&gt; is the name you gave to the machine in your &lt;code&gt;~/.ssh/config&lt;/code&gt;.&lt;/p&gt;
                      
                      &lt;p&gt;As you can see you can also define customs apts and packages that should get installed. For performing special setup routines or invoking more complex tasks you can utilize the &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki/Recipes&quot;&gt;recipes&lt;/a&gt; feature. Recipes are standalone files that can be written in Ruby and allow for sharing and reuse. Here’s an example of how to install nginx via the passenger gem:&lt;/p&gt;
                      
                      &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gem_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;passenger&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`passenger-config --version`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;
                      
                      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;
                        &lt;span class=&quot;nb&quot;&gt;warn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Passenger is not installed. Please add it to your Gemfile.&quot;&lt;/span&gt;
                      &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_s&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Passenger &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; is already installed&quot;&lt;/span&gt;
                      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Installing Nginx via Passenger (installed: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_installed&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, gem version: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version_gem&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;passenger-install-nginx-module&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(--auto --auto-download --prefix=/opt/nginx)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# install without prompting&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;update-rc.d nginx defaults&quot;&lt;/span&gt;                                                      &lt;span class=&quot;c1&quot;&gt;# activate autostart&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;service nginx restart&quot;&lt;/span&gt;                                                           &lt;span class=&quot;c1&quot;&gt;# restart nginx&lt;/span&gt;
                      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                      &lt;/pre&gt;
                      &lt;/div&gt;
                      
                      
                      &lt;p&gt;The files directory contains files and directories that get copied over to the target machine - not much magic about that. To install system-wide gems you can place a Gemfile and Gemfile.lock inside the files directory.&lt;/p&gt;
                      
                      &lt;p&gt;Finally you can run the setup with&lt;/p&gt;
                      
                      &lt;pre&gt;&lt;code&gt;$ teleport my-own-vps
                      &lt;/code&gt;&lt;/pre&gt;
                      
                      &lt;p&gt;Keep in mind that you can re-run this every time you make a change to the Telfile or add new files. Teleport strives to be idempotent and can be run  repeatedly without breaking the target machine(unless you explicitely messed up something ;)).&lt;/p&gt;
                      
                      &lt;h3&gt;Let’s go…&lt;/h3&gt;
                      
                      &lt;p&gt;There is much more to Teleport than what I could cover in this short post. For example you can define &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki#wiki-telfile&quot;&gt;multiple servers with different roles&lt;/a&gt; or &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki#wiki-infer&quot;&gt;reverse engineering existing servers&lt;/a&gt; which makes it very easy to generate a Telfile from your current setup. In case you want to get started head over to the &lt;a href=&quot;https://github.com/gurgeous/teleport/wiki&quot;&gt;project wiki&lt;/a&gt; which contains a lot of information and examples.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Capybara Finder for Cucumber Rails’ Deprecated Tableish</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/j0cbf2WPXTQ/capybara-finder-for-cucumber-rails-deprecated-tableish"/>
		<id>http://dennisreimann.de/blog/capybara-finder-for-cucumber-rails-deprecated-tableish</id>
		<updated>2011-11-12T21:35:00+00:00</updated>
		<content type="html">&lt;p&gt;The cucumber-rails gem recently &lt;a href=&quot;https://github.com/cucumber/cucumber-rails/issues/145&quot;&gt;deprecated the tableish method&lt;/a&gt; which could be used to verify data in tables using &lt;a href=&quot;https://github.com/cucumber/cucumber/wiki/multiline-step-arguments&quot;&gt;Table#diff!&lt;/a&gt;. Tableish was easy to use but also had some limitations so that from now on you are advised to use Capybara’s finder API which is much more flexible.&lt;/p&gt;
                        
                        &lt;p&gt;In case you are now searching for a replacement for tableish, look no further:&lt;/p&gt;
                        
                        &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;table#selector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'tr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'th,td'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;expected_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;/pre&gt;
                        &lt;/div&gt;
                        
                        
                        &lt;p&gt;This maps the table into a two dimensional array containing all cell contents. The last line diffs this array against the &lt;code&gt;expected_table&lt;/code&gt; which is the table that’s passed into the step definition like explained on this &lt;a href=&quot;https://github.com/cucumber/cucumber/wiki/multiline-step-arguments&quot;&gt;Cucumber wiki page&lt;/a&gt;.&lt;/p&gt;
                        
                        &lt;p&gt;You’ll have to replace &lt;code&gt;table#selector&lt;/code&gt; with the actual table selector you are looking for.&lt;/p&gt;
                        
                        &lt;p&gt;When using capybara-webkit for testing elements that get inserted into the page via JavaScript I had to change this a little bit, because the finder did not seem to work with capybara-webkit. One can circumvent this by parsing the page body and using the finder on the new result:&lt;/p&gt;
                        
                        &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Capybara&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Simple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;table#selector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'tr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'th,td'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;expected_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diff!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;/pre&gt;
                        &lt;/div&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Global Day of Coderetreat Cologne / Bonn</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/DTiGqXyyQRU/"/>
		<id>http://blog.railslove.com/?p=1154</id>
		<updated>2011-11-03T10:04:54+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://coreyhaines.com/&quot;&gt;Corey Haines&lt;/a&gt; is organizing a Global Day of Coderetreat for the 3rd of December. Many cities world-wide will collaborate and hold local code retreat events. Cologne, especially the &lt;a href=&quot;http://www.coworkingcologne.de/tag/gasmotorenfabrik&quot;&gt;Coworkingspace Gasmotorenfabrik&lt;/a&gt; is one of the hosts. For future details and registration check out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/coreyhaines/coderetreat/wiki/Cologne&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.xing.com/events/global-day-coderetreat-cologne-bonn-821294&quot;&gt;Xing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=DTiGqXyyQRU:uFwj5RjWcSk:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=DTiGqXyyQRU:uFwj5RjWcSk:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=DTiGqXyyQRU:uFwj5RjWcSk:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=DTiGqXyyQRU:uFwj5RjWcSk:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Installing MacVim with Ruby support and Command T on OSX Lion</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/c0P6L6ce7Sw/"/>
		<id>http://blog.railslove.com/?p=1119</id>
		<updated>2011-10-17T17:21:31+00:00</updated>
		<content type="html">&lt;p&gt;When I set up my new Macbook Air recently, I ran into some unexpected problems setting up MacVim &amp;#8211; mostly related to Ruby versions linked against MacVim and the Command T plugin. Here are some notes that might help you.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;&lt;br /&gt;
In case you wonder: MacVim uses it own separate version of vim (installed here: /Applications/MacVim.app/Contents/MacOS/Vim), which is not linked against your own /user/local/bin/vim (or wherever your vim resides), which you or your package manager installed separately. The reason I&amp;#8217;m mentioning this is that if you lack Ruby support in MacVim, compiling vim by hand won&amp;#8217;t help, since MacVim doesn&amp;#8217;t use it.&lt;/p&gt;
&lt;h2&gt;Howto&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;activate your favourite version of Ruby via RVM or rbenv.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;in my case:&lt;br /&gt;
$ ruby -v&lt;br /&gt;
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.0.1]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;run (in case you haven&amp;#8217;t already, download and install the excellent &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt;):&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$ brew install macvim&lt;/p&gt;
&lt;p&gt;* start MacVim with&lt;br /&gt;
$ mvim&lt;br /&gt;
run :version and make sure it lists +ruby (instead of -ruby)&lt;br /&gt;
test Ruby support by invoking&lt;br /&gt;
:ruby nil[]&lt;br /&gt;
which should return a NoMethodError&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; $ mkdir ~/.vim&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt; install &lt;a href=&quot;http://www.vim.org/scripts/script.php?script_id=2332&quot;&gt;Pathogen&lt;/a&gt; (better management of vim plugins, each living in its own subfolder inside ~/.vim/bundle)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to install &lt;a href=&quot;https://github.com/wincent/Command-T&quot;&gt;Command T&lt;/a&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$ cd ~/.vim&lt;br /&gt;
$ git submodule add git://git.wincent.com/command-t.git bundle/command-t&lt;br /&gt;
$ git submodule init&lt;br /&gt;
$ git clone git://git.wincent.com/command-t.git bundle/command-t&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;with the &lt;strong&gt;same&lt;/strong&gt; version of Ruby activated you used to install MacVim (Ruby 1.9.2p290 in my case), run:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;$ cd ~/.vim/bundle/command-t&lt;br /&gt;
$ rake make&lt;/p&gt;
&lt;p&gt;more details in section 4 &amp;#8220;MANAGING USING PATHOGEN&amp;#8221; of: &lt;a href=&quot;https://github.com/wincent/Command-T/blob/master/doc/command-t.txt&quot;&gt;https://github.com/wincent/Command-T/blob/master/doc/command-t.txt&lt;/a&gt;&lt;/p&gt;
&lt;li&gt;create a symlink under Applications:&lt;br /&gt;
$ ln -s /usr/local/Cellar/macvim/7.3-62/MacVim.app /Applications/MacVim.app&amp;nbsp;&lt;/li&gt;
&lt;h2&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;1) Lacking Ruby support inside MacVim&lt;/em&gt;&lt;br /&gt;
&lt;span&gt;Symptom:&lt;/span&gt; Plugins written in Ruby, like Command T or Lusty Juggler, don&amp;#8217;t work.&lt;br /&gt;
Check: $ mvim &amp;#8211;version or :version inside of MacVim should list &amp;#8220;-ruby&amp;#8221;, if your version lacks Ruby support (&amp;#8220;+ruby&amp;#8221; if it has Ruby support built in).&lt;br /&gt;
&lt;span&gt;Cause:&lt;/span&gt; This happens when your version of MacVim was compiled without the &amp;#8211;enable-rubinterp flag. This usually happens when you install a binary off MacVim&amp;#8217;s Google Code Project.&lt;br /&gt;
&lt;span&gt;Remedy:&lt;/span&gt; Best use Homebrew to install MacVim from source. Although the Homebrew command&amp;#8217;s output does not explicitly list the &amp;#8211;enable-rubyinterp flag, you should be fine and :version should list +ruby.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;2) Can&amp;#8217;t compile MacVim or vim&lt;/em&gt;&lt;br /&gt;
&lt;span&gt;Cause:&lt;/span&gt; You probably didn&amp;#8217;t install Xcode. Unfortunately you need proprietary Cocoa headers for MacVim, which are not included in this Kenneth Reitz&amp;#8217; GCC OSX installer (&lt;a href=&quot;https://github.com/kennethreitz/osx-gcc-installer&quot;&gt;https://github.com/kennethreitz/osx-gcc-installer&lt;/a&gt;; cf. related problem: &lt;a href=&quot;https://github.com/mxcl/homebrew/issues/7576&quot;&gt;https://github.com/mxcl/homebrew/issues/7576&lt;/a&gt;).&lt;br /&gt;
&lt;span&gt;Remedy:&lt;/span&gt; Install the full Xcode package via Apple&amp;#8217;s App Store. Make sure to check your Launchpad for download activity &amp;#8211; it took me half an hour to figure out that the app store&amp;#8217;s Install button was actually doing something and not broken.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;3) Command T complains about lacking C extensions&lt;/em&gt;&lt;br /&gt;
&lt;span&gt;Symptom:&lt;/span&gt; Command T doesn&amp;#8217;t start and informs me about missing C extensions.&lt;br /&gt;
&lt;span&gt;Remedy:&lt;/span&gt; run rake make inside ~/.vim/bundle/command-t&lt;/p&gt;
&lt;p&gt;&lt;em&gt;4) Command T causes SIGTERMS&lt;/em&gt;&lt;br /&gt;
&lt;span&gt;Symptom:&lt;/span&gt; After having compiled Command T&amp;#8217;s C extensions, as soon as you try to invoke Command T inside MacVim, it causes the program to crash with a SIGTERM exception.&lt;br /&gt;
&lt;span&gt;Cause:&lt;/span&gt; Usually the reason for the SIGTERM is that your MacVim was compiled with a link to a different version of Ruby than Command T. However, I encountered the same problem when linking everything against system Ruby (1.8.7 in my case).&lt;br /&gt;
&lt;span&gt;Remedy:&lt;/span&gt; Be very careful about your RVM/rbenv settings and ensure the exact same version of Ruby is active when you compile MacVim (installing via Homebrew triggers a compilation process) or Command T. My issue was resolved by using Ruby 1.9.2 instead of system Ruby.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ralph/dotvim&quot;&gt;https://github.com/ralph/dotvim&lt;/a&gt; Ralph&amp;#8217;s .vim files &amp;#8211; certainly more well-honed and better organized than my own.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/paulwittmann/vimrc-osx&quot;&gt;https://github.com/paulwittmann/vimrc-osx&lt;/a&gt; my current .vimrc &amp;amp; plugins on OSX. Still lacking some features, but more cleaned up than my &lt;a href=&quot;https://github.com/paulwittmann/vimrc&quot;&gt;old one&lt;/a&gt; for Ubuntu.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=c0P6L6ce7Sw:VOnSn6NCeIY:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=c0P6L6ce7Sw:VOnSn6NCeIY:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=c0P6L6ce7Sw:VOnSn6NCeIY:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=c0P6L6ce7Sw:VOnSn6NCeIY:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">“Birthday” gem for easy anniversaries handling</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/OI8_xaqFRyY/"/>
		<id>http://blog.railslove.com/?p=1112</id>
		<updated>2011-10-17T09:59:10+00:00</updated>
		<content type="html">&lt;p&gt;While working on one of our client projects, I was asked to create a search for users&amp;#8217; birthdays. Instantly, I remembered what problems I had with it in the past, like taking care of not only finding the right dates by only day and month, but also, checking for birthdays today, any upcoming birthdays, or even just looking up user&amp;#8217;s age based on that information.&lt;/p&gt;
&lt;p&gt;So, to never ever repeat that code again (and to keep the code DRY), I&amp;#8217;ve decided to write a simple gem specifically for this stuff. And thus the &lt;a href=&quot;https://github.com/railslove/birthday&quot;&gt;&lt;tt&gt;birthday&lt;/tt&gt; gem&lt;/a&gt; was born.&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;p&gt;The gem has been tested against Rails 3 (3.0.9) and Rails 2 (2.3.14), and depends on ActiveRecord and ActiveSupport (for inflections), making it a perfect fit for Rails. It is possible to use it outside Rails project, but you are required to use ActiveRecord as your ORM framework.&lt;/p&gt;
&lt;p&gt;The gem works with MySQL and PostgreSQL adapters, but you can &lt;a href=&quot;https://github.com/railslove/birthday/blob/master/README.md&quot;&gt;write your own adapters&lt;/a&gt;, if you need to. If you do so, it would be good to fork the gem and add it there for everybody to use. :)&lt;/p&gt;
&lt;h3&gt;So, how does it actually work?&lt;/h3&gt;
&lt;p&gt;Handling birthdays wasn&amp;#8217;t that easy before. Here&amp;#8217;s what you have to do in your model:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s all. This one line enables extra actions on the &amp;#8220;birthday&amp;#8221; field (of DATE or DATETIME types) in your database. For example from now on you can search for birthdays&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on a specific date:&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;between a specific range:&lt;br /&gt;

&lt;/li&gt;
&lt;li&gt;and even at the turn of the years:&lt;br /&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All these methods are essentially scopes, so you could also do something like:&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;On top of that, you get convenience methods for single records, like getting the age:&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;You can get any field to behave like this. For example, let&amp;#8217;s say we want marriage anniversaries:&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;And it&amp;#8217;s done, from now on you have convenient scopes to search and handle anniversaries:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;Final words&lt;/h3&gt;
&lt;p&gt;I&amp;#8217;ve done this gem, because I never ever want to write this piece of code again, I&amp;#8217;d rather spend my time on actually coding the important stuff in applications, than to fiddle around with dates and birthdays. Hope this gem will be of some use to you. If not, fork it, and patch it to your needs! :)&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=OI8_xaqFRyY:8xTsTp8y5tM:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=OI8_xaqFRyY:8xTsTp8y5tM:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=OI8_xaqFRyY:8xTsTp8y5tM:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=OI8_xaqFRyY:8xTsTp8y5tM:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Backlash @ Robot Unicorn Invasion Party 2011</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/O11FrWs1c-8/"/>
		<id>http://blog.railslove.com/?p=1109</id>
		<updated>2011-10-13T15:05:42+00:00</updated>
		<content type="html">&lt;div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://www.mixcloud.com/backslash/backlash-robot-unicorn-invasion-party-2011/#utm_source=widget&amp;utm_medium=web&amp;utm_campaign=base_links&amp;utm_term=resource_link&quot; target=&quot;_blank&quot;&gt;Backlash @ Robot Unicorn Invasion Party 2011&lt;/a&gt;&lt;span&gt; by &lt;/span&gt;&lt;a href=&quot;http://www.mixcloud.com/backslash/#utm_source=widget&amp;utm_medium=web&amp;utm_campaign=base_links&amp;utm_term=profile_link&quot; target=&quot;_blank&quot;&gt;Backslash&lt;/a&gt;&lt;span&gt; on &lt;/span&gt;&lt;a href=&quot;http://www.mixcloud.com/#utm_source=widget&amp;utm_medium=web&amp;utm_campaign=base_links&amp;utm_term=homepage_link&quot; target=&quot;_blank&quot;&gt; Mixcloud&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=O11FrWs1c-8:pY_YwGoo9Rw:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=O11FrWs1c-8:pY_YwGoo9Rw:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=O11FrWs1c-8:pY_YwGoo9Rw:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=O11FrWs1c-8:pY_YwGoo9Rw:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Help You need somebody; Help not just anybody!</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/BoNP4Iez2qU/"/>
		<id>http://blog.railslove.com/?p=1058</id>
		<updated>2011-10-11T22:36:28+00:00</updated>
		<content type="html">&lt;p&gt;Here at Railslove, we love building web applications. But aside from our core business, we also help other startups understand how the web works and what it means to run a web business &amp;#8212; in Hamburg, Berlin, Cologne. And since experienced Ruby on Rails developers are increasingly hard to find, we&amp;#8217;ve started to offer apprenticeships, too.&lt;/p&gt;
&lt;p&gt;One of our new partners is &lt;a href=&quot;http://dailydeal.de/&quot;&gt;DailyDeal&lt;/a&gt;. We&amp;#8217;ve done some beginners and advanced courses in Rails covering stuff like testing, building APIs, advanced JavaScript coding and general design and programming patterns in Ruby on Rails, etc.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.xing.com/profile/Oliver_Hepfner&quot;&gt;Oliver Hepfner&lt;/a&gt;, Director Software Engineering of &lt;a href=&quot;http://dailydeal.de/&quot;&gt;DailyDeal&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The training Railslove provided under the direction of Georg Leciejewski helped us understand advanced programming patterns in Ruby on Rails. Our developers were excited to get a hands-on introduction into Ruby on Rails.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next month, we will launch a few more courses with &lt;a href=&quot;http://railslove.com/items/daily_deal&quot;&gt;DailyDeal&lt;/a&gt; and with other companies, like &lt;a href=&quot;http://adcloud.com&quot;&gt;Adcloud GmbH&lt;/a&gt; in Germany. If you are interested in learning more, please contact Ralph and Georg: ralph AT railslove.com &amp;#038; gl AT salesking.eu &amp;#038; team AT railslove.com&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=BoNP4Iez2qU:6MKsivVAUKM:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=BoNP4Iez2qU:6MKsivVAUKM:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=BoNP4Iez2qU:6MKsivVAUKM:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=BoNP4Iez2qU:6MKsivVAUKM:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Travis – a distributed build system</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/0UCan9a--EY/"/>
		<id>http://blog.railslove.com/?p=1067</id>
		<updated>2011-10-03T20:04:29+00:00</updated>
		<content type="html">&lt;p&gt;Let us introduce us to Travis. What is Travis? As you can read on Github:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Travis is an attempt to create an open-source, distributed build system for the Ruby community that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;allows open-source projects to register their repository and have their test-suites run on demand&lt;/li&gt;
&lt;li&gt;allows users to contribute build capacities by connecting a VM that runs a build agent somewhere on their underused servers&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/10/safe_image.png&quot;&gt;&lt;img class=&quot;size-full wp-image-1068&quot; title=&quot;Travis Logo&quot; src=&quot;http://blog.railslove.com/wp-content/uploads/2011/10/safe_image.png&quot; alt=&quot;Travis Logo&quot; width=&quot;90&quot; height=&quot;90&quot; /&gt;&lt;/a&gt; You can and should use travis for your open source projects as an continuos integration system. Travis is an incredible project and helps increase the quality of  lots of Open Source projects. So please head over to &lt;a href=&quot;http://travis-ci.org&quot;&gt;travis&lt;/a&gt; and setup tests for your ruby, node.js, erlang, &amp;#8230; projects. &amp;#8211; you can also setup your own instance installing Travis and use it for your private projects.&lt;/p&gt;
&lt;p&gt;For more information check out &lt;a href=&quot;https://github.com/travis-ci/travis-ci&quot;&gt;the github page&lt;/a&gt; and &lt;a href=&quot;http://about.travis-ci.org/docs/user/getting-started/&quot;&gt;the getting started section&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re really happy to be able to support Travis by sponsoring one of the worker boxes.&lt;/p&gt;
&lt;p&gt;btw. Sven, Josh, thanks for mentioning us on your talks at &lt;a href=&quot;http://rulu.eu/speakers#sven-fuchs&quot;&gt;Ruby Lugdunum&lt;/a&gt; and &lt;a href=&quot;https://frozenrails.eu/sessions#sven&quot;&gt;Frozen Rails 2011&lt;/a&gt; this year. ;)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/10/Screen-Shot-2011-10-03-at-9.44.26-PM.png&quot;&gt; &lt;img class=&quot;alignleft size-medium wp-image-1079&quot; title=&quot;Travis Sponsors&quot; src=&quot;http://blog.railslove.com/wp-content/uploads/2011/10/Screen-Shot-2011-10-03-at-9.44.26-PM.png&quot; alt=&quot;&quot; width=&quot;500px&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Btw.: have you heard about the &lt;a href=&quot;http://feeds.feedburner.com/awesomebotfactory.com&quot;&gt;Awesome Bot Factory&lt;/a&gt;? With the Awesome Bot Factory you&amp;#8217;re able to create bots for your campfire channel. There is a bot to integrate travis to your campfire chat: simply ask the bot for a given status, like:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Jan    travis:status Nerds/NerdPursuit&lt;br /&gt;
Choco Bits Bot    Nerds/NerdPursuit is stable&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Or get notified about your project&amp;#8217;s new travis builds.&lt;/p&gt;
&lt;p&gt;- Thank you, Travis-CI!&lt;/p&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Travis on Twitter: &lt;a href=&quot;http://feeds.feedburner.com/twitter.com/travisci&quot;&gt;@travisci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Travis on Github: &lt;a href=&quot;https://github.com/travis-ci/&quot;&gt;travis-ci&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Homepage: &lt;a href=&quot;http://travis-ci.org&quot;&gt;travis-ci.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=0UCan9a--EY:WbJsAxoHOOM:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=0UCan9a--EY:WbJsAxoHOOM:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=0UCan9a--EY:WbJsAxoHOOM:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=0UCan9a--EY:WbJsAxoHOOM:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The DevHouseFriday Chillout and the stolen Adcloud chair</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/qJVQ-w7w1SI/"/>
		<id>http://blog.railslove.com/?p=1041</id>
		<updated>2011-09-27T12:01:54+00:00</updated>
		<content type="html">&lt;p&gt;First of all &amp;#8211; a big, big thank you to &lt;a href=&quot;http://twitter.com/adcloud&quot;&gt;@adcloud&lt;/a&gt; for hosting last DevHouseFriday. The location is perfect for such events &amp;#8211; nice conference room, a terrace, free beer and some food. Thanks again!&lt;/p&gt;
&lt;p&gt;The last DevHouseFriday had cool talks too: &lt;a href=&quot;http://twitter.com/tisba&quot;&gt;@tisba&lt;/a&gt; talked about loadtesting in the cloud &lt;a href=&quot;http://twitter.com/killerg&quot;&gt;@killerg&lt;/a&gt; was talking about his PDF-Dragon idea, we had a interesting talk about &lt;a href=&quot;http://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt; and &lt;a href=&quot;http://javac.info/&quot;&gt;Closures for Java&lt;/a&gt; (by TJ) so, thanks again.&lt;/p&gt;
&lt;p&gt;Unfortunately someone has stolen an &lt;a href=&quot;http://twitter.com/adcloud&quot;&gt;@adcloud&lt;/a&gt; chair from the office. Turns out it was one of the Railslove guys. At the event only handful of Railslovers were present: &lt;a href=&quot;http://railslove.com/items/georg_leciejewski&quot;&gt;Georg&lt;/a&gt;, &lt;a href=&quot;http://railslove.com/items/jan_kus&quot;&gt;Jan&lt;/a&gt;, &lt;a href=&quot;http://railslove.com/items/lars_brillert&quot;&gt;Lars&lt;/a&gt;, &lt;a href=&quot;http://railslove.com/items/michael_bumann&quot;&gt;Michael&lt;/a&gt; and &lt;a href=&quot;http://railslove.com/items/dirk_jost&quot;&gt;Dirk&lt;/a&gt;&amp;#8230;. Apparently, it was Jan. He got his punishment for this. Now this Chair is his burden to bear, and he has to take it on every other DevHouseFriday Chillout meetup. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://s3.amazonaws.com/imgly_production/2091803/large.jpg&quot; alt=&quot;the devhousefriday chair&quot; width=&quot;500px&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So, see you next time, the next DevHouse Friday Chillout is on the October, 21th. Venue will be announced soon. Jan the Chairman will also be there to throw rocks at.&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qJVQ-w7w1SI:Vm64t5NTLWw:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qJVQ-w7w1SI:Vm64t5NTLWw:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=qJVQ-w7w1SI:Vm64t5NTLWw:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=qJVQ-w7w1SI:Vm64t5NTLWw:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">10th anniversary of Polish Wikipedia</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/ubPpz4Rgot0/"/>
		<id>http://blog.railslove.com/?p=1023</id>
		<updated>2011-09-27T10:02:43+00:00</updated>
		<content type="html">&lt;p&gt;Last weekend, as a long-standing &lt;a href=&quot;http://pl.wikipedia.org/wiki/User:Holek&quot;&gt;Polish Wikipedian&lt;/a&gt;, I went to &lt;a href=&quot;http://en.wikipedia.org/wiki/Poznań&quot;&gt;Poznań&lt;/a&gt; to celebrate the 10th anniversary of Polish Wikipedia.&lt;/p&gt;
&lt;p&gt;The event started on Friday, September 23th and went on until Monday, September 26th, the actual date of establishing Polish Wikipedia. During that time, I&amp;#8217;ve met old friends, colleagues, and newcomers to our project. The event took place in &lt;a href=&quot;http://multikino.pl/pl/wszystkie-kina/poznan-stary-browar/o-kinie/&quot;&gt;Multikino cinema&lt;/a&gt; in &lt;a href=&quot;http://en.wikipedia.org/wiki/Stary_Browar&quot;&gt;Shopping, Arts and Business Center &amp;#8220;Stary Browar&amp;#8221;&lt;/a&gt; (&lt;abbr title=&quot;literally&quot;&gt;lit.&lt;/abbr&gt; &amp;#8220;Old Brewery&amp;#8221;), a place dating back to 1844, when Ambrosius Hugger, a Wirtembergian brewer, came to Poznań to start his brewery there.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Stary_Browar_Pozna%C5%84_RB1.JPG&quot;&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Stary_Browar_Pozna%C5%84_RB1.JPG/500px-Stary_Browar_Pozna%C5%84_RB1.JPG&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;small&gt;Author: Radomil. License: CC-BY-SA&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;Almost 200 people came to celebrate with us and to participate in talks and presentations, making it the biggest Wikipedia meet-up in Poland so far. As usual, there were also guests from other countries: we were visited by Wikipedians from Germany, Czech, Belarus, Philippines, Hungary, Ukraine and Russia. On Friday we spent time on getting together, drinking beer and organizing our stay in hostels.&lt;/p&gt;
&lt;p&gt;The actual event started on Saturday with a discussion between founders of Polish Wikipedia, Paweł Jochym and Krzysztof Jasiutowicz, who told us about the beginnings of Polish Wikipedia and how they imagine its future. What&amp;#8217;s worth noting this is also the first time these founders actually met each other. Before now they only collaborated on the encyclopedia online, and we&amp;#8217;ve never seen them together during one conference. Other speakers included: Jan Wróbel (a contributor to a weekly newsmagazine &lt;a href=&quot;http://en.wikipedia.org/wiki/Wprost&quot;&gt;Wprost&lt;/a&gt;), Piotr Marcinkowski (vicepresident of Library of University of Poznań), Sylwia Ufnalska (translator and science journalist), Jarosław Lipszyc (president of Modern Poland Foundation) and Edwin Bendyk (famous editor, blogger and journalist).&lt;/p&gt;
&lt;p&gt;We also had a chance to see a documentary &lt;a href=&quot;http://en.wikipedia.org/wiki/Truth_in_Numbers%3F&quot;&gt;&lt;em&gt;Truth in Numbers? Everything, According to Wikipedia&lt;/em&gt;&lt;/a&gt;, which explores the history and cultural implications of the online user-editable encyclopedia Wikipedia. The film attempts to answer the question of whether all kinds of individuals or just experts should be tasked with editing an encyclopedia.&lt;/p&gt;
&lt;p&gt;Apart from that, there was a surprise made by Wikimedia Polska Association for all editors: a video with congratulations on the anniversary from famous Polish people:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Congratulations for our work were given from: Polish president Bronisław Komorowski, professor Jerzy Bralczyk, Bartłomiej Chaciński, Ilona Łepkowska, Marek Niedźwiecki, Krzysztof Skowroński, Mariusz Szczygieł and Ewa Wachowicz. President Komorowski encouraged to edit Wikipedia and share the knowledge, Mariusz Szczygieł and Marek Niedźwiecki admitted Wikipedia helps them in their work, and professor Bralczyk expressed his pride in Polish Wikipedia being one of the biggest language version of this encyclopedia.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Grupowe_2.jpg&quot;&gt;&lt;img src=&quot;http://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Grupowe_2.jpg/500px-Grupowe_2.jpg&quot; alt=&quot;Group photo of all attendees&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;small&gt;Author: Polimerek. License: CC-BY-SA 3.0&lt;/small&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;And thus, the event concluded on Sunday, with a group photo of all the attendees, after which all of us started going home, tired, but happy after seeing each other again, hoping we can make the best of this great project, to which we contributed over past decade. And that is what I wish to Polish Wikipedia for this and next decades to come! Let&amp;#8217;s make the best encyclopedia ever!&lt;/p&gt;
&lt;p&gt;Photos from the event are available on various free licenses on Wikimedia Commons in [[&lt;a href=&quot;http://commons.wikimedia.org/wiki/Category:10th_birthday_of_Polish_Wikipedia&quot;&gt;Category:10th birthday of Polish Wikipedia&lt;/a&gt;]]&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ubPpz4Rgot0:xbIEP_lpQQc:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ubPpz4Rgot0:xbIEP_lpQQc:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=ubPpz4Rgot0:xbIEP_lpQQc:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=ubPpz4Rgot0:xbIEP_lpQQc:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">An Update On The NoSQL Handbook</title>
		<link href="http://www.paperplanes.de//2011/9/7/an-update-on-the-nosql-handbook.html"/>
		<id>http://www.paperplanes.de//2011/9/7/an-update-on-the-nosql-handbook.html</id>
		<updated>2011-09-07T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;A couple of months ago I set out to write a &lt;a href=&quot;http://nosqlhandbook.com&quot;&gt;book on
NoSQL&lt;/a&gt;. It's about time I give an update on how it's
been going, and when you can expect a book in your hands, or rather, on your
screen.&lt;/p&gt;

&lt;p&gt;After an initial burst of writing, I took somewhat of a break, so please excuse
the delay in general. I spent the last weeks writing (a lot), and I'm currently
trying to polish and finish up the existing content so that I can throw
something out there for the world to peek at. Currently, the book covers
MongoDB, Riak and Redis in varying detail, and I'm working to finish up loose
ends to get into a good shape, before I'm starting work on more chapters.&lt;/p&gt;

&lt;p&gt;A lot of people have asked me about pricing, distribution model, updates, and so
on, so I'm following up with an FAQ section. In general, I'm as keen to get
something out there as people have expressed their interest in reading it,
believe me.&lt;/p&gt;

&lt;p&gt;Turns out though: writing a book is hard. It takes a lot of work, a lot of
discipline and creativity to come up with the right words and code examples. I'm
not complaining, it's just something you don't realize from writing even
slightly longer blog posts. It's still an incredible learning experience too,
because I (and you) get to play with pretty much all of the features the
databases covered have to offer.&lt;/p&gt;

&lt;p&gt;So bear with me, I'm on it.&lt;/p&gt;

&lt;p&gt;The book is not built around the idea that a big application is to be built with
each database. I'm not a fan of that approach myself, as it makes it too easy to
lose track of details. It's full of small examples, focused on specific
features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many pages does it have?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As the book is still growing, and I'm still playing with layouting details, I
can't give you an exact number, but the final book is probably going to have
more than 200 pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the pricing going to be?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I haven't decided yet. It's not going to be in the single digits pricing range,
and as the book is pretty dense with content, I don't want to undercharge. I'll
keep you posted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will there be early access to the book?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, there will be. You'll be able to buy the beta of the book for a reduced
price, and follow the updates. Maybe even the commits on GitHub? I don't know.
Let &lt;a href=&quot;mailto:meyer@paperplanes.de&quot;&gt;me know&lt;/a&gt; if that's something you're interested
in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you have some samples I can peek at?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not yet. Layout is still far from final, but I'll throw something out as soon as
an early access will be available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What databases are being covered?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To reach my goal for a final release, I'm covering Redis, MongoDB, CouchDB,
Riak, and Cassandra, all in varying detail. For some it makes more sense to go
deeper than for others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are future updates included?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, as content gets added, typos get fixed, and new databases pop up, I'll send
updates to everyone buying the book. The updates are free. Consider buying the
book a subscription for more chapters on other databases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are you extending the book with more databases over time?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, I have an insatiable thirst to play with more databases, and I don't want
to deprive you of experiencing that too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are you covering database SomeDB? I hear it's the next big thing!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For now, the list of databases is fixed. What's coming after that, on the other
hand, is not. I'm open to suggestions, but I'd prefer some non-exotic over a
very domain-specific database you wrote for a recent project. I'll set up some
sort of voting when the final release is done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What formats will be available?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm currently working on PDF and ePub, with Kindle to follow. Gotta have my
priorities. A good-looking and readable PDF is my first priority, an ePub after
that. Buying the book includes access to all formats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there going to be a print edition?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Print is not a priority right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are you using to write and generate the book?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The book is written in Markdown (I hate LaTeX), converted to HTML using
&lt;a href=&quot;https://github.com/tanoku/redcarpet&quot;&gt;Redcarpet&lt;/a&gt;, using
&lt;a href=&quot;https://github.com/github/albino&quot;&gt;Albino&lt;/a&gt; for syntax-highlighting, and
converted to PDF using the awesome &lt;a href=&quot;http://www.princexml.com/&quot;&gt;Prince XML&lt;/a&gt;
library, I hope to eventually use &lt;a href=&quot;http://docraptor.com/&quot;&gt;DocRaptor&lt;/a&gt; to create
the final result, as a Prince license is slightly out of budget, but DocRaptor
is pretty affordable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where can I get updates on progress?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mostly be following &lt;a href=&quot;http://twitter.com/roidrage&quot;&gt;me&lt;/a&gt; or &lt;a href=&quot;http://twitter.com/nosqlhandbook&quot;&gt;the handbook
itself&lt;/a&gt; on Twitter.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/Kp3Ym7tdY80&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Die Internetwoche Köln</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/tDcxdjib-fw/"/>
		<id>http://blog.railslove.com/?p=1012</id>
		<updated>2011-09-06T00:54:36+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/09/IWK-Logo_101_Q-500.png&quot;&gt;&lt;img src=&quot;http://blog.railslove.com/wp-content/uploads/2011/09/IWK-Logo_101_Q-500-291x300.png&quot; alt=&quot;&quot; title=&quot;IWK-Logo_101_Q-500&quot; width=&quot;100&quot; class=&quot;aligncenter size-medium wp-image-1019&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
Und wieder ist es soweit: die Internetwoche Köln 2011 findet zwischen dem 19.09.2011 &amp;#8211; 23.09.2011 statt. Die Internetwoche Köln ist eine Plattform für Kölner Internetstartups in der Veranstaltungen rund um das Thema Web-Business organisiert werden.&lt;/p&gt;
&lt;p&gt;Wir möchten Euch herzlich zu folgenden Events einladen:&lt;/p&gt;
&lt;h2&gt;Montag&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.eco.de/veranstaltungen/1164_9312.htm&quot;&gt;Das Unternehmerfrühstück im Rahmen der Internetwoche Köln&lt;/a&gt; wo wir auch Railslove kurz in einem Vortrag vorstellen werden. Start 9:15 im eco Kubus&lt;br /&gt;
Lichtstraße 43 i&lt;/li&gt;
&lt;li&gt;Der 26. Webmontag in Köln natürlich unter Moderation von Rene Bredlau. Ab 19:00 im Spielplatz. Ubierring.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mittwoch&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://limited-wip-society-cologne.grouply.com/&quot;&gt;Limited WIP Society Cologne -Kanban User Group Köln&lt;/a&gt;. In der Gasmotorenfabrik ab 19:00&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dmexco.de/&quot;&gt;dmexco &amp;#8211; Digital Marketing Exposition and Conference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Donnerstag&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.dmexco.de/&quot;&gt;dmexco &amp;#8211; Digital Marketing Exposition and Conference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Freitag&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Das DevHouse Friday Chillout. Start 19:00. Ort wird noch bekannt gegeben.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Das Railslove-Team freut sich auf gemeinsame spannende Talks während der Internetwoche Köln.&lt;/p&gt;
&lt;h2&gt;Was ist die Internetwoche Köln?&lt;/h2&gt;
&lt;blockquote&gt;&lt;p&gt;Internetwoche Köln: Netz-Know-how und Networking&lt;/p&gt;
&lt;p&gt;Zum zweiten Mal bieten Kölner Unternehmen in der Internetwoche Köln vom 19. bis 25. September Businesswissen rund um das Internet: Ein Unternehmerfrühstück zum Start bereitet den Boden für lokales Networking, die internationale Advance Conference vernetzt Start-ups und Investoren und zahlreiche Workshops liefern viele Antworten: Wie präsentiere ich mein Unternehmen im Netz? Wie mache ich einen QR-Tag? Wie bekomme ich meine eigenen Top-Level-Domain? Wie geht Online-Lernen? Ist die Cloud eine Option für mein Unternehmen? Wie gestalte ich meinen Büroalltag effizienter?&lt;br /&gt;
Organisatoren der Internetwoche Köln sind eco &amp;#8211; Verband der deutschen Internetwirtschaft und die Köner Internet-Union (KIU).&lt;/p&gt;
&lt;p&gt;Alle Veranstaltungen finden sich unter http://iwcgn.koeln.de/.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=tDcxdjib-fw:NPVywl99uRA:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=tDcxdjib-fw:NPVywl99uRA:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=tDcxdjib-fw:NPVywl99uRA:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=tDcxdjib-fw:NPVywl99uRA:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">JSON Schema Baby</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/KSYCO_zqvf8/"/>
		<id>http://blog.railslove.com/?p=1001</id>
		<updated>2011-09-05T17:43:02+00:00</updated>
		<content type="html">&lt;p&gt;Building an application programming interface is not easy. Designing an API is more complex than just writing code. For a few projects we tried out different approaches to implement an API in Ruby on Rails. There are two main ways to make your resources accessible:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;using the standard to_json renderer built into Rails&lt;/li&gt;
&lt;li&gt;building your own views&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Using standard renderer provided by Rails&lt;/h2&gt;
&lt;p&gt;In Rails 2.0 you have the possibility to using the respond_to block to expose your resource in whatever format you rewuire (xml, json, html). E.g.:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The same is possible in Rails 3.0 but a little bit easier:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In these examples you can define the representation of your resource by defining the format you want the resource to be represented in. But in most cases you don&amp;#8217;t want to expose every attribute of your resource. To achieve this, you could use Rails&amp;#8217; as_json method to create a custom JSON structure of your resource. E.g:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;As Jonathan Julian mentioned &lt;a href=&quot;http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/&quot;&gt;in his blog post&lt;/a&gt;, call as_json directly or override it in your model to customize your representation of your resource. Sounds easy so far. Summarizing this approach we can say:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It is understandable and quite easy to use&lt;/li&gt;
&lt;li&gt;You can easily customize the representation of your resources via the as_json method&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But the way how this approach is realized is not the best in my opinion, because it too much correlated with the models when we talking only about a &amp;#8220;representation&amp;#8221;. That&amp;#8217;s why I like the second approch &amp;#8211; building your own views.&lt;/p&gt;
&lt;h2&gt;Customize it baby&lt;/h2&gt;
&lt;p&gt;What does it exactly mean? Instead of just overriding the as_json method in your model, build a template that exposes your API. The easiest way is, e.g., to use RABL &amp;#8211; Ruby API Templating Language.&lt;/p&gt;
&lt;p&gt;As in the example before you define within your controller structure WHICH resources are being exposed, like:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And within your RABL-Template now you can define HOW your resources should look:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;What happened here is that the representation of the resource is properly split from the resource using templates, like using .html-templates that belongs to your views. Thats great. You&amp;#8217;re very flexible to define how the respresentation should looks like without overriding some methods. The resource is exposed &amp;#8216;as it is&amp;#8217; but the template takes the response of what representation exactly the API users should get. In general, that seems to be the right approach; and it really is, but for me it isn&amp;#8217;t going far enough. What I like to see is an even looser representation.&lt;/p&gt;
&lt;h2&gt;Here comes JSON-Schema&lt;/h2&gt;
&lt;p&gt;Now we&amp;#8217;re going a step further and completely split our resource from the representation. Based on JSON-Schema (http://json-schema.org/) we&amp;#8217;re going to define one that is responsible how our resource is being represented. With this approach, it is also possible to define our yourself in which way you want to interpret the schema within your code. And it&amp;#8217;s fully decorrelated if you want to.&lt;/p&gt;
&lt;p&gt;If found a very good approach for using the JSON-Schema for an API representation (sk_api_schema &amp;#8211; https://github.com/salesking/sk_api_schema) &amp;#8211; a Ruby library that defines the schema which takes care of the representation of their API resources.&lt;/p&gt;
&lt;p&gt;How does it work? Your controllers are almost the same. E.g.:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The only small difference is the object_as_json method, which is provided by your own schema library. This method takes the properties defined in the schema and looks them up on the object in question.&lt;/p&gt;
&lt;p&gt;Within your schema for a single resource looks like this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the schema described everything:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;resource itself&lt;/em&gt; &amp;#8211; here a user&lt;/li&gt;
&lt;li&gt;Its &lt;em&gt;properties&lt;/em&gt; &amp;#8211; the attributes of this resource&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Links&lt;/em&gt; belonging to this resource &amp;#8211; These describe some nested resources which belong to this resource and you can also define search parameters here&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And there&amp;#8217;s even one more big advantage: publishing your JSON-Schema library gives your API users a good and clean documentation of your interface. You don&amp;#8217;t have to describe it anymore. Moreover, it could be possible to generate a nicer representation from your documentation. You can see an example of thishere: http://sk-api-browser.heroku.com/. This API browser reads the JSON-Schema here and generates a nice overview of the API.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;What I tried to describe here were some facts about how to implement an API with Ruby on Rails but more about how to split the resource itself from the representation in your webservice. For this you can use internal methods responsible for representing your resource, or create your own templates with defined libraries like RABL. Using JSON schema for the representation of your API is the most loosely coupled approach. With JSON schema you&amp;#8217;re don&amp;#8217;t care about the resource&amp;#8217;s representation within your code but reather within your schema. It&amp;#8217;s a description of whatever you want to expose to your clients.&lt;/p&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://sk-api-browser.heroku.com/&quot;&gt;A JSON schema browser&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/salesking/sk_api_schema&quot;&gt;SalesKing API schema&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://json-schema.org/&quot;&gt;JSON schema&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nesquena/rabl/wiki/Set-up-rabl-for-Ruby-on-Rails&quot;&gt;Set up RABL for Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://teohm.github.com/2011/05/using-rabl-in-rails-json-web-api&quot;&gt;Using RABL in Rails JSON Web API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nesquena/rabl&quot;&gt;RABL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rubyflow.com/items/5649-rabl-the-ruby-api-templating-language&quot;&gt;RABL, The Ruby API Templating Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/&quot;&gt;Rails to_json or as_json?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=KSYCO_zqvf8:1hC_oMwQsRc:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=KSYCO_zqvf8:1hC_oMwQsRc:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=KSYCO_zqvf8:1hC_oMwQsRc:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=KSYCO_zqvf8:1hC_oMwQsRc:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Nerds/Cookbooks</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/Ac2NXiORrDc/"/>
		<id>http://blog.railslove.com/?p=997</id>
		<updated>2011-08-23T17:52:09+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://www.urbandictionary.com/define.php?term=What's%20cookin%20good%20lookin%3F&quot;&gt;What&amp;#8217;s cookin good lookin?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Beside our NerdPursuit project, we&amp;#8217;re proud to invite the &lt;a href=&quot;https://github.com/Nerds/Cookbooks&quot;&gt;Nerds/Cookbooks&lt;/a&gt; project today. Go ahead and create real recipes for real nerds today!&lt;/p&gt;
&lt;p&gt;The Recipe of the day: fried egg with applesauce and mashed potatoes&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ac2NXiORrDc:YfYW36kiRLw:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ac2NXiORrDc:YfYW36kiRLw:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=Ac2NXiORrDc:YfYW36kiRLw:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=Ac2NXiORrDc:YfYW36kiRLw:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">DevHouse Friday @ Simfy</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/s36izamms2w/"/>
		<id>http://blog.railslove.com/?p=986</id>
		<updated>2011-08-15T16:52:35+00:00</updated>
		<content type="html">&lt;div&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/03/DevHouse-Friday-Logo.jpeg&quot;&gt;&lt;img title=&quot;DevHouse Friday Logo&quot; src=&quot;http://blog.railslove.com/wp-content/uploads/2011/03/DevHouse-Friday-Logo.jpeg&quot; alt=&quot;&quot; width=&quot;126&quot; height=&quot;126&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
Dieses mal gastiert der DevHouse Friday bei &lt;a href=&quot;http://www.simfy.de&quot; target=&quot;_blank&quot;&gt;simfy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Kickertisch, Terasse, Beamer als auch fette Beschallung sind vorhanden.&lt;/p&gt;
&lt;p&gt;Wenn das nicht genug Argumente sind vorbei zu kommen, legt simfy noch einen Premium-Gutschein für einen Monat drauf.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;WANN:&lt;/strong&gt; 19.08.2011 ab: 19:00 Uhr
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;WO: &lt;a href=&quot;http://maps.google.de/maps/place?q=Simfy,+Vogelsanger+Str.,+187&amp;hl=de&amp;cid=4487133234066811329&quot; target=&quot;_blank&quot;&gt; simfy GmbH, Vogelsanger Straße 187, Köln&lt;/a&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;WAS:&lt;/strong&gt; Guter Musikgeschmack!
&lt;/p&gt;
&lt;p&gt;
MORE: &lt;a href=&quot;http://devhousefriday.org/&quot;&gt;http://devhousefriday.org/&lt;/a&gt; AND &lt;a href=&quot;http://twitter.com/devhousefriday&quot;&gt;@devhousefriday&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Der erste Rock&amp;#8217;n'Roll Devhouse Friday erwartet euch!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://corporate.simfy.com/fileadmin/tmpl/images/logo_simfy_11.gif&quot; alt=&quot;Simfy Logo&quot; /&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; and the Friday, 19th of August is, of course, the &lt;a href=&quot;http://whyday.org/&quot;&gt;Whyday&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=s36izamms2w:ENbGCxscZ-Q:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=s36izamms2w:ENbGCxscZ-Q:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=s36izamms2w:ENbGCxscZ-Q:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=s36izamms2w:ENbGCxscZ-Q:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Nerds/NerdPursuit</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/h0MWZ1l-UNY/"/>
		<id>http://blog.railslove.com/?p=980</id>
		<updated>2011-08-14T20:35:07+00:00</updated>
		<content type="html">&lt;p&gt;For nerds, from nerds.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve presented this projects a few times at &lt;a href=&quot;http://webmontag.de&quot;&gt;Webmontag Köln&lt;/a&gt; and &lt;a href=&quot;http://devhousefriday.org&quot;&gt;DevHouse Friday Chillout&lt;/a&gt; @ &lt;a href=&quot;http://www.papaya-cms.com/&quot;&gt;Papaya&lt;/a&gt; and &lt;a href=&quot;http://www.millepondo.de/&quot;&gt;Millepondo&lt;/a&gt;. Now we have about &lt;a href=&quot;https://github.com/Nerds/NerdPursuit/tree/master/questions&quot;&gt;100 Questions in 14 different Topics (algorithms/ bash/ couchdb/ css/ culture/ flash/ grafix/ html/ http/ javascript/ php/ rails/ regex/ ruby/)&lt;/a&gt; . But we&amp;#8217;re still missing many.&lt;/p&gt;
&lt;p&gt;Beside creating new questions we&amp;#8217;re working on an offline game &amp;#8211; and hey &lt;a href=&quot;http://9elements.com/&quot;&gt;9elements&lt;/a&gt; brought to us &amp;#8211; a real time nerd pursuit game &amp;#8211; fuck yeah! (will be linked soon).&lt;/p&gt;
&lt;p&gt;Participate and send us as much pull requests as you can!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=h0MWZ1l-UNY:wL3BGdI4B8A:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=h0MWZ1l-UNY:wL3BGdI4B8A:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=h0MWZ1l-UNY:wL3BGdI4B8A:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=h0MWZ1l-UNY:wL3BGdI4B8A:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Short Update on Railslove</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/xOmWeTHOOAo/"/>
		<id>http://blog.railslove.com/?p=971</id>
		<updated>2011-08-10T12:35:41+00:00</updated>
		<content type="html">&lt;p&gt;Hey there,&lt;/p&gt;
&lt;p&gt;there&amp;#8217;s so much going on at Railslove at the moment, we&amp;#8217;ve felt it&amp;#8217;s really time for another update here on the blog.&lt;/p&gt;
&lt;p&gt;First of all, it&amp;#8217;s a great pity that &lt;a href=&quot;http://twitter.com/mkorfmann&quot;&gt;Manuel&lt;/a&gt; is leaving Railslove (hopefully just for a while?), because he decided to focus on finishing school for now &amp;#8212; even though I&amp;#8217;m sure he&amp;#8217;ll keep rubying with passion like he did at Railslove. Thanks for working, hacking and sharing skills with us, Manuel. Hope to see you soon at one of our next hack-ups @cowoco.&lt;/p&gt;
&lt;p&gt;Next up is &lt;a href=&quot;http://www.salesking.eu/&quot;&gt;SalesKing&lt;/a&gt;. Some of you may know &lt;a href=&quot;http://twitter.com/killerG&quot;&gt;Georg&lt;/a&gt; and the heavy-duty billing application he&amp;#8217;s been building for years now. After a long friendship, &lt;a href=&quot;http://blog.railslove.com/2009/06/02/railslove-und-salesking-suchen-ein-neues-zuhause/&quot;&gt;shared offices&lt;/a&gt; (back in 2008), the creation of &lt;a href=&quot;http://blog.railslove.com/2009/05/23/devhousefriday-mit-gary-vaynerchuk-yehuda-katz-und-scotland-on-rails/&quot;&gt;DevHouseFriday&lt;/a&gt; (in 2009) and now with Time2King a first shared project, it finally happened last week, that Railslove has become an official shareholder of SalesKing. We&amp;#8217;re very happy about our first investment (even though we&amp;#8217;re working with funded start-ups all the time, this is new to us) and the new involvement into the upcoming development of SalesKing, that comes with it. With Georg as visionary lead developer Railslove is now the new development team of SalesKing.&lt;/p&gt;
&lt;p&gt;And there&amp;#8217;s good news from &lt;a href=&quot;http://9flats.com/&quot;&gt;9flats&lt;/a&gt; for us: Together with Stephan Uhrenbacher and his managing team we agreed on a common future. Since 9flats is still growing at light speed and ideas and challenges don&amp;#8217;t seem to decrease at all, it will definitely be an exciting time for us. Thanks a lot for your great work until now, dear 9flats team, Stephan and his team know that their success and growth is also due to your dedication. Keep on rocking, Lena, Stephan, Jakob, Ralph, Jan, Lars and Tim!&lt;/p&gt;
&lt;p&gt;But 9flats has always been just one of our major projects, and also our &lt;a href=&quot;http://payango.com/&quot;&gt;Payango&lt;/a&gt; team has a good reason to celebrate soon, because Payango 3, the ultimate, most advanced, fastest and shiniest Payango-System ever built is about to launch! After months of conception work and development I can&amp;#8217;t wait to see this complete rewrite of their whole business application suite run in a production environment. While Payango 2 has &amp;#8220;just&amp;#8221; been a blown-up Rails application with a few white label frontends, Payango 3 will consist of several own backend and frontend web services, it will include new external services, new business partners and it will at all be the powerful technical future for all the crazy ideas the Payango guys are working on atm. Be on the lookout for &lt;a href=&quot;http://www.facebook.com/kiscard&quot;&gt;KisCARD&lt;/a&gt;, which will be the first Payango 3-based frontend running on the new infrastructure. Also, thank you for your great work and tireless efforts, dear Payango team aka &amp;#8220;triple-B&amp;#8221; Basti, Bartek, Bumi + Jan and Lars. Can&amp;#8217;t wait. Can&amp;#8217;t wait.&lt;/p&gt;
&lt;p&gt;Ahm, by the way, did you know that Railslove took over the active development and maintenance of &lt;a href=&quot;http://www.avocadostore.de/&quot;&gt;Avocado Store&lt;/a&gt; some month ago? Well, I have to admit, I almost forgot about that, too, because Lars silently uses his sustainable coding skills to keep everything working just like it should. Kudos, Lars!&lt;/p&gt;
&lt;p&gt;What else? Well, our incredible &lt;a href=&quot;http://awesomebotfactory.com/&quot;&gt;Awesome Bot Factory&lt;/a&gt; will *soon* be launched based on &amp;#8211; wait for it &amp;#8211; node.js! Bumi kindly asked me to put it in the blog post, so he and Lars feel a little productive pressure to finally deliver somewhere along the way&amp;#8230; ;-)&lt;/p&gt;
&lt;p&gt;Upcoming Events, you should keep in mind:&lt;/p&gt;
&lt;p&gt;* 10|11|12|13|14th August 2011: &lt;a href=&quot;http://events.ccc.de/camp/2011/wiki/Ruby_Village&quot;&gt;Ruby Village @ Chaos Communication Camp 2011&lt;/a&gt; thankfully initiated by Basti&lt;br /&gt;
* 27th &amp;#8211; 29th August 2011: node.js ko with @cowoco being an &lt;a href=&quot;http://nodeknockout.com/locations&quot;&gt;official knockout location&lt;/a&gt;, so come around to hack! &lt;/p&gt;
&lt;p&gt;Yeah, and that&amp;#8217;s what we have for you today. Thanks for reading and hope to see/read/hack with you soon. &lt;/p&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=xOmWeTHOOAo:uLVzYB8bTFw:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=xOmWeTHOOAo:uLVzYB8bTFw:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=xOmWeTHOOAo:uLVzYB8bTFw:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=xOmWeTHOOAo:uLVzYB8bTFw:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Erklärt: &quot;Law of Demeter&quot;</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/DByrCdKb-0g/erklart-law-of-demeter-8"/>
		<id>http://rubymag.de/erklart-law-of-demeter-8</id>
		<updated>2011-07-28T12:08:58+00:00</updated>
		<content type="html">Das &quot;Law of Demeter&quot; ist sicherlich kein Unbekannter, gehört meines Erachtens nach aber zu den oft falsch (oder besser nicht komplett) verstandenen Theorien. Avdi Grimm schreibt sehr ausführlich über das Thema in seinem Artikel &quot;Demeter: It’s not just a good idea. It’s the law.&quot;. Besonders...&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/DByrCdKb-0g&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Rails: Auf dem Weg zu 3.1 - Release 3.1.0.rc5</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/GtuokG-GuYM/rails-auf-dem-weg-zu-3-1-release-3-1-0-rc5-7"/>
		<id>http://rubymag.de/rails-auf-dem-weg-zu-3-1-release-3-1-0-rc5-7</id>
		<updated>2011-07-26T08:32:03+00:00</updated>
		<content type="html">Gestern wurde Release Candidate 5 der kommenden Rails Version 3.1 veröffentlicht.


Setup: gem install rails --pre&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/GtuokG-GuYM&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Web Operations 101 For Developers</title>
		<link href="http://www.paperplanes.de//2011/7/25/web_operations_101_for_developers.html"/>
		<id>http://www.paperplanes.de//2011/7/25/web_operations_101_for_developers.html</id>
		<updated>2011-07-25T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;This post is not about devops, it's not about lean startups, it's not about web
scale, it's not about the cloud, and it's not about continuous deployment. This
post is about you, the developer who's main purpose in life has always been to
build great web applications.  In a pretty traditional world you write code, you
write tests for it, you deploy, and you go home. Until now.&lt;/p&gt;

&lt;p&gt;To tell you the truth, that world has never existed for me. In all of my
developer life I had to deal with all aspects of deployment, not just putting
build artifacts on servers, but dealing with network outages, faulty network
drivers, crashing hard disks, sudden latency spikes, analyzing errors coming
from those pesky crawling bots on that evil internet of yours. I take a lot of
this for granted, but working in infrastructure and closely with developers
trying to get applications and infrastructure up and running on EC2 has taught
me some valuable lessons to assume the worst. Not because developers are stupid, but
because they like to focus on code, not infrastructure.&lt;/p&gt;

&lt;p&gt;But here's the deal: your code and all your full-stack and unit tests is worth
squat if they're not running out there on some server or infrastructure stack
like Google Apps or Heroku. Without running somewhere in production, your code
doesn't generate any business value, it's just a big pile of ASCII or UTF-8
characters that cost a lot of money to create, but didn't offer any return of
investment yet.&lt;/p&gt;

&lt;h3&gt;Love Thy Infrastructure&lt;/h3&gt;

&lt;p&gt;Operations isn't hard, but necessary. You don't need to know everything about
operations to become fluent in it, you just have to know enough to start and
know how to use Google.&lt;/p&gt;

&lt;p&gt;This is my collective dump from the last years of working both as a developer
and that guy who does deployments and manages servers too. Most are lessons I
learned the hard way, others just seemed logical to me when I learned about them
the first time around.&lt;/p&gt;

&lt;p&gt;Between you and me, having this skill set at hand makes you a much more valuable
developer. Being able to analyze any problem in production and at least having a
basic skill set to deal with it makes you a great asset for companies and
clients to hold on to. Thought you should know, but I digress.&lt;/p&gt;

&lt;p&gt;The most important lesson I can tell you right up front: love your
infrastructure, it's the muscles and bones of your application, whereas your
code running on it is nothing more than the skin.&lt;/p&gt;

&lt;h3&gt;Without Infrastructure, No-one Will Use Your Application&lt;/h3&gt;

&lt;p&gt;Big surprise. For users to be able to enjoy your precious code, it needs to run
somewhere. It needs to run on some sort of infrastructure, and it doesn't matter
if you're managing it, or if you're paying another company to take care of it for
you.&lt;/p&gt;

&lt;h3&gt;Everything Is Infrastructure&lt;/h3&gt;

&lt;p&gt;Every little piece of software and hardware that's necessary to make your
application available to users is infrastructure. The application server serving
and executing your code, the web server, your email delivery provider, the
service that tracks errors and application metrics, the servers or virtual
machines your services are running on.&lt;/p&gt;

&lt;p&gt;Every little piece of it can break at any time, can stall at any time. The more
pieces you have in your application puzzle, the more breaking points you have.
And everything that can break, will break. Usually not all at once, but most
certainly when it's the least expected, or just when you really need your
application to be available.&lt;/p&gt;

&lt;h3&gt;On Day One, You Build The Hardware&lt;/h3&gt;

&lt;p&gt;Everything starts with a bare metal server, even that cloud you've heard so much
about. Knowing your way around everything that's related to setting up a full
rack of servers on a single day, including network storage a fully configured
switch with two virtual LANs and a master-slave database setup using a RAID 10
a bunch of SAS drives might not be something you need every day, but it sure
comes in handy.&lt;/p&gt;

&lt;p&gt;The good news is the internet is here for you. You don't need to know everything
about every piece of hardware out there, but you should be able to investigate
strengths and weaknesses, when an SSD is an appropriate tool to use, and when
SAS drives will kick butt.&lt;/p&gt;

&lt;p&gt;Learn to distinguish the different levels of RAID, why having an additional file
system buffer on top of a RAID that doesn't have a backup battery for its own,
internal write buffer is a bad idea. That's a pretty good start, and will make
decisions much easier.&lt;/p&gt;

&lt;h3&gt;The System&lt;/h3&gt;

&lt;p&gt;Do you know what swap space is? Do you know what happens when it's used by the
operating system, and why it's actually a terrible thing and gives a false sense
of security? Do you know what happens when all available memory is exhausted?&lt;/p&gt;

&lt;p&gt;Let me tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When all available memory is allocated, the operating system starts swapping
out memory pages to swap space, which is located on disk, a very slow disk,
slow like a snail compared to fast memory.&lt;/li&gt;
&lt;li&gt;When lots of stuff is written to and read from swap space on disk, I/O wait
goes through the roof, and processes start to pile up waiting for their memory
pages to be swapped out to or read from disk, which in turn increases load
average, and almost brings the system to a screeching halt, but only almost.&lt;/li&gt;
&lt;li&gt;Swap is terrible because it gives you a false sense of having additional
resources beyond the available memory, while what it really does is slowing
down performance in a way that makes it almost impossible for you to log into
the affected system and properly analyze the problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is basically operations level on the operating system level. It's not much
you need to know here, but in my opinion it's essential. Learn about the most
important aspects of a Unix or Linux system. You don't need to know everything,
you don't need to know the specifics of Linux' process scheduler or the
underlying datastructure used for virtual memory. But the more you know, the
more informed your decisions will be when the rubber hits the road.&lt;/p&gt;

&lt;p&gt;And yes, I think enabling swap on servers is a terrible idea. Let processes
crash when they don't have any resources left. That at least will allow you to
analyze and fix.&lt;/p&gt;

&lt;h3&gt;Production Problems Don't Solve Themselves&lt;/h3&gt;

&lt;p&gt;Granted, sometimes they do, but you shouldn't be happy about that. You should be
willing to dig into whatever data you have posthumous to find whatever went wrong,
whatever caused a strange latency spike in database queries, or caused an
unusually high amount of errors in your application.&lt;/p&gt;

&lt;p&gt;When a problem doesn't solve itself though, which is certainly the common case,
someone needs to solve it. Someone needs to look at all the available data to
find out what's wrong with your application, your servers or the network.&lt;/p&gt;

&lt;p&gt;This person is not the unlucky operations guy who's currently on call, because
let's face it, smaller startups just don't have an operations team.&lt;/p&gt;

&lt;p&gt;That person is you.&lt;/p&gt;

&lt;h3&gt;Solve Deployment First&lt;/h3&gt;

&lt;p&gt;When the first line of code is written, and the first piece of your application
is ready to be pushed on a server for someone to see, solve the problem of
deployment. This has never been easier than it is today, and being able to push
incremental updates from then on speeds up development and the customer feedback
cycle considerably.&lt;/p&gt;

&lt;p&gt;As soon as you can, build that Capfile, Ant file, or whatever build and
deployment tools you're using, set up servers, or set up your project
on an infrastructure platform like &lt;a href=&quot;http://scalarium.com&quot;&gt;Scalarium&lt;/a&gt;,
&lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt;, &lt;a href=&quot;http://www.google.com/apps/&quot;&gt;Google Apps&lt;/a&gt;, or
&lt;a href=&quot;http://dotcloud.com&quot;&gt;dotCloud&lt;/a&gt;. The sooner you solve this problem, the easier
it will be to finally push that code of yours into production for everyone to
use. I consider application deployment a solved problem. There's no reason why
you shouldn't have it in place even in the earliest stages of a project.&lt;/p&gt;

&lt;p&gt;The more complex a project gets over even just its initial lifecycle the easier
it will be to add more functionality to an existing deployment setup instead of
having to build everything from scratch.&lt;/p&gt;

&lt;h3&gt;Automate, Automate, Automate&lt;/h3&gt;

&lt;p&gt;Everything you do by hand, you should only be doing once. If there's any chance
that particular action will be repeated at some point, invest the time to turn
it into a script. It doesn't matter if it's a shell, a Ruby, a Perl, or a Python
script. Just make it reusable. Typing things into a shell manually, or updating
configuration files with an editor on every single server is tedious work, work
that you shouldn't be doing manually more than once.&lt;/p&gt;

&lt;p&gt;When you automate something once, it not only greatly increases execution speed the
second and third time around, it reduces the chance of failure, of missing that one
important step.&lt;/p&gt;

&lt;p&gt;There's an abundance of tools available to automate infrastructure, hand-written
script are only the simplest part of it. Once you go beyond managing just one or
two servers, tools like &lt;a href=&quot;http://www.opscode.com/chef/&quot;&gt;Chef&lt;/a&gt;,
&lt;a href=&quot;http://www.puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt; and
&lt;a href=&quot;http://docs.puppetlabs.com/mcollective/&quot;&gt;MCollective&lt;/a&gt; come in very handy to
automate everything from setting up bare servers to pushing out configuration
changes from a single point, to deploying code. Everything should be properly
automated with some tool. Ideally you only use one, but looking at Chef and
Puppet, both have their strength and weaknesses.&lt;/p&gt;

&lt;p&gt;Changes in Chef aren't instant, unless you use the command line tool &lt;code&gt;knife&lt;/code&gt;,
which assumes SSH access to all servers you're managing. The bigger your
organizations the less chance you'll have to be able to access all machines via
SSH. Instant tools like mCollective that work based on a push agent system, are
much better for these instant kinds of activities.&lt;/p&gt;

&lt;p&gt;It's not important what kind of tool you use to automate, what's important is
that you do it in the first place.&lt;/p&gt;

&lt;p&gt;By the way, if your operations team restricts SSH access to machines for
developers, fix that. Developers need to be able to analyze and fix incidents
just like the operations folks do. There's no valid point in denying SSH access
to developers. Period.&lt;/p&gt;

&lt;h3&gt;Introduce New Infrastructure Carefully&lt;/h3&gt;

&lt;p&gt;Whenever you add a new component, a new feature to an application, you add a new
point of failure. Be it a background task scheduler, a messaging queue, an image
processing chain or asynchronous mail delivery, it can and it will fail.&lt;/p&gt;

&lt;p&gt;It's always tempting to add shiny new tools to the mix. Developers are prone to
trying out new tools even though they've not yet fully proven themselves in
production, or experience running them is still sparse. It's a good thing in one
way, because without people daring to use new tools everyone else won't be able
to learn from their experiences (you do share those experiences, do you?).&lt;/p&gt;

&lt;p&gt;But on the other hand, you'll live the curse of the early adopter. Instead of
benefiting from existing knowledge, you're the one bringing the knowledge into
existence. You'll experience all the bugs that are still lurking in the darker
corners of that shiny new database or message queue system. You'll spend time
developing tools and libraries to work with the new stuff, time you could just
as well be spending working on generating new business value by using existing
tools that do the job similarly well. If you do decide for a new tool, be
prepared to degrade back to other tools in the case of failure.&lt;/p&gt;

&lt;p&gt;No matter if old or new, adding more infrastructure always has the potential for
more things to break. Whenever you add something, be sure to know what you're
getting yourself into, be sure to have fallback procedures in place, be sure
everyone knows about the risks and the benefits. When something that's still
pretty new breaks, you're usually on your own.&lt;/p&gt;

&lt;h3&gt;Make Activities Repeatable&lt;/h3&gt;

&lt;p&gt;Every activity in your application that causes other, dependent activities to be
executed, needs to be repeatable, either by the user, or through some sort of
administrative interface, or automatically if feasible. Think user confirmation
emails, generating monthly reports, background tasks like processing uploads.
Every activity that's out of the normal cycle of fetching records from a
datasource and updating them is bound to fail. Heck, even that cycle will fail
at some point due to some odd error that only comes up every once in a blue
moon.&lt;/p&gt;

&lt;p&gt;When an activity is repeatable, it's much easier to deal with outages of single
components. When it comes back up, simply re-execute the tasks that got stuck.&lt;/p&gt;

&lt;p&gt;This, however, requires one important thing: every activity must be idempotent.
It must have the same outcome no matters how often it's being run. It must know
what steps were already taken before it broke the last time around. Whatever's
already been done, it shouldn't be done again. It should just pick up where it
left off.&lt;/p&gt;

&lt;p&gt;Yes, this requires a lot of work and care for state in your application. But
trust me, it'll be worth it.&lt;/p&gt;

&lt;h3&gt;Use Feature Flips&lt;/h3&gt;

&lt;p&gt;New features can cause joy and more headaches. Flickr was one of the first to
add something called feature flips, a simple way to enable and disable features
for all or only specific users. This way you can throw new features onto your
production systems without accidentally enabling it for all users, you can
simply allow a small set of users or just your customer to use it and to play
with it.&lt;/p&gt;

&lt;p&gt;What's more important though, when a feature breaks in production for some
reason, you can simply switch it off, disabling traffic on the systems involved,
allowing you to take a breether and analyze the problem.&lt;/p&gt;

&lt;p&gt;Feature flips come in many flavors, the simplest approach is to just use a
configuration file to enable or disable them. Other approaches use a centralized
database like Redis for that purpose, which has an added benefit for other parts
of your application, but also adds new infrastructure components and therefore,
more complexity and more points of failure.&lt;/p&gt;

&lt;h3&gt;Fail And Degrade Gracefully&lt;/h3&gt;

&lt;p&gt;What happens when you unplug your database server? Does your application throw
in the towel by showing a 500 error, or is it able to deal with the situation
and show a temporary page informing the user of what's wrong? You should try it
and see what happens.&lt;/p&gt;

&lt;p&gt;Whenever something non-critical breaks, your application should be able to deal
with it without anything else breaking. This sounds like an impossible thing to
do, but it's really not. It just requires care, care your standard unit tests
won't be able to deliver, and thinking about where you want a breakage to leak
to the user, or where you just ignore it, picking up work again as soon as the
failed component becomes available again.&lt;/p&gt;

&lt;p&gt;Failing gracefully can mean a lot of things, there's things that directly affect
user experience, a database failure comes to mind, and things that the user will
notice only indirectly, e.g. through delays in delivering emails or fetching
data from an external service like Twitter, RSS feeds and so on.&lt;/p&gt;

&lt;p&gt;When a major component in your application fails, a user will most likely be
unable to use your application at all. When your database latency increases
manifold, you have two options. Try to squeeze through as much as you can,
accepting long waits on your user's side, or you can let him know that it's
currently impossible to serve him in an acceptable time frame, and that you're
actively working on fixing or improving the situations. Which you should, either
way.&lt;/p&gt;

&lt;p&gt;Delays in external services or asynchronous tasks are much harder for a user to
notice. If fetching data from an external source, like an API, directly affects
your site's latency, there's your problem.&lt;/p&gt;

&lt;p&gt;Noticing problems in external services requires two things: monitoring and
metrics. Only by tracking queue sizes, latency for calls to external services,
mail queues and all things related to asynchronous tasks will you be able to
tell when your users are indirectly affected by a problem in your
infrastructure.&lt;/p&gt;

&lt;p&gt;After all, knowing is half the battle.&lt;/p&gt;

&lt;h3&gt;Monitoring Sucks, You Need It Anyway&lt;/h3&gt;

&lt;p&gt;I've written in &lt;a href=&quot;http://www.paperplanes.de/2011/1/5/the_virtues_of_monitoring.html&quot;&gt;abundance on the virtues of monitoring, metrics and
alerting&lt;/a&gt;. I
can't say it enough how important having a proper monitoring and metrics gathering
system in place is. It should be by your side from day one of any testing deployment.&lt;/p&gt;

&lt;p&gt;Set up alerts for thresholds that seem like a reasonable place to start to you.
Don't ignore alerting notifications, once you get into that habit, you'll miss
that one important notification that's real. Instead, learn about your system
and its thresholds over time.&lt;/p&gt;

&lt;p&gt;You'll never get alerting and thresholds right the first time, you'll adapt over
time, identifying false negatives and false positives, but if you don't have a
system in place at all, you'll never know what hit your application or your
servers.&lt;/p&gt;

&lt;p&gt;If you're not using a tool to gather metrics like
&lt;a href=&quot;http://munin-monitoring.org/&quot;&gt;Munin&lt;/a&gt;,
&lt;a href=&quot;http://ganglia.sourceforge.net/&quot;&gt;Ganglia&lt;/a&gt;, &lt;a href=&quot;http://newrelic.com&quot;&gt;New Relic&lt;/a&gt;, or
&lt;a href=&quot;http://collectd.org/&quot;&gt;collectd&lt;/a&gt;, you'll be in for a big surprise once your application becomes
unresponsive for some reason. You'll simply never find out what the reason was
in the first place.&lt;/p&gt;

&lt;p&gt;While Munin has basic built-in alerting capabilities, chances are you'll add
something like &lt;a href=&quot;http://www.nagios.org/&quot;&gt;Nagios&lt;/a&gt; or
&lt;a href=&quot;http://www.pagerduty.com/&quot;&gt;PagerDuty&lt;/a&gt; to the mix for alerting.&lt;/p&gt;

&lt;p&gt;Most monitoring tools suck, you'll need them anyway.&lt;/p&gt;

&lt;h3&gt;Supervise Everything&lt;/h3&gt;

&lt;p&gt;Any process that's required to be running at any time needs to be supervised.
When something crashes be sure there's an automated procedure in place that will
either restart the process or notify you when it can't do so, degrading
gracefully. &lt;a href=&quot;http://mmonit.com/monit/&quot;&gt;Monit&lt;/a&gt;,
&lt;a href=&quot;http://god.rubyforge.org/&quot;&gt;God&lt;/a&gt;, &lt;a href=&quot;https://github.com/arya/bluepill&quot;&gt;bluepill&lt;/a&gt;,
&lt;a href=&quot;http://supervisord.org/&quot;&gt;supervisord&lt;/a&gt;, &lt;a href=&quot;http://smarden.org/runit/&quot;&gt;RUnit&lt;/a&gt;, the
number of tools available to you is endless.&lt;/p&gt;

&lt;p&gt;Micromanaging people is wrong, but processes need that extra set of eyes on them
at all times.&lt;/p&gt;

&lt;h3&gt;Don't Guess, Measure!&lt;/h3&gt;

&lt;p&gt;Whatever directly affects your users' experience affects your business. When
your site is slow, users will shy away from using it, from generating revenue
and therefore (usually) profit. &lt;/p&gt;

&lt;p&gt;Whenever a user has to wait for anything, they're not willing to wait forever.
If an uploaded video takes hours to process, they'll go to the next video
hosting site. When a confirmation email takes hours to be delivered, they'll
check out your competitor, taking the money with them.&lt;/p&gt;

&lt;p&gt;How do you know that users have to wait? Simple, you track how long things in
your application take, how many tasks are currently stuck in your processing
queue, how long it took to process an upload. You stick metrics on anything
that's directly or indirectly responsible for generating business value.&lt;/p&gt;

&lt;p&gt;Without having a proper system to collect metrics in place, you'll be blind.
You'll have no idea what's going inside your application at any given time.
Since Coda Hale's talk &lt;a href=&quot;http://codahale.com/codeconf-2011-04-09-metrics-metrics-everywhere.pdf&quot;&gt;&quot;Metrics
Everywhere&quot;&lt;/a&gt;
at CodeConf and the release of &lt;a href=&quot;https://github.com/codahale/metrics&quot;&gt;his metrics library for
Scala&lt;/a&gt;, an abundance of libraries for
different languages has popped up left and right. They make it easy to include
timers, counters, and other types of metrics into your application,
allowing you to instrument code where you see fit. Independently, Twitter has
lead the way by releasing &lt;a href=&quot;https://github.com/twitter/ostrich&quot;&gt;Ostrich&lt;/a&gt;, their
own Scala library to collect metrics. The tools are here for you. Use them.&lt;/p&gt;

&lt;p&gt;The most important metrics should be easily accessible on some sort of
dashboard. You don't need a big fancy screen in your office right away, a
canonical place, e.g. a website including the most important graphs and numbers,
where everyone can go and see what's going on with a glance is a good start.
Once you have that in place, the next step towards a company-visible dashboard
is simple buying a big-ass screen.&lt;/p&gt;

&lt;p&gt;All metrics should be collected in a tool like Ganglia, Munin or something else.
These tools make analysis of historical data easy, they allow you to make
predictions or correlate the metrics gathered in your applications to other
statistics like CPU, memory usage, I/O waits, and so on.&lt;/p&gt;

&lt;p&gt;The importance of monitoring and metrics cannot be stressed enough. There's no
reason why you shouldn't have it in place. Setting up Munin is easy enough,
setting up collection using an external service like New Relic or
&lt;a href=&quot;http://scoutapp.com&quot;&gt;Scout&lt;/a&gt; is usually even easier.&lt;/p&gt;

&lt;h3&gt;Use Timeouts Everywhere&lt;/h3&gt;

&lt;p&gt;Latency is your biggest enemy in any networked environment. It creeps up on you
like the shadow of the setting sun. There's a whole bunch of reasons why, e.g.
database queries will suddenly see a spike in execution time, or external
services suddenly take forever to answer even the simplest requests.&lt;/p&gt;

&lt;p&gt;If your code doesn't have appropriate timeouts, requests will pile up and maybe
never return, exhausting available resources (think connection pools) faster
than Vettel does a round in Monte Carlo.&lt;/p&gt;

&lt;p&gt;Amazon for example has internal contracts. Going to their home page involves
dozens of requests to internal services. If any one of them doesn't respond in a
timely manner, say 300 ms, the application serving the page will render a static
piece snippet instead, but thereby decreasing the chance of selling something,
directly affecting business value.&lt;/p&gt;

&lt;p&gt;You need to treat every call to an external resource as something that can take
forever, something that potentially blocks an application server process
forever. When an application server process or thread is blocked, it can't serve
any other client. When all processes and threads lock up waiting for a resource,
your website is dead.&lt;/p&gt;

&lt;p&gt;Timeouts make sure that resources are freed and made available again after a
grace period. When a database query takes longer than usual, not only does your
application need to know how to handle that case, but your database needs to. If
your application has a timeout, but your database will happily keep sorting those
millions of records in a temp file on disk, you didn't gain a lot. If two
dependent resources are within your hands, both need to be aware of contracts
and timeouts, both need to properly free resources when the request couldn't be
served in a timely manner.&lt;/p&gt;

&lt;p&gt;Use timeouts everywhere, but know how to handle them when they occur, know what
to tell the user when his request didn't return quickly enough. There is no
golden rule what to do with a timeout, it depends not just on your application,
but on the specific use case.&lt;/p&gt;

&lt;h3&gt;Don't Rely on SLAs&lt;/h3&gt;

&lt;p&gt;The best service fails at some point. It will fail in the most epic way
possible, not allowing any user to do anything. This doesn't have to be your
service. It can be any service you directly or indirectly rely on.&lt;/p&gt;

&lt;p&gt;Say, your code runs on Heroku. Heroku's infrastructure runs on Amazon's EC2.
Therefore Heroku is prone to problems with EC2. If a provider like Heroku tells
you they have a service level agreement in place that guarantees a minimum
amount of availability per month or per year, that's worth squat to you, because
they in turn rely on other external services, that may or may not offer
different SLAs. This is not specific to Heroku, it's just an obvious example.
Just because you outsourced infrastructure doesn't mean you're allowed to stop
caring.&lt;/p&gt;

&lt;p&gt;If your application runs directly on EC2, you're bound by the same problem. The
same is true for any infrastructure provider you rely on, even a big hosting
company where your own server hardware is colocated.&lt;/p&gt;

&lt;p&gt;They all have some sort of SLA in place, and they all will screw you over with
the terms of said SLA. When stuff breaks on their end, that SLA is not worth a
single dime to you, even when you were promised to get your money back. It will
never make up for lost revenue, for lost users and decreased uptime on your end.
You might as well stop thinking about them in the first place.&lt;/p&gt;

&lt;p&gt;What matters is what procedures any provider you rely on has in place in case of
a failure. The important thing for you as one of their users is to not be left
standing in the rain when your hosting world is coming close to an end. A
communicative provider is more valuable than one that guarantees an impossible
amount of availability. Things will break, not just for you. SLAs give you that
false sense of security, the sense that you can blame an outage on someone else.&lt;/p&gt;

&lt;p&gt;For more on this topic, Ben Black has written a
&lt;a href=&quot;http://blog.b3k.us/2009/07/15/service-level-disagreements.html&quot;&gt;two&lt;/a&gt;
&lt;a href=&quot;http://blog.b3k.us/2009/07/16/service-level-disagreements-2.html&quot;&gt;part&lt;/a&gt; series
aptly named &quot;Service Level Disagreements&quot;.&lt;/p&gt;

&lt;h3&gt;Know Your Database&lt;/h3&gt;

&lt;p&gt;You should know what happens inside your database when you execute any query.
Period. You should know where to look when a query takes too long, and you
should know what commands to use to analyze why it takes too long.&lt;/p&gt;

&lt;p&gt;Do you know how an index is built? How and why your database picks one index over
another? Why selecting a random record based on the wrong criteria will kill
your database?&lt;/p&gt;

&lt;p&gt;You should know these things. You should read &quot;High Performance MySQL&quot;, or
&quot;Oracle Internals&quot;, or &quot;PostgreSQL 9.0 High Performance&quot;. Sorry, I didn't mean
to say you should, I meant you must read them.&lt;/p&gt;

&lt;h3&gt;Love Your Log Files&lt;/h3&gt;

&lt;p&gt;In case of an emergency, a good set of log files will mean the world to you.
This doesn't just include the standard set of log files available on a Unix
system. It includes your application and all services involved too.&lt;/p&gt;

&lt;p&gt;Your application should log important events, anything that may seem useful to
analyze an incident. Again, you'll never get this right the first time around,
you'll never know up front all the details you may be interested in later. Adapt
and improve, add more logging as needed. It should allow you to tune the log
verbosity at runtime, either by a using a feature switch or by accepting a Unix
signal.&lt;/p&gt;

&lt;p&gt;Separate request logging from application logging. Data on HTTP requests is just
as important as application logs, but it's easier if you can sift through them
independently, they're also a lot easier to aggregate for services like Syslog
or Loggly when they're on their own.&lt;/p&gt;

&lt;p&gt;For you Rails developers out there: using &lt;code&gt;Rails.logger&lt;/code&gt; is not an acceptable
logging mechanism. All your logged statements will be intermingled with Rails
next to unusable request logging output. Use a separate log file for anything
that's important to your application.&lt;/p&gt;

&lt;p&gt;Just like you should stick metrics on all things that are important to your
business, log additional information when things get out of hand. Correlating
log files with metrics gathered on your servers and in your application is an
incredibly powerful way of analyzing incidents, even long after they occurred.&lt;/p&gt;

&lt;h3&gt;Learn the Unix Command Line&lt;/h3&gt;

&lt;p&gt;In case of a failure, the command line will be your best friend. Knowing the
right tools to quickly sift through a set of log files, being able to find and
set certain kernel parameters to adjust TCP settings, knowing how get the most
important system statistics with just a few commands, and knowing where to look
for a specific service's configuration. All these things are incredibly valuable
in case of a failure.&lt;/p&gt;

&lt;p&gt;Knowing your way around a Unix or Linux system, even with just a basic toolset
is something that will make your life much easier, not just in operations, but
also as a developer. The more tools you have at your disposal, the easier it
will be for you to automate tasks, to not be scared of operations in general.&lt;/p&gt;

&lt;p&gt;In times of an emergency, you can't afford to argue that your favorite editor is
not installed on a system, you use what's available.&lt;/p&gt;

&lt;h3&gt;At Scale, Everything Breaks&lt;/h3&gt;

&lt;p&gt;Working at large scale is nothing anyone should strive for, it's a terrible
burden, but an incredibly fascinating one. The need for scalability evolves over
time, it's nothing you can easily predict or assume without knowing all the
details, parameters and the future. Out of all three, at least one is 100% guess
work.&lt;/p&gt;

&lt;p&gt;The larger your infrastructure setup gets, the more things will break. The more
servers you have, the larger the number of servers being not available at any
time. That's nothing you need to respect right from the get go, it's something
to keep in mind.&lt;/p&gt;

&lt;p&gt;No service that's working at a larger scale was originally designed for it. The
code and infrastructure were adapted, the services grew over time, and they
failed a lot. Something to think about when you reach for that awesome scalable
database before even having any running code.&lt;/p&gt;

&lt;h3&gt;Embrace Failure&lt;/h3&gt;

&lt;p&gt;The bottom line of everything is, stuff breaks, everything breaks at different
scale. Embrace breakage and failure, it will help you learn and improve your
knowledge and skill set over time. Analyze incidents using the data available to
you, fix the problem, learn your lesson, and move on.&lt;/p&gt;

&lt;p&gt;Don't embrace one thing though: never let a failure happen again if you know
what caused it the first time around.&lt;/p&gt;

&lt;p&gt;Web operations is not solely related to servers and installing software
packages. Web operations involves everything required to keep an application
available, and your code needs to play along.&lt;/p&gt;

&lt;h3&gt;Required Reading&lt;/h3&gt;

&lt;p&gt;As 101s go, this is a short overview of what I think makes up for a good starter
set of operations skills. If you don't believe or trust me (which is a good
thing), here's a list of further reading for you. By now, I consider most of
these required reading even. The list isn't long, mind you. The truth as of
today is still that you learn the most out of personal experience on production
systems. Both require one basic skill though: you have to want to learn.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0978739213/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0978739213&quot;&gt;Release It!&lt;/a&gt; - A must read, that's all I can say. It's an incredible resource stemming from years of production. A must read, no excuses.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/1449377440/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1449377440&quot;&gt;Web Operations: Keeping the Data on Time&lt;/a&gt; - The best summary on all things operations available today. If
you read one book, read this, and the previous one (that's two books, I know)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0974514039/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0974514039&quot;&gt;Pragmatic Project Automation&lt;/a&gt; (oldie, but goldie, this book was an eye-opener to me)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0596518579/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596518579&quot;&gt;The Art of Capacity Planning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0596102356/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596102356&quot;&gt;Building Scalable Websites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/B004PUIVLQ/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B004PUIVLQ&quot;&gt;High Performance MySQL, 2nd. Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ctlab.org/documents/How%20Complex%20Systems%20Fail.pdf&quot;&gt;How Complex Systems Fail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.usenix.org/event/lisa07/tech/full_papers/hamilton/hamilton_html/&quot;&gt;On Designing and Deploying Internet-Scale Services&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Shameless Plug&lt;/h2&gt;

&lt;p&gt;If you liked this article, you may enjoy the book I'm currently working on: &lt;a href=&quot;http://nosqlhandbook.com/&quot;&gt;&quot;The NoSQL
Handbook&quot;&lt;/a&gt;.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/AIie6Gnw1V8&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Rails 3.1 HackFest am Wochenende</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/EZEb8D081zw/rails-3-1-hackfest-am-wochenende-6"/>
		<id>http://rubymag.de/rails-3-1-hackfest-am-wochenende-6</id>
		<updated>2011-07-22T17:38:50+00:00</updated>
		<content type="html">An diesem Wochenende (23. und 24. Juli 2011) findet das Rails HackFest zum kommenden Release 3.1 statt. Die Zielsetzung ist einfach: Einen möglichst stabilen 3-1-stable Branch erzeugen. Mehr Informationen finden sich im offiziellen Rails Blog.&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/EZEb8D081zw&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">&quot;Hört auf Java zu hassen&quot; - Ein Aufruf mit Einblick</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/ahSjFI9TOhk/hort-auf-java-zu-hassen-ein-aufruf-mit-einblick-5"/>
		<id>http://rubymag.de/hort-auf-java-zu-hassen-ein-aufruf-mit-einblick-5</id>
		<updated>2011-07-22T14:01:45+00:00</updated>
		<content type="html">Stop hating Java - Ein Artikel von Andrzej Krzywda der die guten Seiten der Sprache Java beleuchtet. Geschrieben für Rubyisten.&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/ahSjFI9TOhk&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Garbage Collector Tuning mit Ruby 1.9.2</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/FIPtv_baomc/garbage-collector-tuning-mit-ruby-1-9-2-4"/>
		<id>http://rubymag.de/garbage-collector-tuning-mit-ruby-1-9-2-4</id>
		<updated>2011-07-22T12:53:38+00:00</updated>
		<content type="html">Shai Rosenfeld erklärt im Engine Yard Blog wie man den Ruby GC optimieren kann und warum das nötig sein könnte.&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/FIPtv_baomc&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Rails: Travis CI übernimmt</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/xycaC7cUcR0/rails-travis-ci-ubernimmt-3"/>
		<id>http://rubymag.de/rails-travis-ci-ubernimmt-3</id>
		<updated>2011-07-21T20:22:27+00:00</updated>
		<content type="html">Seit Kurzem kümmert sich Travis um das Continuous Integration System des Rails Projektes.


Aktuelle Build Informationen finden sich hier. ()&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/xycaC7cUcR0&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Railcamp Poland after some time</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/mz690_Dt4Fk/"/>
		<id>http://blog.railslove.com/?p=951</id>
		<updated>2011-07-21T10:56:55+00:00</updated>
		<content type="html">&lt;p&gt;In April, we, in cooperation with few Rails community companies, have organized the first edition of &lt;a href=&quot;http://railscamp.pl&quot;&gt;Railscamp Poland&lt;/a&gt;. Railscamp Poland took place in &lt;a href=&quot;http://en.wikipedia.org/wiki/Wis%C5%82a&quot;&gt;Wisła&lt;/a&gt;, the same Wisła where &lt;a href=&quot;http://en.wikipedia.org/wiki/Adam_Ma%C5%82ysz&quot;&gt;Adam Małysz&lt;/a&gt;, a legendary former ski jumper, is from. We are very happy how the event turned out, and that many people spoke well about the organization of it.&lt;/p&gt;
&lt;p&gt;So, right now, when I look back at the event, what do I see?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/bumi/5617471020/sizes/o/in/pool-1633180@N24/&quot;&gt;&lt;img alt=&quot;Railscamp Poland&quot; src=&quot;http://farm6.static.flickr.com/5188/5617471020_bb09f9fb58.jpg&quot; title=&quot;Railscamp Poland&quot; class=&quot;alignnone&quot; width=&quot;500&quot; height=&quot;374&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I see happy people, getting together, in one case, to have a good time while doing what they like! And all the time we did just that. There was a bit of coding, but mostly we had fun playing Guitar Hero, singing, playing Urban Terror.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/bumi/5616883149/sizes/l/in/pool-1633180@N24/&quot;&gt;&lt;img src=&quot;http://farm6.static.flickr.com/5183/5616883149_68c2e56a59.jpg&quot; alt=&quot;Barbeque&quot; title=&quot;Barbeque&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some quick (and not entirely accurate) facts about Railscamp Poland:&lt;/p&gt;
&lt;p&gt;During the event, people:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;drank 20 liters of vodka,&lt;/li&gt;
&lt;li&gt;drank 40 liters of Club Mate,&lt;/li&gt;
&lt;li&gt;eaten 50 kilograms of pizzas,&lt;/li&gt;
&lt;li&gt;eaten 120 sausages,&lt;/li&gt;
&lt;li&gt;got 250 euro from a deposit for returned beer bottles,&lt;/li&gt;
&lt;li&gt;wrote daily 4000 lines of code (including 2600 while drinking), which test coverage is at 100%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, big thanks to these guys for making this possible:&lt;/p&gt;
&lt;div&gt;&lt;a href=&quot;http://applicake.com&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://mike.poltyn.com/img/ext/applicake_220.png&quot; title=&quot;Applicake&quot; alt=&quot;Applicake&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://jarorcon.pl&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://img846.imageshack.us/img846/3066/jarorconlogo.png&quot; title=&quot;Jarorcon&quot; alt=&quot;Jarorcon&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://railslove.com&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://mike.poltyn.com/img/ext/railslove_220.png&quot; title=&quot;Railslove&quot; alt=&quot;Railslove&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://salesking.eu&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://blog.salesking.eu/files/2010/05/SalesKing-Logo-550x128.jpg&quot; width=&quot;222px&quot; title=&quot;SalesKing&quot; alt=&quot;SalesKing&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The photos from the event are available on &lt;a href=&quot;http://www.flickr.com/groups/railscamp_pl/pool/&quot;&gt;Flickr&lt;/a&gt; and &lt;a href=&quot;http://www.ipernity.com/doc/14661/album/231267&quot;&gt;Ipernity&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=mz690_Dt4Fk:bkFGV4e69fU:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=mz690_Dt4Fk:bkFGV4e69fU:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=mz690_Dt4Fk:bkFGV4e69fU:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=mz690_Dt4Fk:bkFGV4e69fU:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Sind Klassen-Methoden böse?</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/5cq6ZpV5BtE/sind-klassen-methoden-bose-2"/>
		<id>http://rubymag.de/sind-klassen-methoden-bose-2</id>
		<updated>2011-07-21T09:40:07+00:00</updated>
		<content type="html">Diese Frage wird von Nick Sutterer in seinem Blog aufgeworfen. Folgt man den Ideen von DCI müsste man die Rails-Model Finder Methoden überdenken. Aktuell wird die Diskussion zum Thema in den Kommentaren des Artikels geführt. Prädikat: Lesenswert.&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/5cq6ZpV5BtE&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Rails: 300% schneller im Development Modus</title>
		<link href="http://feedproxy.google.com/~r/rubyblog/~3/dWG1zHCeEjw/rails-300-schneller-im-development-modus-1"/>
		<id>http://rubymag.de/rails-300-schneller-im-development-modus-1</id>
		<updated>2011-07-21T09:33:12+00:00</updated>
		<content type="html">Das ActiveReload Gem von Robert Pankowecki beschleunigt Rails im Development Modus um bis zu 300%. Anstatt bei jedem Request alle Dateien neu zu laden, sorgt das Gem dafür, dass nur wirklich geänderte Dateien aktualisiert werden.&lt;img src=&quot;http://feeds.feedburner.com/~r/rubyblog/~4/dWG1zHCeEjw&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>RubyMag</name>
			<uri>http://rubymag.de</uri>
		</author>
		<source>
			<title type="html">RubyMag</title>
			<subtitle type="html">Ruby und Ruby on Rails News</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/rubyblog"/>
			<id>tag:rubyphunk.com,2008:mephisto/</id>
			<updated>2011-07-28T12:40:20+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">The Ethical Programmer</title>
		<link href="http://feedproxy.google.com/~r/jankrutisch/rss/~3/FbRMWwjfmSg/"/>
		<id>http://jan.krutisch.de/en/2011/06/19/The-Ethical-Programmer.html/</id>
		<updated>2011-06-18T22:00:00+00:00</updated>
		<content type="html">&lt;p&gt;This is somewhat of a complicated issue for me. I&amp;#8217;m having a lot of discussions with fellow developers and colleagues on this and it seems to be very difficult to find some common ground here. But since it bugs me a lot and I am still very indifferent on the whole issue, I had to blog about it and kind of hoping to start a discussion amongst us, the developer community.&lt;/p&gt;
&lt;p&gt;So, here&amp;#8217;s the question: Do we have, as developers, have some kind of moral obligation to choose projects to work on which follow certain ethical standards. If so, what might these standards look like?&lt;/p&gt;
&lt;p&gt;For me, there are actually a few &lt;strong&gt;solid&lt;/strong&gt; lines. I would never work for a company that builds weapons, for example. I would never work for organisations that are downright, and knowingly so, criminal. Beyond those lines, things tend to get blurry very very fast. Take Apple, for example (just picking it because of it&amp;#8217;s current popularity, could probably pick any consumer electronics vendor). While working at cupertino is certainly a cool job and work ethics are valued relatively high at the company(take a look at their &amp;#8220;It get&amp;#8217;s better&amp;#8221; video, for example), you still would work for a company that manufactures their computers in factories where people actually commit suicide during work. Well? How would you decide?&lt;/p&gt;
&lt;p&gt;But let&amp;#8217;s dismount the high horse &amp;#8211; I&amp;#8217;m aiming lower. Actually so low that &amp;#8220;ethical&amp;#8221; sounds a bit huge.&lt;/p&gt;
&lt;p&gt;Actually, I want to turn this completely around, from negative selection to positive: Are you, am I working on something that makes the world a better place? The internet a better place? Does it make people happy? Does it help people doing their jobs better, making their lives better?&lt;/p&gt;
&lt;p&gt;Because, in the end, that&amp;#8217;s what I want to aim for, as a programmer, as a citizen, as a human being.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And, to be honest, I think that we&amp;#8217;re largely failing here.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;span id=&quot;more&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You see, I&amp;#8217;m a german. And I am largely working for startups. And the german startup scene&amp;#8230;&lt;/p&gt;
&lt;p&gt;&amp;#8230;sorry. Had to go to the basement to not scare my neighbours with excessive swearing.&lt;/p&gt;
&lt;p&gt;I often ramble about the useless copycat-ism of the german startup scene. I am especially fond of the Samwer brothers, who are extremly successful (and admired by many for that) in building clones of US apps, making them big in Europe and then selling them to &amp;#8220;the original&amp;#8221;&amp;#8482;. They got their first big monies from selling their dot-com startup to eBay (Was it alando? Abacho? Do I care?) and lately got some comical amount of money for their City Deals platform they sold to Groupon. We&amp;#8217;ll get back to the Samwers later.&lt;/p&gt;
&lt;p&gt;Now, I spent huge amounts of this spring actually building a copycat, namely &lt;a href=&quot;http://rent-n-roll.de&quot;&gt;rent-n-roll&lt;/a&gt;, a clone of platforms like &lt;a href=&quot;http://www.whipcar.com/&quot;&gt;whipcar&lt;/a&gt; and &lt;a href=&quot;http://relayrides.com&quot;&gt;relayrides&lt;/a&gt; which all do p2p car rentals. And I was hugely enjoying it. Why that double standard?&lt;/p&gt;
&lt;p&gt;Well, first of all, all p2p car rental sites seem to focus very much on their local markets so far. UK&amp;#8217;s Whipcar very much focuses on the london area (clever move, huh?) and Relayrides actually takes city by city in the US, very carefully and slowly.&lt;/p&gt;
&lt;p&gt;There are actually a few german contenders and it&amp;#8217;s not completely clear yet if the model would work at all in car-fetishist-land-germany, but we actually felt that we had something serious to add (in this case, mostly insurance related stuff and building an app that&amp;#8217;s not completely broken in terms of UX). So, yes, I think, in building the app we were actually making the internet a better place. And the world. Kinda.&lt;/p&gt;
&lt;p&gt;Back to the Samwer brothers. They seem to be genuinly non-interested in making the world a better place. It&amp;#8217;s not too cynical to say that all they are interested in is to make their wallets a richer place, an endeavour in which they seem to be very successful.&lt;/p&gt;
&lt;p&gt;Their latest baby is a platform called Wimdu, which is, more or less, a 1:1 copycat of &lt;a href=&quot;http://www.airbnb.com/&quot;&gt;AirBnB&lt;/a&gt;, a wildly successful US startup that currently revolutionizes on-the-road accomodation by letting people rent out beds or flats directly to people visiting the city. Let&amp;#8217;s just say, if I would own a cheap hotel or a youth hostel, I wouldn&amp;#8217;t be too happy about this trend.&lt;/p&gt;
&lt;p&gt;Now, Wimdu has been accused by AirBnB for using &lt;a href=&quot;http://techcrunch.com/2011/06/09/airbnb/&quot;&gt;shady business tactics&lt;/a&gt; and I am only mildly surprised. Because, in the end, what you have to do to make such a business strategy successful is owning the market, in this case, Europe. That&amp;#8217;s why City Deals, in the end, had more than 600 employees, most of them working in sales, before being sold to Groupon. Same now happens with wimdu.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; My employer, &lt;a href=&quot;http://www.mindmatters.de/&quot;&gt;mindmatters&lt;/a&gt;, has been working, for a short period of time, for another &lt;a href=&quot;http://www.airbnb.com/&quot;&gt;AirBnB&lt;/a&gt; copycat, called 9flats. I found that problematic. I haven&amp;#8217;t been on the team, though and only found out about the actual type of application post launch, as the team was told to be silent about it. I found that problematic &amp;#8211; but that&amp;#8217;s another story.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; A group of people I would call friends, or at least &amp;#8220;fellow developers&amp;#8221; still work, as freelancers or contractors, for 9flats. When we talk about it, it can get awkward. I must admit that I so far usually avoided talking about it, because of that awkwardness.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Meta-Disclosure: I changed the wording here, because it didn&amp;#8217;t feel exactly right. Go look it up in &lt;a href=&quot;http://github.com/halfbyte/jan.krutisch.de&quot;&gt;git&lt;/a&gt;, if you&amp;#8217;re interested in the original)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, let&amp;#8217;s keep shady business tactics away for a moment. Let&amp;#8217;s say it&amp;#8217;s totally unproblematic to copy an application screen by screen on your employers request. How do apps like wimdu and 9flats make the internet a better place? The world? How do they make people happier? Can you come up with a useful answer here, without ridiculing yourself utterly and completely?&lt;/p&gt;
&lt;p&gt;Because, you know what? AirBnB works perfectly on the European market. Because, on the inside, it is a very, very simple business model without huge local differences.&lt;/p&gt;
&lt;p&gt;Well, to be honest, there&amp;#8217;s one aspect which makes local adaptions possible, and that is international payment issues: For example, credit cards are not as popular in some European countries. Does that justify a million dollar rat race of three companies for European Championship Of Peer To Peer Roomsharing? Yeah, sure, why not. Wait, what?&lt;/p&gt;
&lt;p&gt;Another thought: Does the world really need another couponing platform? Ah, well, let&amp;#8217;s not go there, I don&amp;#8217;t have my Kleenex at hand to wipe up my tears of despair.&lt;/p&gt;
&lt;p&gt;And, to drive home my point, let me put aside copycat-ism for a little while. For example, we&amp;#8217;ve been working, in 2010, for a startup that shall remain unnamed, which actually had a very cool core idea. A very technically challenging one, as well. But then, their business model was completely focused on ads, and therefore traffic, and therefore Google. If you have ever worked on a business completely focused on &lt;span class=&quot;caps&quot;&gt;SEO&lt;/span&gt;, you know what this means: It means optimizing your platform for a very specific user, namely the Googlebot. What it doesn&amp;#8217;t mean is building a good product for the other pesky folks: The humans. Which means that in the end you&amp;#8217;re building a less-than-subpar product which is best read with the eyes of a googlebot. And in the process, we actually made the internet a bit worse by spamming the google index with links to a platform that largely wasn&amp;#8217;t working very well but displayed highly profitable ads. Adding insult to injury, the client turned out the be somewhat of a dick. And that is the nicest way of putting it.&lt;/p&gt;
&lt;p&gt;Needless to say, making the internet or the world a better place wasn&amp;#8217;t very high on &lt;strong&gt;their&lt;/strong&gt; list of priorities.&lt;/p&gt;
&lt;p&gt;So, I find it problematic to work for those kind of projects. Other fellow developers have less problems with that. They may, in some cases, even find it refreshing to be part of some kind of challenge on world domination. Which I can relate to, at least a little.&lt;/p&gt;
&lt;p&gt;In the end, to be completely honest, as much as I would like to claim that these &amp;#8220;ethical&amp;#8221; rules are imperative for my selection of projects, I must admit, that I am, too, utterly failing at this.&lt;/p&gt;
&lt;p&gt;But, you know what: I&amp;#8217;d very much like to change that. As much as possible. It&amp;#8217;s actually hard if you are working at a company which is selling services, because it&amp;#8217;s not always you deciding what to work on and it&amp;#8217;s not always possible to be choosy about your clients (Sidenote: That&amp;#8217;s why it&amp;#8217;s always a huge satisfaction to decide not to work for a specific client, if you&amp;#8217;re able to). But, does it need to be that way? The current need for developers actually gives us a lot of power in that respect. We &lt;strong&gt;could&lt;/strong&gt; say no.&lt;/p&gt;
&lt;p&gt;So, whenever I &lt;strong&gt;am&lt;/strong&gt; able to chose, whenever I &lt;strong&gt;have&lt;/strong&gt; the means of saying no, please do me a favour and hold me accountable on this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I want to build stuff that makes the world and the internet a better place. If possible, exclusively so.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you feel the same and you need help on something, please let me know. There&amp;#8217;s also a company full of people that largely feel the same on this as I do, which is why I am still enjoying working for &lt;a href=&quot;http://www.mindmatters.de/&quot;&gt;mindmatters&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A closing personal message to my friends and fellow developers: I am not out to judge you. As I said, I am not very good at this myself, mostly. But I want this to become &lt;strong&gt;my own&lt;/strong&gt; &amp;#8220;ethical&amp;#8221; baseline. And if you can relate to that, feel free to join me here. Let&amp;#8217;s be our own judges on this. If you have diffenrent views on this, please share. If, in the end, this starts a discussion on the ethical baselines of our profession, I will be the happiest person on earth.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/jankrutisch/rss/~4/FbRMWwjfmSg&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>jan.krutisch.de</name>
			<uri>http://jan.krutisch.de</uri>
		</author>
		<source>
			<title type="html">jan.krutisch.de</title>
			<subtitle type="html">An ongoing conversation between Jan Krutisch and the Interwebs on nothing in particular.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/jankrutisch/rss/"/>
			<id>http://feeds.feedburner.com/jankrutisch/rss/</id>
			<updated>2012-01-15T22:20:31+00:00</updated>
			<rights type="html">Copyright 2004-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Redesign, Schmedesign</title>
		<link href="http://feedproxy.google.com/~r/jankrutisch/rss/~3/JH9Lk3lgo18/"/>
		<id>http://jan.krutisch.de/en/2011/06/18/Redesign-Schmedesign.html/</id>
		<updated>2011-06-17T22:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Yeah, right. I did a big bang relaunch on this blog. Well, not really, it took me about 6 hours, markup changes were minimal, but the whole thing is a little more sematic now and actually is html5. I used &lt;a href=&quot;http://www.andytlr.com/&quot;&gt;Andy Taylor&amp;#8217;s&lt;/a&gt; excellent &lt;a href=&quot;http://cssgrid.net/&quot;&gt;1140 responsive grid&lt;/a&gt;, in form of the &lt;a href=&quot;https://github.com/zombor/eleven40-compass&quot;&gt;eleven40 compass extension&lt;/a&gt; from &lt;a href=&quot;http://zombor.net&quot;&gt;Jeremy Bush&lt;/a&gt; (I ran across some issues with it, hopefull I&amp;#8217;ll find the time to fix them soon).&lt;/p&gt;
&lt;p&gt;The rationale of this redesign was to cut down on visual complexity. It is now more or less one of those &amp;#8220;standard, two column, image on top, large font, serif text, sans-serif headlines&amp;#8221; blog templates. I used two of the proposed font stacks from the excellent &lt;a href=&quot;http://www.awayback.com/revised-font-stack/&quot;&gt;Revised Font Stack&lt;/a&gt; article by Amrinder Sandhu, to be not completely in boring-land with Helvetica and Times New Roman or something like that. I am happy with the design for now, although I would love to apply some &lt;a href=&quot;http://wolfgangwopperer.com/&quot;&gt;Wowo&lt;/a&gt; style baseline nazi love to it somewhere in teh futare.&lt;/p&gt;
&lt;p&gt;And, yes, I implanted a small Adsense Ad on the page.&lt;/p&gt;
&lt;p&gt;How do you like it? Lemme know on &lt;a href=&quot;http://twitter.com/halfbyte&quot;&gt;the twitters&lt;/a&gt; or in the comments. Thank you for your business.&lt;/p&gt;
&lt;p&gt;Now I only need to write more often.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/jankrutisch/rss/~4/JH9Lk3lgo18&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>jan.krutisch.de</name>
			<uri>http://jan.krutisch.de</uri>
		</author>
		<source>
			<title type="html">jan.krutisch.de</title>
			<subtitle type="html">An ongoing conversation between Jan Krutisch and the Interwebs on nothing in particular.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/jankrutisch/rss/"/>
			<id>http://feeds.feedburner.com/jankrutisch/rss/</id>
			<updated>2012-01-15T22:20:31+00:00</updated>
			<rights type="html">Copyright 2004-2009</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Programmiert Ihr Deutsch?</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/37kSzH7XixE/programmiert-ihr-deutsch-nachgeladen"/>
		<id>http://dennisreimann.de/blog/programmiert-ihr-deutsch-nachgeladen</id>
		<updated>2011-06-01T13:37:00+00:00</updated>
		<content type="html">&lt;p&gt;Mit diesem Post würde ich gerne ein Thema wieder aufgreifen, dass ich vor drei Jahren
                          einmal angeschnitten habe: &lt;a href=&quot;http://dennisreimann.de/blog/programmiert-ihr-deutsch/&quot;&gt;Programmiert Ihr Deutsch?&lt;/a&gt;&lt;/p&gt;
                          
                          &lt;p&gt;Grund dafür ist, dass wir in zwei aktuellen Projekten dazu übergegangen sind, alles was
                          mit der Domäne und Tests zu tun hat komplett in deutsch zu entwickeln. Nach anfänglicher Skepsis
                          darüber muss ich nun sagen, dass ich meine Meinung deutlich geändert habe und es in jedem kommenden
                          Projekt wohl wieder so machen würde – es sei denn natürlich, es gibt Beschränkungen bzw. gute Gründe eben
                          nicht deutsch als Sprache zu verwenden (bspw. englischsprachige Teammitglieder oder Kunden).&lt;/p&gt;
                          
                          &lt;p&gt;Wir haben Modell-, Controller- und Attributnamen auf deutsch definiert, was auch erstaunlich
                          problemlos funktioniert. Die einzigen Anpassungen die in Rails daraus resultieren sind, dass
                          es erfordert die Inflections (&lt;code&gt;config/initializers/inflections.rb&lt;/code&gt;) anzupassen. Alles weitere
                          (bspw. Datenbanktabellennamen) resultiert daraus und benötigt weiter keine Konfiguration. Wir
                          waren bislang noch nicht wagemutig genug das auf die Spitze zu treiben und auch Umlaute in Klassen-
                          und Dateinamen zu verwenden, das bleibt dann dem geneigten Leser als Übung überlassen ;)&lt;/p&gt;
                          
                          &lt;h3&gt;Testing&lt;/h3&gt;
                          
                          &lt;p&gt;Richtig angenehm wird es in den Tests: Cucumber bringt von Haus aus mit, Features auch in anderen
                          Sprachen als Englisch zu verfassen. Alles was dazu nötig ist, ist bei der Installation das Kürzel
                          der Sprache mitzugeben, für die zusätzliche Web Steps generiert werden sollen, in unserem Fall:&lt;/p&gt;
                          
                          &lt;p&gt;&lt;code&gt;rails generate cucumber:install de&lt;/code&gt;&lt;/p&gt;
                          
                          &lt;p&gt;Eine Übersicht der in deutsch benötigten Keywords gibt es mittels&lt;/p&gt;
                          
                          &lt;p&gt;&lt;code&gt;bundle exec cucumber --i18n de&lt;/code&gt;&lt;/p&gt;
                          
                          &lt;p&gt;Die Testdaten legen wir über Tabellen an, was meiner Meinung nach mittlerweile auch etwas übersichtlicher
                          ist als Bibliotheken zu verwenden, die Factory Steps generieren (wie &lt;a href=&quot;https://github.com/makandra/cucumber_factory&quot;&gt;cucumber_factory&lt;/a&gt;
                          oder &lt;a href=&quot;https://github.com/ianwhite/pickle&quot;&gt;pickle&lt;/a&gt;). Dies ist aber sicherlich Geschmacksache und es gäbe
                          auch Möglichkeiten, die Stepgeneratoren so anzupassen, dass sie auch für deutsche Steps funktionieren.
                          Hier ein kurzes Beispiel für eines unserer Features (wichtig für Cucumber ist dabei der Kommentar in der
                          ersten Zeile):&lt;/p&gt;
                          
                          &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# language: de&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&lt;/span&gt;
                          
                          &lt;span class=&quot;k&quot;&gt;Funktionalität:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Kunde-Login&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;  Als Kunde&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;  Möchte ich mich mit meinen Zugangsdaten einloggen&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;  Um an der Auktion teilnehmen zu können&lt;/span&gt;
                          
                          &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Grundlage:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Bestehender Kunde&lt;/span&gt;
                          &lt;span class=&quot;k&quot;&gt;    Angenommen &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;es gibt die folgenden Kunden:&lt;/span&gt;
                          &lt;span class=&quot;k&quot;&gt;      |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; email&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;        |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; kundennummer&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; password&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;   |&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&lt;/span&gt;
                          &lt;span class=&quot;k&quot;&gt;      |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; kunde@web.de&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 123456&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;       |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; top_secret&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;
                          
                          &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Szenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Erfolgreiches Login mit E-Mail-Adresse&lt;/span&gt;
                          &lt;span class=&quot;k&quot;&gt;    Wenn &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich auf die Login-Seite gehe&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; mit &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;kunde@web.de&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; ausfülle&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Passwort&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; mit &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;top_secret&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; ausfülle&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich auf &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Anmelden&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; drücke&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Dann &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sollte ich auf der Startseite sein&lt;/span&gt;
                          &lt;span class=&quot;nf&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Und &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ich sollte &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Sie wurden erfolgreich eingeloggt&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; sehen&lt;/span&gt;
                          &lt;/pre&gt;
                          &lt;/div&gt;
                          
                          
                          &lt;p&gt;Auch die Specs lassen sich bis auf die Keywords sehr gut auf deutsch schreiben, was bei uns dann
                          in etwa so aussieht:&lt;/p&gt;
                          
                          &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# encoding: utf-8&lt;/span&gt;
                          
                          &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'spec_helper'&lt;/span&gt;
                          
                          &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Auktionator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                            
                            &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bei bevorstehender Auktion&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                              
                              &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@los1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:los&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;losnummer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@los2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:los&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auktionstermin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;losnummer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@termin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              
                              &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#phase&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                
                                &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sollte 'auktion_bevorstehend' zurückgeben&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'auktion_bevorstehend'&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auktion_bevorstehend?&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be_true&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                          
                              &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#los&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                              
                                &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;sollte das aktuelle Los zurückgeben&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                  &lt;span class=&quot;vi&quot;&gt;@auktionator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;los&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@los1&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                          
                          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                          &lt;/pre&gt;
                          &lt;/div&gt;
                          
                          
                          &lt;p&gt;Mich würde wie gesagt eure Meinung dazu interessieren, vielleicht habt ihr Tips und weitere Tools
                          dafür. Wer darüber hinaus auf der Suche nach Anregungen zum Thema Domänenabbildung ist, dem sei ggf.
                          noch Eric Evans’ Buch &lt;a href=&quot;http://www.amazon.de/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot;&gt;Domain Driven Design&lt;/a&gt;
                          empfohlen - dies aber wohl eher nur als Randnotiz.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Silencing the Rails log on a per-action basis</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/T5vFYhbirLY/silencing-the-rails-log-on-a-per-action-basis"/>
		<id>http://dennisreimann.de/blog/silencing-the-rails-log-on-a-per-action-basis</id>
		<updated>2011-05-26T11:14:00+00:00</updated>
		<content type="html">&lt;p&gt;In our current project we are having an action that is polled every ten seconds by the clients.
                            This clutters up the log, so I was looking for a way to completely silence the Rails logger
                            for this action. It turns out that you have to swap the default logger with a custom one, because
                            even when you use the &lt;code&gt;Rails.logger.silence&lt;/code&gt; block in your action, you will still find a line
                            in your log that is printed out before the request gets dispatched.&lt;/p&gt;
                            
                            &lt;p&gt;Here’s our custon logging class:&lt;/p&gt;
                            
                            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# lib/custom_logger.rb&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomLogger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{})&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;
                                &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              
                              &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'X-SILENCE-LOGGER'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'PATH_INFO'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;silence&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
                                    &lt;span class=&quot;vi&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                                &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            &lt;/pre&gt;
                            &lt;/div&gt;
                            
                            
                            &lt;p&gt;This way you can either define request paths that should not get logged or send the &lt;code&gt;X-SILENCE-LOGGER&lt;/code&gt;
                            header for the request you don’t want to log.&lt;/p&gt;
                            
                            &lt;p&gt;To make use of your own logger, you’ll have to swap the default logger, which is included as
                            a Rack middleware:&lt;/p&gt;
                            
                            &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# config/application.rb&lt;/span&gt;
                            &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'/../lib/custom_logger.rb'&lt;/span&gt;
                            
                            &lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;MyApp&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;
                                &lt;span class=&quot;c1&quot;&gt;# Middlewares&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;middleware&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CustomLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:silenced&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/noisy/action.json&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
                            &lt;/pre&gt;
                            &lt;/div&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Why Big Bang Relaunches are evil</title>
		<link href="http://feedproxy.google.com/~r/jankrutisch/rss/~3/Jbom0JfugTA/"/>
		<id>http://jan.krutisch.de/en/2011/05/17/why-big-bang-relaunches-are-evil.html/</id>
		<updated>2011-05-16T22:00:00+00:00</updated>
		<content type="html">&lt;p&gt;A few days back, &lt;span class=&quot;caps&quot;&gt;XING&lt;/span&gt; started an &lt;a href=&quot;http://whatsnew.xing.com/de/index.php&quot;&gt;online campaign&lt;/a&gt; for their grand redesign that will launch in june 2011. The campaign is nicely made, with interviews with some of the people behind that huge undertaking. I like it.&lt;/p&gt;
&lt;p&gt;What I strongly dislike, though, are big bang relaunches. I voiced that concern on twitter and this lead into a longish discussion with various people. So, I&amp;#8217;m writing this post to archive my points I made yesterday, but also to elaborate a bit on the responses.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s my basic set of assumtions. If you don&amp;#8217;t agree with them, you won&amp;#8217;t agree with the rest of my text, which is fine, by the way :)&lt;/p&gt;
&lt;p&gt;1. Agile project/product management and software development is the best way to build our software. I don&amp;#8217;t care if you use Kanban or Scrum or XP or whatever, but don&amp;#8217;t go chasin&amp;#8217; waterfalls.&lt;br /&gt;
2. We build software for our users. This sounds like a no-brainer but I&amp;#8217;ve too often seen people build software for the googlebot. Did it myself even, but not without cringing.&lt;br /&gt;
3. We do have a lean organisation without much organisational friction. I&amp;#8217;ll come back to this later, because this actually may be a bit of a stretch.&lt;/p&gt;
&lt;p&gt;Funnily enough, we had that discussion briefly last wednesday at the Ruby Usergroup, where it became obvious that Big Bang Relaunches are obviously one of the clearer reasons to have a good branching model on your &lt;span class=&quot;caps&quot;&gt;SCM&lt;/span&gt; (Source Code Management) system which was the main topic. The top reasons given why Big Bang Relaunches are necessary according to the audience were:&lt;/p&gt;
&lt;p&gt;1. Because Marketing wants them&lt;br /&gt;
2. Because Designers can&amp;#8217;t do incremental design&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s look at them in detail.&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;span id=&quot;more&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Marketing loves Big Bang Relaunches&lt;/h3&gt;
&lt;p&gt;This is quite obviously true. Marketing traditionally comes from a strong product background. You are usually dealing with large release cycles and thus, a Big Bang Launch is a fixed point in time that gives you an anchor to base your marketing actions around. That&amp;#8217;s understood.&lt;/p&gt;
&lt;p&gt;Is it &lt;strong&gt;the&lt;/strong&gt; best way to communicate changes to the user? Do users love Bing Bang Relaunches as well? First of all, my answer would be a straight &lt;strong&gt;No!&lt;/strong&gt;. Most users, especially the loyal, long time power users, usually &lt;strong&gt;hate&lt;/strong&gt;, &lt;strong&gt;hate&lt;/strong&gt;, &lt;strong&gt;hate&lt;/strong&gt; relaunches. Ask people that have a product at the market for years, like the people from germans social network dinosaur &lt;a href=&quot;http://www.wer-weiss-was.de/&quot;&gt;Wer Weiss Was&lt;/a&gt;. Mind you, these people hate all changes, so you won&amp;#8217;t make them entirely happy by only doing incremental changes to your site, &lt;strong&gt;evar&lt;/strong&gt;, but it certainly soothes the pain.&lt;/p&gt;
&lt;p&gt;Additionally, if your marketing really loves Big Bang Relaunches, it also means that Marketing &lt;strong&gt;did not get&lt;/strong&gt; the core principles of &lt;strong&gt;agile&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As well as it is our (developers) responsibility to continuously improve the software, it is, in a truly agile environment, the responsibility of Marketing to continuously market new features, simplifications and small adaptions to the users. You have to transform your work from huge bursts of marketing activity (product launch campaigns) to a continous flow of marketing goodness. If a large feature comes along, by all means, celebrate it and rock it, but otherwise, just do your job on a day to day basis. Have standups, watch your developers scrum/kanban board. Yes, this will also mean that you probably won&amp;#8217;t need that huge relaunch party you were so much looking forward to. That&amp;#8217;s tough. You&amp;#8217;ll find other things to celebrate.&lt;/p&gt;
&lt;h3&gt;Designers can&amp;#8217;t do incremental design&lt;/h3&gt;
&lt;p&gt;That&amp;#8217;s the tough one. It is tough because web design is a very tough field in itself. Why? Because we still mix up so many different things into these two words. Do we mean interface design? Graphics design? UX? What does it all mean? Double Rainbow? Here&amp;#8217;s my own interpretation.&lt;/p&gt;
&lt;p&gt;1. If you call yourself an UX expert, you should hate Big Bang Relaunches. Why? Because they are usually a lost chance to learn things. Sure, you can do all kinds of user tests in the relaunch process, but everybody should know by now that you always should prefer real world data to lab data when it comes to user feedback.&lt;/p&gt;
&lt;p&gt;2. If you are a graphics designer, you will probably be more happy with Big Bang Relaunches, because, and I totally acknowledge that, it is invariantly harder to change a site&amp;#8217;s design gradually than it is to do the redesign in one big step. But, as long as you&amp;#8217;re not working on a product presentation page on a retailers web page, that should not be the way you should do your job, anyway. Mind you, being artistically responsible for the look and feel of a web application is a very tough job, because it means two very different things at once: You need to pay incredible amounts of attention to details and need to spend a lot of time doing UX work (or collaborating with an UX expert), probably regarding very small elements on a single page, and, at the same time, keep an eye on the overall look and keep things consistent on a larger scale. But if your only answer to this is that you want to do Big Bang Relaunches, you are not trying hard enough.&lt;/p&gt;
&lt;h3&gt;There is a step three&lt;/h3&gt;
&lt;p&gt;Ultimately, it&amp;#8217;s a question of organisation. To be able to do &lt;strong&gt;only&lt;/strong&gt; incremental changes to your software, your organisation must breathe &lt;strong&gt;agile&lt;/strong&gt;. I know I sound like some crazy agile marketing guy, but really, that&amp;#8217;s the whole point. Everybody must adhere to the thought of incremental improvement. And also, which sounds counter intuitive, it needs strong leadership. To prevent feature creep. To prevent all those dark corners that every software seems to accumulate over time, where nobody wants to touch anything anymore. This strong leadership needs not to be carried out by &amp;#8220;the UX guy&amp;#8221; or &amp;#8220;the product guy&amp;#8221;, it can also be organized and carried out as a collaborate effort, but anyway, that&amp;#8217;s the really hard part. That is also where most organisations fail. When organisations grow, responsibilities are divided up without keeping vital connections between disciplines. You suddenly have a head of UX and a head of Art Direction and those two people hate each other and the only thing they can agree on is that they hate that guy from Product Management even more.&lt;/p&gt;
&lt;p&gt;And suddenly, a Big Bang Relaunch is the only thing that will enable you and your organisation to get back your focus. Usually this involves organisational changes as well, and also really painful discussions in the conceptional phase.&lt;/p&gt;
&lt;h3&gt;Why Big Bang Relaunches are a bad idea.&lt;/h3&gt;
&lt;p&gt;Of course, you do organise your relaunches in an agile fashion. So you think you&amp;#8217;re safe. If you&amp;#8217;re not, you&amp;#8217;re in even deeper trouble, because you suddenly lock away yourself from reality for the runtime of the project (which, in XING&amp;#8217;s case seems to be more than half a year). So you don&amp;#8217;t. The problem is pretty big, still. Because, in reality, doing a big fat redesign means that you need to divide up your resources. There will be a relaunch team, and a maintenance team. Also, you need to fork your code base. While I&amp;#8217;m no general opponent of forks or branches, they should be small and local. Huge global forks give you &lt;strong&gt;a lot&lt;/strong&gt; to worry about. While git in theory makes it really easy to keep your relaunch-branch up to date with changes in your non-relaunch branch, in practice, especially with huge refactorings in html templates, you&amp;#8217;re in for a lot of pain. Trust me, I&amp;#8217;ve been there. Ask me about 2004 at &lt;span class=&quot;caps&quot;&gt;AOL&lt;/span&gt;.de. I will tell you stories that involve branches in &lt;span class=&quot;caps&quot;&gt;CVS&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Which means that you end up splitting your dev team, splitting your code base and, if you take the process seriously, also the rest of your company. One half does day to day business, the other half is locked up in the basement. However you do the splitting, you&amp;#8217;ll end up with not getting things done at one end.&lt;/p&gt;
&lt;p&gt;Also, in every Big Bang Relaunch project I&amp;#8217;ve seen, you start the relaunch with the promise of a huge cleanup. And then stakeholders come into play, and there&amp;#8217;s a lot of changes and suddenly you&amp;#8217;re in crunch mode to finish the Big Bang Relaunch inside the timeframe (That has, in worst case, arbitrarily set by marketing without any backup by your dev team) and in the end, the front end may have gotten some love, but the amout of refactoring and simplification you were hoping to get at the start of the project has nothing to do with the reality you end up with.&lt;/p&gt;
&lt;h3&gt;But didn&amp;#8217;t you get the memo? Reality doesn&amp;#8217;t work like that!&lt;/h3&gt;
&lt;p&gt;Yes it does. There are &lt;strong&gt;tons&lt;/strong&gt; of examples of companies and startups doing an incredible job of continuously improving their platform, launching features, taking useless features away, refining and polishing their UI. Github, All 37signals projects, Dropbox, even most Google products. To be honest, almost all of the web tools I use on a day to day basis work like that. (With the notable and also quite painful exception of the infamous newtwitter.)&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s very hard to get this right. It takes an exceptional team with exceptional self organisation and/or leadership. It takes a strong product vision and extreme focus on what&amp;#8217;s important (And even harder to get right: A good idea on how to find out what&amp;#8217;s important).&lt;/p&gt;
&lt;p&gt;But if you get this right, you&amp;#8217;ll end up with happier customers, happier team members and a whole lotta less stress.&lt;/p&gt;
&lt;p&gt;Oh, and you also don&amp;#8217;t have to waste money on a PR company to build a campaign site to support the Big Bang Relaunch.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/jankrutisch/rss/~4/Jbom0JfugTA&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>jan.krutisch.de</name>
			<uri>http://jan.krutisch.de</uri>
		</author>
		<source>
			<title type="html">jan.krutisch.de</title>
			<subtitle type="html">An ongoing conversation between Jan Krutisch and the Interwebs on nothing in particular.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/jankrutisch/rss/"/>
			<id>http://feeds.feedburner.com/jankrutisch/rss/</id>
			<updated>2012-01-15T22:20:31+00:00</updated>
			<rights type="html">Copyright 2004-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Say Hello To Manuel</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/JMhP-69eQVg/"/>
		<id>http://blog.railslove.com/?p=942</id>
		<updated>2011-05-06T20:49:38+00:00</updated>
		<content type="html">&lt;p&gt;As mentioned on &lt;a href=&quot;https://twitter.com/railslove/status/66553385335263233&quot;&gt;twitter&lt;/a&gt; we want to introduce you to &lt;a href=&quot;http://railslove.com/about-us#manuel_korfmann&quot;&gt;Manuel Korfmann&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
Manuel is a 16-year-old boy, who loves seeing and writing elegant, clean and DRY Ruby code. And since Rails is perfectly suited for doing this, Manuel loves Rails too. So it seems like his destiny is to work for Railslove. Manuel started programming Ruby about a year ago, though he had some experiences with C++ before but don&amp;#8217;t wants to be approached upon this subject.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;You can follow Manuel on &lt;a href=&quot;http://www.twitter.com/mkorfmann&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://www.github.com/mkorfmann&quot;&gt;Github&lt;/a&gt; and visit his &lt;a href=&quot;http://mkorfmann.github.com/&quot;&gt;homepage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Glad that you&amp;#8217;re hacking at Railslove!&lt;br /&gt;
We wish you a very nice time!&lt;/p&gt;
&lt;p&gt;The Crew!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JMhP-69eQVg:F9PcivZgpvY:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JMhP-69eQVg:F9PcivZgpvY:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JMhP-69eQVg:F9PcivZgpvY:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=JMhP-69eQVg:F9PcivZgpvY:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Mai 13th – the next DevHouse Friday Chillout</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/jbfhE5wBZ-Y/"/>
		<id>http://blog.railslove.com/?p=939</id>
		<updated>2011-05-02T08:36:22+00:00</updated>
		<content type="html">&lt;p&gt;DevHouseFriday is an event intended for creative and curious people interested in technology inspired by SuperHappyDevHouse. Once a month (on fridays) we talk about technology and share our knowledge while meeting new people and learning stuff we are all interested in.&lt;/p&gt;
&lt;p&gt;Everyone had troubles while writing code. We need people they can tell us that special experience with us.&lt;/p&gt;
&lt;p&gt;What kind of trouble? How did you resolved it? Tell us everything!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Am 13.05.2011 um 19:00 Uhr&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;millepondo services&lt;br /&gt;
Heinrich-Brüning-Str. 8&lt;br /&gt;
50969 Cologne Deutschland (Germany)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.millepondo.de&quot;&gt;http://www.millepondo.de&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://devhousefriday.org&quot;&gt;Anmeldung auf der DevHouse mixxt-Seite.&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=jbfhE5wBZ-Y:Ctd_vcV751A:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=jbfhE5wBZ-Y:Ctd_vcV751A:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=jbfhE5wBZ-Y:Ctd_vcV751A:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=jbfhE5wBZ-Y:Ctd_vcV751A:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">EventMachine, How Does It Work?</title>
		<link href="http://www.paperplanes.de//2011/4/25/eventmachine-how-does-it-work.html"/>
		<id>http://www.paperplanes.de//2011/4/25/eventmachine-how-does-it-work.html</id>
		<updated>2011-04-25T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;At this year's &lt;a href=&quot;http://scottishrubyconference.com/&quot;&gt;Scottish Ruby Conference&lt;/a&gt;, I gave a talk about
&lt;a href=&quot;http://rubyeventmachine.com&quot;&gt;EventMachine&lt;/a&gt;, &lt;a href=&quot;http://eventmachine-scotrubyconf.heroku.com/&quot;&gt;slides&lt;/a&gt; are available.
Amidst the hype around Node.js it's too easy to forget that Ruby has had evented I/O libraries for years.
&lt;a href=&quot;http://rubyeventmachine.com&quot;&gt;EventMachine&lt;/a&gt;, &lt;a href=&quot;http://tinyclouds.org/libebb/&quot;&gt;libebb&lt;/a&gt;, &lt;a href=&quot;http://rev.rubyforge.org/&quot;&gt;rev&lt;/a&gt;,
&lt;a href=&quot;http://coolio.github.com/&quot;&gt;cool.io&lt;/a&gt;, to name a few. As a general introduction I recommend reading &lt;a href=&quot;http://www.kegel.com/c10k.html&quot;&gt;Dan Kegel's article
on the C10K problem&lt;/a&gt;, the problem of handling 10000 server connections on a single
machine. It introduces all the evented approaches that have been implemented in the different operating systems over the
last some 15 years.&lt;/p&gt;

&lt;p&gt;In preparation for the talk I got curious about EventMachine's innards. So I thought it'd be nice to share my findings
with you. Node.js kids, pay attention, this concerns you as well. It may be JavaScript, but in the end Node.js works in
a similar fashion, though it builds on &lt;a href=&quot;http://software.schmorp.de/pkg/libev.html&quot;&gt;libev&lt;/a&gt;, which does most of the
plumbing for the different operating system implementations of non-blocking I/O.&lt;/p&gt;

&lt;p&gt;Most of the magic happens inside the C++ part of EventMachine, so now's as good a time as any to dig into it and find
out how it works. There'll be code in here, not assembler, but I'll be throwing constants, standard library functions
and TCP networking bits (from C, not from Ruby) at you. There's no magic however, and when in doubt, consult the man
pages. You do know about man pages, right? They're awesome.&lt;/p&gt;

&lt;h3&gt;while(true): The Event Loop&lt;/h3&gt;

&lt;p&gt;EventMachine is based on the idea of an event loop, which is basically nothing more than an endless loop. The standard
snippet of code you're wrapping all your evented code is this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;EM.run do
  # go forth and handle events
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can look at the details of what the method does in &lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/bd77b0503557de565d3cc9b629ab260b4055bc9d/lib/eventmachine.rb#L185-240&quot;&gt;its full
glory&lt;/a&gt;.
Other than initializing some things, it dives down into the C++ layer immediately, and it's where most of the magic
happens from now on.&lt;/p&gt;

&lt;p&gt;Three C/C++ extension files are of importance,
&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/6f7885166746e4dca124780432c8315cd57ca89d/ext/rubymain.cpp&quot;&gt;&lt;code&gt;ext/rubymain.cpp&lt;/code&gt;&lt;/a&gt;
is the bridge between Ruby and the C code layer. It uses Ruby's C functions, mostly to convert datatypes for the later
below. It then calls into code defined in
&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/6f7885166746e4dca124780432c8315cd57ca89d/ext/cmain.cpp&quot;&gt;&lt;code&gt;ext/cmain.cpp&lt;/code&gt;&lt;/a&gt;,
which in turn bridges the C and the C++ code.&lt;/p&gt;

&lt;p&gt;When you call &lt;code&gt;EM.run&lt;/code&gt; to start the event loop, it calls down into the C layer to &lt;code&gt;t_run_machine_without_threads&lt;/code&gt;, which
is called as &lt;code&gt;run_machine&lt;/code&gt;, and which in turn calls
&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/6f7885166746e4dca124780432c8315cd57ca89d/ext/em.cpp#L427&quot;&gt;&lt;code&gt;EventMachine_t::Run()&lt;/code&gt;&lt;/a&gt;,
whose interesting bits are shown below.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; while (true) {
   _UpdateTime();
   if (!_RunTimers())
     break;

  _AddNewDescriptors();
  _ModifyDescriptors();

  if (!_RunOnce())
    break;
  if (bTerminateSignalReceived)
    break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's your event loop, doesn't look that scary now, right? It basically does five things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Update the current time (line 2)&lt;/p&gt;

&lt;p&gt;Used in the next step to determine whether a timer should be fired&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run configured timers (line 3)&lt;/p&gt;

&lt;p&gt;All the timers specified through either &lt;code&gt;add_timer&lt;/code&gt; or &lt;code&gt;add_periodic_timer&lt;/code&gt; are run here. When you add a timer,
EventMachine stores it in a map indexed with the time it's supposed to fire. This makes checking the list for the ones
that should be fired in the current iteration a cheap operation.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/6f7885166746e4dca124780432c8315cd57ca89d/ext/em.cpp#L1008&quot;&gt;&lt;code&gt;_RunTimers()&lt;/code&gt;&lt;/a&gt;
iterates over the list of timers until it reaches one entry whose key (i.e. the time it's supposed to fire) is higher
than the current time. Easy and efficient.&lt;/p&gt;

&lt;p&gt;On a side note, &lt;code&gt;_RunTimers&lt;/code&gt; always returns true, so it's a bit weird that the return value is checked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new descriptors (line 6)&lt;/p&gt;

&lt;p&gt;Whenever you open a new server connection, EventMachine adds an object representing the connection and the associated
callbacks to this list. All connections and descriptors created in the last iteration are handled, which basically
includes setting additional options if applicable and add them to the list of active connections.&lt;/p&gt;

&lt;p&gt;On the operating system level a descriptor represents a file handle or a socket connection.  When you open a file,
create a connection to another machine or create a server to listen for incoming connections, all of them are
represented by descriptors, which are basically integers pointing into a list maintained by the operating system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify descriptors (line 7)&lt;/p&gt;

&lt;p&gt;Modify existing descriptors, if applicable. This only has any effect when you're using epoll, which we'll get to
later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the event (line 9)&lt;/p&gt;

&lt;p&gt;Check all open file descriptors for new input. Read whatever's available, run the associated event callbacks. The
heart of the event loop, worth taking a closer look below.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The event loop really is just an endless loop after all.&lt;/p&gt;

&lt;h3&gt;Open a Socket&lt;/h3&gt;

&lt;p&gt;When you call &lt;code&gt;EM.connect&lt;/code&gt; to open a connection to a remote server, the connection will be immediately created, but it
may not finish until later. The resulting connection will have a bunch of properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The descriptor is configured to not block on input and output by setting the socket option &lt;code&gt;O_NONBLOCK&lt;/code&gt;. This way
reads will immediately return when there's no data instead of waiting for some to arrive, and writes don't necessarily
write all the data they're given. It also means that a call to
&lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/connect.2.html&quot;&gt;&lt;code&gt;connect()&lt;/code&gt;&lt;/a&gt; to create a new connection returns
before it's fully created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Nagle algorithm is disabled to prevent the TCP stack from delaying sending packets by setting &lt;code&gt;TCP_NODELAY&lt;/code&gt; on the
socket. The operating system wants to buffer output to send fewer packets. Disabling Nagle causes any writes to be
sent immediately. As EventMachine does internal buffering, it's preferrable for the data to be really sent when it's
eventually written to a socket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reuse connections in &lt;code&gt;TIME_WAIT&lt;/code&gt; state before they're fully removed from the networking stack. TCP keeps connections
around for a while, even after they're closed to ensure that all data from the other side really, really made it to
your end. Nice and all, but in environments with a high fluctuation of connnections, in the range of hundreds to
thousands per second, you'll run out of file descriptors in no time.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Opening a socket is an immediate event, it happens as soon as you create a new connection. Running any callbacks on it
won't happen until the next iteration of the event loop. That's why it's safe to e.g. fire up a new HTTP request and
then attach callbacks to it. Even if that wouldn't be the case, EventMachine's
&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/master/docs/DEFERRABLES&quot;&gt;Deferrables&lt;/a&gt; (not to be confused with
&lt;code&gt;EM.defer&lt;/code&gt;) ensure that callbacks are fired even after the original event fired, when they're added at a later time.&lt;/p&gt;

&lt;p&gt;What is immediately called, though, is the &lt;code&gt;post_init&lt;/code&gt; method on the connection object.&lt;/p&gt;

&lt;p&gt;Opening a network connection is just one thing you can do with EventMachine, but as it's the one thing you're most
likely to do when you're using it, let's leave it at that.&lt;/p&gt;

&lt;h3&gt;Don't call us, we'll call you&lt;/h3&gt;

&lt;p&gt;Working with asynchronous code in EventMachine usually involves callbacks, unless you work with your own connection
class. Libraries like &lt;a href=&quot;https://github.com/igrigorik/em-http-request&quot;&gt;&lt;code&gt;em-http-request&lt;/code&gt;&lt;/a&gt; rely on deferrables to
communicate with your application. They're fired when a HTTP request finished or failed. But how does a library keep
track of data that only comes in bit by bit?&lt;/p&gt;

&lt;p&gt;The answer is simply buffering. Which brings us to the core of the event loop, checking sockets for input, which is done
from the ominous &lt;code&gt;_RunOnce()&lt;/code&gt; method in the code snippet above. EventMachine can utilize three mechanisms to check
descriptors for new input.&lt;/p&gt;

&lt;h3&gt;select(*)&lt;/h3&gt;

&lt;p&gt;The default is using &lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/select.2.html&quot;&gt;&lt;code&gt;select()&lt;/code&gt;&lt;/a&gt;, a standard
system call to check a collection of file descriptors for input, by way of Ruby's implementation &lt;code&gt;rb_thread_select()&lt;/code&gt;,
which wraps the call to &lt;code&gt;select()&lt;/code&gt; with a bunch of code ensuring thread safety.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;select()&lt;/code&gt; pretty much works everywhere, and is perfectly fine up to a certain number of file descriptors. If
you're simply serving an asynchronous web application or API using EventMachine, this may be totally acceptable.&lt;/p&gt;

&lt;p&gt;Implementing this way of handling I/O is rather straight-forward, if you look at the
&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/master/ext/em.cpp#L823-957&quot;&gt;implementation&lt;/a&gt;. Collect all file
descriptors that may be of interest, feed them into select, read and/or write data when possible.&lt;/p&gt;

&lt;p&gt;What makes using &lt;code&gt;select()&lt;/code&gt; a bit cumbersome is that you always have to assemble a list of all file descriptors for
every call to &lt;code&gt;_RunOnce()&lt;/code&gt;, so EventMachine iterates over all registered descriptors with every loop. After select ran,
it loops over all file descriptors again, checking to see if &lt;code&gt;select&lt;/code&gt; marked them as ready for reads and/or writes.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;select()&lt;/code&gt; marks a descriptor as ready for read or write operations that means the socket will not block when data
is read from or written to it. In the case of reading that usually means the operating system has some data buffered
somewhere, and it's safe to read that data without having to wait for it to arrive, which in turn would block the call.&lt;/p&gt;

&lt;p&gt;Instead of using &lt;code&gt;select()&lt;/code&gt;, EventMachine could also use
&lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/poll.2.html&quot;&gt;&lt;code&gt;poll()&lt;/code&gt;&lt;/a&gt; instead, which just handles a bit nicer in
general, but is not available in the Ruby VM. &lt;/p&gt;

&lt;h3&gt;epoll&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/eventmachine/eventmachine/blob/master/docs/EPOLL&quot;&gt;epoll&lt;/a&gt; is Linux' implementation for multiplexing
I/O across a large number of file descriptors.&lt;/p&gt;

&lt;p&gt;The basic steps of using epoll are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up an epoll instance using
&lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/epoll_create.2.html&quot;&gt;&lt;code&gt;epoll_create&lt;/code&gt;&lt;/a&gt;, done initially when the
event loop is created. This creates a virtual file descriptor pointing to a data structure that keeps track of all
real file descriptors associated with it in the next step.&lt;/p&gt;

&lt;p&gt;You only need to reference this single file descriptor later, so there's no need to collect a list of all file
descriptors, as is the case when &lt;code&gt;select()&lt;/code&gt; is used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Register interest for events on a file descriptor using
&lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/epoll_ctl.2.html&quot;&gt;&lt;code&gt;epoll_ctl&lt;/code&gt;&lt;/a&gt; on the epoll instance created
above.&lt;/p&gt;

&lt;p&gt;This is used in &lt;code&gt;_AddNewDescriptors&lt;/code&gt; and &lt;code&gt;_ModifyDescriptors&lt;/code&gt; to register and update EventMachine's file descriptors
with epoll. In fact, both methods only do anything noteworthy when epoll is used. Otherwise they just iterate over a
list of descriptors, pretty much doing nothing with them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait for input with &lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/epoll_wait.2.html&quot;&gt;&lt;code&gt;epoll_wait&lt;/code&gt;&lt;/a&gt; for a
specified duration. You can wait forever, return immediately if nothing happened, or wait for a specific amount of
time.&lt;/p&gt;

&lt;p&gt;EventMachine seems to have chosen to return immediately if there's no activity. There's an alternative implementation
calculating the time to wait based on the likelihood of a specific event (e.g a timer firing) to fire on the next
event loop iteration, but it doesn't seem to ever be used. Seems to be a relict from the time it could also be used as
a C++ library.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;epoll events are registered for both reads and writes, with &lt;code&gt;epoll_wait&lt;/code&gt; returning the number of file descriptors that
are ready for both events.&lt;/p&gt;

&lt;p&gt;Using epoll has a big advantage, aside from being much more efficient than select in general for larger sets of file
descriptors. It spares code using it the burden of constantly iterating over a list of file descriptors. Instead you
just register them once, and then only iterate over the ones affected by the last call to &lt;code&gt;epoll_wait&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So epoll requires a bit more work when you add or modify connections, but is a bit nicer on the eyes when it comes to
actually polling them for I/O availability.&lt;/p&gt;

&lt;p&gt;Note that epoll support must be explicitly enabled using &lt;code&gt;EM.epoll&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;kqueue&lt;/h3&gt;

&lt;p&gt;kqueue is the BSD equivalent of epoll, and is available on e.g. FreeBSD and Mac OS X. It works very similar to epoll. If
you want to know more details, I'd suggest &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.79.3925&amp;rep=rep1&amp;type=pdf&quot;&gt;reading the paper on it by Jonathan
Lemon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can enable kqueue support using &lt;code&gt;EM.kqueue&lt;/code&gt;, which is, just like &lt;code&gt;EM.epoll&lt;/code&gt;, a noop on systems that don't support
it. Hopefully future EM versions will use whatever's available on a particular system as default.&lt;/p&gt;

&lt;h3&gt;Call me already!&lt;/h3&gt;

&lt;p&gt;All three mechanisms used have one thing in common: when data is read, &lt;code&gt;receive_data&lt;/code&gt; is called immediately, which
brings us back to the question of how a connection objects collects data coming in.&lt;/p&gt;

&lt;p&gt;Whenever data is ready to be consumed from a socket, EventMachine calls &lt;code&gt;EventDescriptor::Read()&lt;/code&gt;, which reads a bunch
of data from the socket, in turn calling &lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/read.2.html&quot;&gt;&lt;code&gt;read()&lt;/code&gt;&lt;/a&gt;
on the file descriptor, and then immediately executes the callback associated with the descriptor, which usually ends up
calling &lt;code&gt;receive_data&lt;/code&gt; with the data that was just read. Note that the callback here refers to something defined on the
C++ level, not yet a Ruby block you'd normally use in an asynchronous programming model.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;receive_data&lt;/code&gt; is where you will usually either buffer data or run some action immediately. em-http-request feeds the
data coming in directly into an HTTP parser. Whatever you do in here, make it quick, don't process the data for too
long. A common pattern in libraries built on EventMachine is to use a &lt;code&gt;Deferrable&lt;/code&gt; object to keep track of a request's
state, firing callbacks when it either succeeded or failed.&lt;/p&gt;

&lt;p&gt;Which brings me to the golden rule of programming with libraries like EventMachine and Node.js: DON'T BLOCK THE EVENT
LOOP!! Defer whatever work you can to a later run of the loop when it makes sense, or push it to another asynchronous
processing facility, e.g. a message queue like RabbitMQ or Redis' Pub/Sub.&lt;/p&gt;

&lt;p&gt;In a similar fashion, whenever you write data to a connection using &lt;code&gt;send_data&lt;/code&gt;, it's first buffered, and not actually
sent until the socket is ready for a non-blocking call to
&lt;a href=&quot;http://www.kernel.org/doc/man-pages/online/pages/man2/write.2.html&quot;&gt;&lt;code&gt;write()&lt;/code&gt;&lt;/a&gt;. Hence all three implementations check
for both read and write availability of a descriptor.&lt;/p&gt;

&lt;h3&gt;Fibers vs. Spaghetti&lt;/h3&gt;

&lt;p&gt;Where do Ruby's Fibers come in here? Callbacks can easily lead to spaghetti code, especially when you have to nest them
to run multiple asynchronous actions in succession.&lt;/p&gt;

&lt;p&gt;Fibers can stop execution of a process flow at any time and yield control to some other, controlling entity or another
Fiber. You could, for example, wrap a single HTTP request into a fiber and yield back control when all the callbacks
have been assigned.&lt;/p&gt;

&lt;p&gt;In the callbacks you then resume the Fiber again, so that processing flow turns into a synchronous, procedural style
again.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  def get(url)
    Fiber.new do
      current_fiber = Fiber.current
      request = EM::HttpRequest.new(url).get
      request.callback { current_fiber.resume(request) }
      request.errback  { current_fiber.resume(request) }
      Fiber.yield
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Fiber.yield&lt;/code&gt; returns whatever object it was handed in &lt;code&gt;Fiber.resume&lt;/code&gt;. Wrap this in a method and boom, there's your
synchronous workflow. Now all you need to do is call &lt;code&gt;get('http://paperplanes.de')&lt;/code&gt; and assign something with the return
value. Many props to &lt;a href=&quot;http://rubysource.com/understanding-concurrent-programming-with-ruby-goliath/&quot;&gt;Xavier Shay for digging into the Goliath
source&lt;/a&gt; to find out how that stuff works.
Helped me a lot to understand how that stuff works.  If you never had a proper use case for Fibers in real life, you do
now.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/igrigorik/em-synchrony&quot;&gt;&lt;code&gt;em-synchrony&lt;/code&gt;&lt;/a&gt; is a library doing just that for a lot of existing EventMachine libraries, and
&lt;a href=&quot;http://goliath.io&quot;&gt;Goliath&lt;/a&gt; is an evented web server, wrapping a Rack-style API using Fibers.&lt;/p&gt;

&lt;h3&gt;Things you should be reading&lt;/h3&gt;

&lt;p&gt;Here's a bunch of free reading tips for ya. These books are pretty old, but have gone through some revisions and
updates, and they're still the classics when it comes to lower level Unix (network) programming and understanding
TCP/IP, which I consider very important. TCP/IP Illustrated is one of the best books I've read so far, and I consider it
essential knowledge to be aware of what happens under the networking hood.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0201633469/ref=as_li_tf_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399353&amp;creativeASIN=0201633469&quot;&gt;TCP/IP Illustrated Vol.  1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0131411551/ref=as_li_tf_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399353&amp;creativeASIN=0131411551&quot;&gt;Unix Network Programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.amazon.com/gp/product/0321525949/ref=as_li_tf_tl?ie=UTF8&amp;tag=javaddicts-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399353&amp;creativeASIN=0321525949&quot;&gt;Advanced Programming in the Unix
Environment&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, read the fine man pages. There's a whole bunch of good documentation installed on every Unix-style system, and I
linked to a couple of them relevant to this post already. Read it.&lt;/p&gt;

&lt;h3&gt;yield&lt;/h3&gt;

&lt;p&gt;This concludes today's whirlwind tour through some of EventMachine's internals. There's actually not too much magic
happening under the covers, it's just wrapped into a bit too much code layering for my taste. But you be the judge.&lt;/p&gt;

&lt;p&gt;Play with EventMachine and/or Node.js if you haven't already, try to wrap your head around the asynchronous programming
model. But for the love of scaling, don't look at evented and asynchronous I/O as the sole means of scaling, because
it's not.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/Paperplanes/~4/oZJq_ARv7Jc&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>paperplanes</name>
			<uri>http://www.paperplanes.de</uri>
		</author>
		<source>
			<title type="html">paperplanes</title>
			<subtitle type="html">software development that flies</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/Paperplanes"/>
			<id>http://feeds.feedburner.com/Paperplanes</id>
			<updated>2012-01-30T14:40:28+00:00</updated>
			<rights type="html">Copyright 2007-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Well, well, hasn't it been quiet in here</title>
		<link href="http://feedproxy.google.com/~r/jankrutisch/rss/~3/4HBjeJDATJk/"/>
		<id>http://jan.krutisch.de/en/2011/04/20/well-well-hasnt-it-been-quiet.html/</id>
		<updated>2011-04-19T22:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Well, yes it has. I still feel like my whole life still didn&amp;#8217;t settle enough for me thinking thoughts deep enough so that I could blog about them. And then, I&amp;#8217;ve obviously been bitten by the pesky twitter bug, resulting in writing invariantly more, but in 140 character chunks.&lt;/p&gt;
&lt;p&gt;So, whassup? &lt;a href=&quot;http://awesome-fontstacks.com&quot;&gt;Awesome Fontstacks&lt;/a&gt; is still going relatively strong, although it is extremely hard to find the necessary time to bring the idea forward. Well, there&amp;#8217;s still more than half a year left before to come up with an idea on how to pay the server bills :)&lt;/p&gt;
&lt;p&gt;On a similar note, we&amp;#8217;ve developed an idea we currently call &amp;#8220;Awesome Ideas Inc.&amp;#8221;, which right now consists of a &lt;a href=&quot;http://twitter.com/wowo101&quot;&gt;small&lt;/a&gt; &lt;a href=&quot;http://twitter.com/theflow&quot;&gt;group&lt;/a&gt; &lt;a href=&quot;http://twitter.com/enebo&quot;&gt;of&lt;/a&gt; &lt;a href=&quot;http://twitter.com/menotti&quot;&gt;awesome&lt;/a&gt; &lt;a href=&quot;http://twitter.com/schurock&quot;&gt;people&lt;/a&gt; &lt;a href=&quot;http://twitter.com/electricgecko&quot;&gt;committed&lt;/a&gt; to bring one small project to life in each quarter, every time in a rails rumble like fashion. We just (this weekend) finished our first project, which we launched in what I would call silent beta. If you&amp;#8217;re interested in checking out a project in a very rough and unfinished state, hit one of us up on the twitters for a link.&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;span id=&quot;more&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The weekend was an interesting experience, because it was the first time we actually tried to force ourselves to work in a rumble like setup with no actual contest going on. Also, we had some organisational issues with people not finding the time to contribute, our lead frontend guy catching the lurgy the week before and also working in a considerably less technically oriented field than the last two times. Nevertheless, &lt;a href=&quot;http://electricgecko.de/&quot;&gt;Malte&lt;/a&gt; with whom we never worked before (but only heard great things about before, of course), not only delivered a great design and visual concept, but also fit the team perfectly. Huge thanks, and massive thumbs up! Also, he contacted his berlin friend &lt;a href=&quot;http://www.kristinaschneider.com/&quot;&gt;Kristina Schneider&lt;/a&gt; who, on very short notice, delivered awesome illustrations.&lt;/p&gt;
&lt;p&gt;The father of the application idea, &lt;a href=&quot;http://twitter.com/schurock&quot;&gt;Tim Schurig&lt;/a&gt;, a long friend of our mindmatters Social Media Expert (just kidding, mate) &lt;a href=&quot;http://floriansiepert.com&quot;&gt;Florian Siepert&lt;/a&gt;, also was great because he not only provided a great idea (ideas alone may be worthless, but that doesn&amp;#8217;t mean that you don&amp;#8217;t need to come up with them) but also was happily bouncing back and forth with all of us on the concept. He spent most of the weekend together with the equally awesome &lt;a href=&quot;http://twitter.com/menotti&quot;&gt;Klaus-Peter Frahm&lt;/a&gt;, preparing scribbles, writing copy and finding an endless stream of project matching puns.&lt;/p&gt;
&lt;p&gt;So, on the concept on design side, things went smoothly, but in retrospect, they also went way to slow, or, more aptly put, way to late. For us in the development corner (Always a pleasure to work with: Podio&amp;#8217;s very own &lt;a href=&quot;http://twitter.com/theflow&quot;&gt;Florian Munz&lt;/a&gt; and mindmatters co-founder and slightly lurgy ridden, but still awesomely awesome &lt;a href=&quot;http://twitter.com/wowo101&quot;&gt;Wolfgang Wopperer&lt;/a&gt;), this weekend was by far the hardest challenge and we almost completely failed. We were reluctant to start at all, because the concept was, at least for the first hours, still very much in flux, and then we started at the wrong edge, prototyping advanced input controls in javascript. What we should have done, in retrospect, is to start as you would do in any sensible project context: Implementing the core workflow (which is complicated enough, as we found out later, maybe too late) without bells and whistles and then iterate from there. So, we pretty much jammed ourselves for the first 8-12 hours in the project. Of course it was Florian who finally got the message and spent the rest of the time implementing the workflow while I was still drenched in jQuery UI slime. I am still amazed that we managed to actually complete the workflow (only the golden path, I&amp;#8217;m afraid, but still&amp;#8230;).&lt;/p&gt;
&lt;p&gt;What do we take away from it? For me personally it was a wake up call to stick to the process I know that works, namely, sketching out a rough workflow with the simplest techniques possible and then, when the conceptional and design dust settles, iterate on UI/UX from there. Apart from that, I am convinced that we have found an amazing model to work with. What makes this concept great is not only the quick turnaround, enabling us to verify ideas with very little overhead, but also the people, which are all absolutely top notch at what they do, but are also astonishingly low on ego trippin&amp;#8217;, which is crucial for such an endeavour &amp;#8211; The last thing you want on such a weekend long sprint is two people fighting some ego fight on conflicting ideas.&lt;/p&gt;
&lt;p&gt;Rock. On. We&amp;#8217;ll keep you posted. For now, it might be a good idea to follow &lt;a href=&quot;http://twitter.com/awesomeideasinc&quot;&gt;@awesomeideasinc&lt;/a&gt; on twitter.&lt;/p&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/jankrutisch/rss/~4/4HBjeJDATJk&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>jan.krutisch.de</name>
			<uri>http://jan.krutisch.de</uri>
		</author>
		<source>
			<title type="html">jan.krutisch.de</title>
			<subtitle type="html">An ongoing conversation between Jan Krutisch and the Interwebs on nothing in particular.</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/jankrutisch/rss/"/>
			<id>http://feeds.feedburner.com/jankrutisch/rss/</id>
			<updated>2012-01-15T22:20:31+00:00</updated>
			<rights type="html">Copyright 2004-2009</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">IBAN Validation and Ruby 1.9</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/T2aYl1bCJGM/"/>
		<id>http://blog.railslove.com/?p=934</id>
		<updated>2011-04-15T13:52:30+00:00</updated>
		<content type="html">&lt;p&gt;In one of our projects &lt;a href=&quot;http://9flats.com&quot;&gt;9flats.com&lt;/a&gt; we&amp;#8217;re using a short IBAN and SWIFT Validation rule to be sure the user entered valid bank account information.&lt;br /&gt;
To know how to validate an IBAN account number, just have a look at &lt;a href=&quot;http://en.wikipedia.org/wiki/IBAN#Calculating_and_Validating_IBAN_checksums&quot;&gt;this article on wikipedia&lt;/a&gt;. Therefore you have to do a few steps to be sure get the right format of an IBAN number:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;
&lt;strong&gt;Validating the IBAN&lt;/strong&gt;&lt;br /&gt;
The basis of the IBAN validation is to convert the IBAN into a number and to perform a basic Mod-97 calculation (as described in ISO 7064) on it. If the IBAN is valid, then the remainder equals 1. Rule process of IBAN validation is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid.&lt;/li&gt;
&lt;li&gt;Move the four initial characters to the end of the string.&lt;/li&gt;
&lt;li&gt;Replace each letter in the string with two digits, thereby expanding the string, where A=10, B=11, &amp;#8230;, Z=35.&lt;/li&gt;
&lt;li&gt;Interpret the string as a decimal integer and compute the remainder of that number on division by 97.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the remainder is 1, the checks digits test is passed and the IBAN may be valid.
&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I found a &lt;a href=&quot;http://www.locknet.ro/article/iban-validation-and-beast&quot;&gt;short (and also funny) blogpost&lt;/a&gt; about a validation script in ruby. Unfortunely the expression&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
iban = value.gsub(/[A-Z]/) { | p | p[0]-55 }&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
does&amp;#8217;n work anymore, because Ruby 1.9 doesn&amp;#8217;t return the integer ordinal of a one-character string using p[0]. Instead of that just use the .ord method on a string. So our Ruby 1.9 compatible code will looks like this:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
iban = value.gsub(/[A-Z]/) { | p | p.ord-55 }&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
If you&amp;#8217;re using two or more environments (e.g.: Ruby 1.8 and Ruby 1.9) on your production or development machine (I know thats not the way to go, but it could happen for a little time) just ask if Ruby respond to the .ord method.&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
iban = value.gsub(/[A-Z]/) { |p| (p.respond_to?(:ord) ? p.ord : p[0]) - 55 }&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The final code from the blogpost mentioned before will be looks like this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Small things can be very helpful!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=T2aYl1bCJGM:ydcDcc65SXg:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=T2aYl1bCJGM:ydcDcc65SXg:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=T2aYl1bCJGM:ydcDcc65SXg:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=T2aYl1bCJGM:ydcDcc65SXg:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="de-de">
		<title type="html">Using Cucumber Step Argument Transforms</title>
		<link href="http://feedproxy.google.com/~r/dopefreshtightblog/~3/C_Ayd4iyr2A/using-cucumber-step-argument-transforms"/>
		<id>http://dennisreimann.de/blog/using-cucumber-step-argument-transforms</id>
		<updated>2011-03-24T09:25:00+00:00</updated>
		<content type="html">&lt;p&gt;In a recent project that is tested with Cucumber we were using „within“ steps with CSS selectors.
                              Though &lt;a href=&quot;http://mislav.uniqpath.com/2010/09/cuking-it-right/&quot;&gt;this isn’t basically considered a good idea&lt;/a&gt;
                              I’d say it made sense for us, because we had to select specific parts of the page. Cuking it like that, our steps
                              usually looked something like this:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;Scenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Edit something&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;  Given &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;there is something&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;another something&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;When &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I go to the page of somethings&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I follow &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;edit&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; within &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;ul.somethings li:nth-child(1)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;Then &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I should be on the edit page for &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;something&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
                              
                              
                              &lt;p&gt;Besides looking just ugly, CSS selectors also don’t offer any business value and are likely to change. Cucumber’s
                              &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms&quot;&gt;Step Argument Transforms&lt;/a&gt; can help you
                              avoid that by refactoring common operations.&lt;/p&gt;
                              
                              &lt;p&gt;Transforms are defined with the &lt;code&gt;Transform&lt;/code&gt; keyword and can be a part of your step definition files. Cucumber matches
                              the captures in your steps (i.e. &lt;code&gt;the 1st something&lt;/code&gt;) against the defined transforms. If the regexp matches, it yields
                              the transformed value as an argument to the step definition block. This sounds complicated, so here’s an example:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;Transform /^the (\d+)(?:st|nd|rd|th) something$/ do&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                              &lt;span class=&quot;s&quot;&gt;  &quot;ul.somethings li:nth-child(&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#{num})&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                              &lt;span class=&quot;s&quot;&gt;end&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
                              
                              
                              &lt;p&gt;This transform allows us to refactor the scenario above to be more readable and maintainable:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;Scenario:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt; Edit something&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  …&lt;/span&gt;
                              &lt;span class=&quot;k&quot;&gt;  When &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I go to the page of somethings&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;And &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;I follow &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;edit&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot; within &quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;the 1st something&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;&quot;&lt;/span&gt;
                              &lt;span class=&quot;nf&quot;&gt;  …&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
                              
                              
                              &lt;p&gt;We can even abstract this a little further and make it usable on a common level:&lt;/p&gt;
                              
                              &lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;Transform /^the (\d+)(?:st|nd|rd|th) (.+)$/ do&lt;/span&gt;&lt;span class=&quot;k&quot;&gt; |&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;num, type&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                              &lt;span class=&quot;s&quot;&gt;  &quot;ul.&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;#{type.pluralize} li:nth-child(#{num})&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&lt;/span&gt;
                              &lt;span class=&quot;s&quot;&gt;end&lt;/span&gt;
                              &lt;/pre&gt;
                              &lt;/div&gt;
                              
                              
                              &lt;p&gt;This is just a basic example of how this often unknown Cucumber feature might help you to refactor your step definitions.
                              For more information and decent examples check out the wiki page on &lt;a href=&quot;https://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms&quot;&gt;Step Argument Transforms&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Dennis Reimann</name>
			<email>mail@dennisreimann.de</email>
			<uri>http://dennisreimann.de</uri>
		</author>
		<source>
			<title type="html">//dennisreimann</title>
			<subtitle type="html">Arbeit und Alltag eines Software-Entwicklers aus Bremen</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/dopefreshtightblog/"/>
			<id>http://dennisreimann.de/</id>
			<updated>2012-02-02T20:00:09+00:00</updated>
			<rights type="html">©</rights>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">DevHouse Friday – 25.03.2011 hosted by adcloud</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/GYuId9RXcNE/"/>
		<id>http://blog.railslove.com/?p=924</id>
		<updated>2011-03-18T22:27:14+00:00</updated>
		<content type="html">&lt;p&gt;&lt;a href=&quot;http://blog.railslove.com/wp-content/uploads/2011/03/DevHouse-Friday-Logo.jpeg&quot;&gt;&lt;img src=&quot;http://blog.railslove.com/wp-content/uploads/2011/03/DevHouse-Friday-Logo.jpeg&quot; alt=&quot;&quot; title=&quot;DevHouse Friday Logo&quot; width=&quot;126&quot; height=&quot;126&quot; class=&quot;alignnone size-full wp-image-925&quot; /&gt;&lt;/a&gt;Es ist wieder einmal Zeit für ein lockeres Come-Together von Web-Entwicklern und Tekki’s &lt;a href=&quot;http://www.youtube.com/watch?v=HR1myxRyrHc&quot;&gt;(endlich normale Leute)&lt;/a&gt;. Mit einem Drink und zwei-drei kurzen Talks leuten wir das Wochenende ein und vergessen den Coding-Stress.&lt;/p&gt;
&lt;p&gt;Vielen Dank an &lt;a href=&quot;https://adcloud.net/&quot;&gt;adcloud&lt;/a&gt;, welche den Event in Ihrer neuen Location im hippen Ehrenfeld ausrichten.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WANN:&lt;/strong&gt; 25.03.2011 ab: 19:00 Uhr&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WO:&lt;/strong&gt; &lt;a href=&quot;http://maps.google.de/maps?f=q&amp;source=s_q&amp;hl=de&amp;geocode=&amp;q=Venloer+Stra%C3%9Fe+25,+K%C3%B6ln&amp;aq=0&amp;sll=50.93873,6.939025&amp;sspn=0.011061,0.027874&amp;ie=UTF8&amp;hq=&amp;hnear=Venloer+Stra%C3%9Fe+25,+K%C3%B6ln+50672+K%C3%B6ln,+Nordrhein-Westfalen&amp;ll=50.941727,6.936341&amp;spn=0.000691,0.001742&amp;t=h&amp;z=20&quot;&gt;adcloud GmbH, Venloerstr. 25-27, 50672 Köln&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WAS:&lt;/strong&gt; Bring your brain and a beer&lt;/p&gt;
&lt;p&gt;MORE: &lt;a href=&quot;http://devhousefriday.org/&quot;&gt;http://devhousefriday.org/&lt;/a&gt; AND &lt;a href=&quot;http://twitter.com/devhousefriday&quot;&gt;@devhousefriday&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Das adcloud-Team ist übrigens noch auf der Suche nach &lt;a href=&quot;http://adcloud.de/jobs/&quot;&gt;Talenten&lt;/a&gt; (&lt;a href=&quot;http://railslove.com/jobs&quot;&gt;übrigens wir auch&lt;/a&gt;), was ich jedem empfehlen kann der am Puls der Zeit arbeiten möchte.&lt;/p&gt;
&lt;p&gt;Entwickler aller Sprachen vereinigt euch!&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=GYuId9RXcNE:925ACm_miG0:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=GYuId9RXcNE:925ACm_miG0:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=GYuId9RXcNE:925ACm_miG0:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=GYuId9RXcNE:925ACm_miG0:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Ruby &amp;amp; Rails UG meetup: 24 Mar @ CoWoCo</title>
		<link href="http://feedproxy.google.com/~r/railslabs/~3/JPWKLF1VBVk/"/>
		<id>http://blog.railslove.com/?p=914</id>
		<updated>2011-03-17T22:58:36+00:00</updated>
		<content type="html">&lt;p&gt;We&amp;#8217;re very excited to announce the second meetup of the revived Cologne Ruby &amp;amp; Rails User Group &lt;a href=&quot;http://www.rurug.de&quot;&gt;RuRUG&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://rurug.de&quot;&gt;&lt;img class=&quot;aligncenter size-full wp-image-916&quot; title=&quot;rurug_image&quot; src=&quot;http://f.cl.ly/items/3g2q0p3U3Z2z20043m47/RuRUG.png&quot; alt=&quot;RuRUG&quot; width=&quot;500&quot; height=&quot;296&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To take part in the awesomeness that is meeting your local gang of fellow Ruby &amp;amp; Rails aficionados, pop by &lt;a href=&quot;http://www.coworkingcologne.de&quot;&gt;Coworking Cologne&lt;/a&gt; on &lt;strong&gt;Thursday, 24 March at 20:00&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The schedule so far consists of a &lt;em&gt;JRuby on Rails&lt;/em&gt; talk by Jan Lühr. More slots are still up for grabs &amp;#8211; feel free to suggest your own talk, or boldly give an impromptu presentation of anything you&amp;#8217;re interested in. After the presentations, there&amp;#8217;ll be plenty of time to meet new people, do some collaborative hacking and have a couple of beers =)&lt;/p&gt;
&lt;p&gt;Hope to see you there!&lt;/p&gt;
&lt;p&gt;For directions and further information, make sure to check out &lt;em&gt;RuRUG&amp;#8217;s&lt;/em&gt; &lt;a href=&quot;http://rurug.de&quot;&gt;website&lt;/a&gt;, &lt;a href=&quot;http://ml01.ispgateway.de/mailman/listinfo/liste_rurug.de&quot;&gt;mailing list&lt;/a&gt;, and &lt;a href=&quot;http://www.facebook.com/pages/RuRUG/186981551346705&quot;&gt;facebook page&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JPWKLF1VBVk:2B8ULYXwuqc:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JPWKLF1VBVk:2B8ULYXwuqc:7Q72WNTAKBA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?d=7Q72WNTAKBA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/railslabs?a=JPWKLF1VBVk:2B8ULYXwuqc:V_sGLiPBpWU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/railslabs?i=JPWKLF1VBVk:2B8ULYXwuqc:V_sGLiPBpWU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;</content>
		<author>
			<name>Railslove</name>
			<uri>http://blog.railslove.com</uri>
		</author>
		<source>
			<title type="html">Railslove</title>
			<subtitle type="html">we love building web applications</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/railslabs"/>
			<id>tag:railslabs.com,2007:mephisto/</id>
			<updated>2012-01-31T10:00:06+00:00</updated>
		</source>
	</entry>

</feed>

