Parallel "mv" with Google Go

The first question, that might come into you mind, could be "why the heck should I do a parallel "mv""? The answer is quite easy: Imagine you have a bunch of folders that you unpack and move to a specific location -  your http document root. Those folders are dependend on each other, using php files via include or require, etc. You need to move them consitently as "the new release" to their destination. You might ask, why the normal linux "mv" is not enough, even when combining the call with "&&"? Imagine that the webserver has a normal traffic of over 1000 page impressions per second. How big is the timeframe you have for moving the folders without having an inconsistent state? The answer is heavy to guess or to calculate. With a transfer time of ~1 msec you hit the 1% rate of getting a request for a page with an inconsistent state. The more you get under the 1 msec mark, the better it is.

The parallel version, which uses Goroutines - a threading model that is even more lightweight than posix threads - does a move of two folders in ~0.019 msec. This reduces the chance of failure under 1%, even under 0.2%.

As we use it for our release process, the folders are compiled in the binary. This is not very flexible, but prevents typos or human failure while using it.

As posterous does not like my embedded code, please find it here 

A few reasons why we do not need meta languages...

Just for the trolls: This is no bashing of the articles about less, sass, haml, coffeescript, etc. Especially the one I've read on Mayflower's blog is very true.

But! 

A language that doesn't change the way you think about programming is not worth learning.— Alan Perlis

And I think Alan is right. None of the languages mentioned above changes the way you think about the language it "generates". The only thing you change, is the way you write stuff in shorter, maybe more oop-ish or whatever style. But does it change the way we think about HTML & CSS? As long as people still addicted to table layouts, we might have more important problems than just writing less code, don't we?

I did not met any - pure - HTML/CSS guy/gal yet, who ever said, that haml, sass or less did the right job for him/her. Only the PHP and Ruby guys and gals who are forced to write stylesheets love this style of writing. And by the way: As we generate HTML strings with PHP, why don't we use the same cool technology to generate CSS in a proper way? We (the PHP world) have invented a thousand ways to abstract and instrument the generation of websites (which means HTML - just wanted to mention it ;) ), that we need another two or three ways to generate some other text (CSS, JavaScript, ...)? 

Let me take something from "the zen of python" for a quote:

There should be one-- and preferably only one --obvious way to do it.

For me, the obivous way to do it is "use the weapons at hand", use your well known language (PHP, Ruby, Python ... whatever it might be).

Just for my information: Is there anyone out there who does HTML/CSS only (no PHP, no RoR or whatever) and uses haml, sass and/or less?

Dependency Injection mit in PHP mit Any\Di/

Tim Glabisch und ich durften auf gestrigen PHPUG D/DU/KR Veranstaltung einen Vortrag zum Thema Dependency Injection halten. Tim und ich haben uns die Präsentation aufgeteilt, der Eine hat ein wenig über das Pattern und den Architektur Ansatz gesprochen, der Andere hat einen DI-Container vorgestellt.

Tim war so nett seinen eigenen DIC vorzustellen: "Any\Di". Any\Di erinnert, für die Leute, die sich auch mal mit Java beschäftigen, an Google Guice - auch wenn es kein direkter Port von Guice ist.

Die Benutzung von Any\Di ist recht einfach (worin meiner Meinung nach auch gleichzeitig die größte Macht steckt). Die Beispiele sind von den Tutorial Seiten von Tim "ausgeliehen" ;).

Man hat einer Seits die Möglichkeit seine Dependencies programmatisch zu deklarieren. Any\Di nennt das "bind":

di();
$di->bind('\de\any\di\test\example\basics\iLogger')
->to('\de\any\di\test\example\basics\Logger');

Wir binden also ein Interface an eine konkrete Implementierung. Über ein  $di->get('\de\any\di\test\example\basics\iLogger'); Komme ich nun auch wieder an die dem Interface folgende Instanz heran. Ich kann nur empfehlen es sich mal anzuschauen, Tim freut sich auf Feedback!

Hier sind noch die Prezi Slides von gestern:

Trouble um MongoDB

Was ist nur los im Social Web? MongoDB wurde rüde von einem Unbekannten attakiert, der CTO von 10gen antwortet über ycombinator. Im Verlauf der Kommentare meldet sich dann auch der der angeblich ursprüngliche Autor zu Wort und konstatiert, dass es sich um einen Hoax handelt. 

Verwirrt? Ich auch. Liest man allerdings brav weiter, dann erfährt man, dass es sich um zwei Autoren handelt. nmongo und nomoremongo. Der Eine ist ein Troll Internetnutzer mit Frustrationshintergrund, der Andere der tatsächliche Autor des Pastbin-Textes. Auf Grund der Anonymität sind etliche Kommentarautoren skeptisch, was die Verwertbarkeit und den Wahrheitsgehalt der Aussagen angeht. Er verspricht jedoch die Veröffentlichung seines Names nach der Auflösung der Verträge mit 10gen.

Hat MongoDB wirklich diese Art von grundsätzlichen Problemen, dann haben die New York Times, GitHub, Sourceforge, Foursquare und BusinessInsider sie auch. Alle genannten Firmen setzen nach eigener Aussage auf MongoDB - wo ich entsprechende Slides gefunden habe sind diese verlinkt. 

Es bleibt spannend.

Zarafa, z-push und iOS5

Meine Migration von meinem Hosted-Exchange zu Zarafa ist nun endlich komplett. Leider gab es da noch ein Problem mit z-push - einer in PHP geschriebenen ActiveSync Implementierung - und meinem iPhone mit iOS 5. Tante Google spuckt dazu einen Forenthread aus, der ein Downgrade auf die Version 1.4.3 empfiehlt sowie einige Modifikationen an den Sourcen. Ich habe das mal ausprobiert und kann sagen ... ja, es läuft, aber! Bei mir gingen leider die Umlaute nicht mehr. Zarafa's Webaccess zeigt mir Diese wunderbar an, das iPhone wandelt ü,ö,ä und ß leider in "?" um. Scheiß Encoding. Die Version 1.5.5, also die aktuelle Stable, lief zuerst garnicht. 

Die Lösung ist einfacher als gedacht. Ich hatte zuerst keine SSL Verschlüsselung für den ActiveSync Endpoint eingerichtet, da ich das Setup nur testen wollte. Leider hielt genau dies die Version 1.5.5 davon ab ihren Dienst zu tun. Mit einem Snake-Oil Zertifikat läuft die Version 1.5.5 auch mit iOS5 einwandfrei. Alle mit der Version 1.4.3 beschriebenen Probleme (Sync der Mails kann nicht mehr als eine Woche zurück vollzogen werden, gelöschte Mail werden nicht wirklich gelöscht, Push oder CalDav laufen nicht korrekt) kann ich mit dieser Version nicht nachvollziehen. Ebenso das Umlautproblem hat sich erledigt.

Sehr geehrte Headhunter, liebe Personalvermittler

aus aktuellem Anlass und in der Hoffnung, dass ihr - neben meinem Xing Profil - auch meinen Blog lest, schreibe ich euch diese Zeilen. Ich habe zum Anfang September den Job gewechselt, das habt ihr sicherlich bemerkt. Ich gehe zwar nicht davon aus, dass ihr es in eure "sprech ich ihn jetzt an?"-Überlegung einbezieht, aber ich wollte in meiner grenzenlosen Naivität trotzdem mal darauf aufmerksam machen. Ich frage mich manches Mal ernsthaft, ob ihr nicht lieber hättet weiter euren gelernten Beruf weiter ausüben sollen. Vielleicht wart ihr ja gut darin? Und selbst wenn ihr diesen Beruf gelernt habt, scheinen die Meisten doch wo anders besser aufgehoben. Die Ignoranz, mit der ihr jedoch über mich und mein öffentliches Profil herfallt, kennt leider kaum eine Grenze. Warum hat euch keiner beigebracht Profile auch mal zu interpretieren, nicht nur zu lesen? Selbst Google reagiert besser auf Keywords als ihr! Nur weil ich "XYZ" in meinem Profil stehen habe, seht ihr die Chance mich zum Experten zu erheben und in euer Suchprofil zu pressen? Ich bin gerade von einer Agentur zu einem völlig anders strukturierten Unternehmen gewechselt. Habt ihr mal nachgedacht, ob das vielleicht ... Absicht war? Würde ich in eine Agentur wollen, hätte ich nicht dann auch eine Agentur gewählt? Meint ihr ernsthaft, ich wechsle nach nicht mal zwei Monaten direkt wieder den Job? Kennt ihr das Wort "Treue" oder auch "Nachhaltigkeit"? Wäre es euch nicht genauso wichtig, dass ein Mitarbeiter in dem Unternehmen bleibt, an den ihr in vermittelt? Nunja, die Erwartungshaltung, dass Psychologie oder auch nur grundsätzliches analytisches Verhalten in eure Arbeit mit einfließt, ist wohl doch zu viel erwartet, schließlich ist der Mensch eure Ware und Nachhaltigkeit nicht euer Problem. Leider wandelt sich euer Verhalten mehr und mehr zu dem eines Spam-Bots und meine Reaktion darauf entspricht auch immer mehr diesem Schema - leider gibt es bei Xing noch keinen Spamfilter. Persönliche Ansprachen sind selten geworden, die Stiefelleckerei in euren Texten und eure Penetranz kotzen mich an. Die Zeiten, wo ihr Nerds und Geeks mit Schmeicheleien hinterm Ofen hervor locken konntet, sind nun seit Jahren vorbei. Ich suche mir meinen Job selbst aus. Und das habe ich bereits getan. Ich weiß, dass ich einigen Vertretern eurer Zunft Unrecht antue. Leider sind mir bis zum heutigen Tage nur ein oder zwei von euch begegnet, von denen ich das oben gesagte nicht behaupten kann.

Ein Newsletter Tool selbst gebaut - Neo4J, RabbitMQ, Vaadin

Seit einiger Zeit arbeite ich jetzt als Java Developer bei der trivago GmbH. Zum ersten Mal durfte ich nun auch an den trivago Developer Days teilnehmen, welche vom Konzept her etwas an die Google'sche 20% Regelung erinnern. Wir Developer bekommen in regelmäßigen Abständen 3-4 Tage Zeit, sich ein Projekt auszuwählen (aus dem internen Ideenportal oder aus eigener Motivation) und dieses Umzusetzen. Für mein erstes DevDays Projekt habe ich mich, zusammen mit Christian Krause (@redbrick) an ein Mail Delivery System gesetzt. Drei Tage (plus ein Halber für das Vorbereiten der Präsentation und ein weiterer Halber für das Setup) sind nun nicht viel, auch wenn man die Definition von "Tag" irgendwo zwischen acht und 14 Stunden ansiedeln kann. Wir haben uns also auf die Kern-Features beschränkt, die wir selbst von einem solchen System erwarten würden. Klar war, dass Mail-Delivery die Kernkompetenz sein sollte. Wir wollten jedoch, auf der Delivery Schicht basierend, auch eine Applikation erstellen, damit der Nicht-Tekkie auch etwas davon hat. So ist die Idee des Newsletter Systems entstanden, welchem wir den Arbeitstitel Mail-Pigeon verpasst haben. Die Wunsch-Features im Überblick: Mail-Delivery:

  • Versand über mehrere Clients (horiz. Skalierbarkeit)
  • Kein Datenverlust beim Absturz einer oder aller Sending-Daemons
  • Bounce Handling (zumindest erst mal rudimentär)
  • Ein Datenformat, dass sowohl von PHP und JavaScript, als auch von Java beherrscht wird. Bleibt nicht viel: XML und JSON. Und XML war es nicht ;)

Newsletter System:

  • Absender Management (Durch die vielen Nationen und Sprachen bei trivago haben wir sehr verschiedene Absender)
  • Empfänger und Empfängergruppen
  • Newsletter und Vorlagen für neue Newsletter sowie Personalisierungsmöglichkeiten
  • Wirkungsgradbestimmung durch Trackingpixel und Kampangen
  • Live Versandstatus und Fortschritt
  • Tagging für einen Versand

Als Technologien kamen Neo4J, eine GraphDB, RabbitMQ, eine MessageQueue und Vaadin, ein auf GWT basierendes UI Framework zum Einsatz. Ich werde alle Technologien, deren Verwendung und eine kurze Begründung zur Wahl im Folgenden anreißen.

RabbitMQ ist ein MessageQueue Server, der von VMWare's SpringSource Devision in Erlang entwickelt wird. Die Wahl fiel auf RabbitMQ, weil er sowohl AMQP und JSONRPC over AMQP, als auch STOMP unterstütz und damit für alle bei trivago eingesetzten Sprachen erreichbar ist. RabbitMQ ist zudem hochperformant und kommt unserem Vorhaben, Tonnen von Mail zu versenden, zu Gute.

Neo4J ist eine Graphdatenbank, geschrieben in Java. Neo4J unterstützt sowohl gerichtete, als auch gewichtete Kanten, ebenso wie Eigenschaften an Knoten. Das Konstrukt wird ergänzt durch einen Lucene Index für Knoten, über den man recht schnelle Key-basierte Lookups durchführen kann. Die Wahl fiel deswegen auf eine GraphDB, weil sie am sinnvollsten unsere Daten abbildet. Es entstehen sehr viele Beziehungen zwischen den Entitäten unserer Applikation, die durch RDBMS - JOIN - Konstrukte sicherlich nur unter hohem Rechenaufwand abbildbar wären.Ein Beispiel ist die Relationsmenge zwischen Empfänger (E), Empfängergruppe (G) und versendetem Newsletter (N). Hier gibt es folgende Relationen abzubilden:
  • N -> versendet an -> G
  • E -> hat empfangen -> N
  • E -> hat geöffnet -> N
  • G -> enthält Empfänger -> E
Nehmen wir noch einen weiteren Knotentype "Bounce" (B) hinzu, wird das Konstrukt noch etwas interessanter:
  • N <- ist hard-bounced <- B -> ist hard-bounced -> E
  • N <- ist soft-bounced <- B -> ist soft-bounced -> E
Damit lässt sich also recht schnell darstellen, welcher Bounce-Typ bei welchem  Newsletter oder Empfänger vorkam. Kanten lassen sich übrigen mit linearem Aufwand zählen, wenn man den Knoten kennt!

Vaadin ist ein auf dem Google Web Toolkit basierendes UI Framework. Ich bin kein großer HTML/CSS Künstler, also musste etwas anderes her, was erwachsen und optisch ansprechend war. Mit Vaadin konnte ich im Liferay - Bereich schon mal Erfahrungen sammeln und fand es schon damals sehr ansprechend. Wer mal Swing oder AWT benutzt hat, der wird sich bei Vaadin recht schnell heimisch fühlen. Jedenfalls bekommt man bei Vaadin jede Menge "geschenkt", was Optik, Kompatibilität und Technologie angeht. Ich kann euch nur den Sampler ans Herz legen, dann versteht ihr was ich meine ;)

Personalisierung  haben wir durch das Einbetten von Apache's Velocity erreicht. Die Mail Templates, aus denen man neue Newsletter erstellen kann, können in Velocity geschrieben werden. Beim Versand wird der Template-Context mit den Daten des Empfängers, der Gruppe, der Kampange und Metadaten befüllt und für jeden Empfänger evaluiert. So wird eine komplette Personalisierung ermöglicht.

Tracking wird durch das automatische Einfügen eines <img/> Tags in die HTML Version der Mail erledigt. Das Image ruft ein separates Servlet auf, welches den Newsletter und die Empfänger ID benötigt. In der Folge kann dann die gerichtete Kante E -> hat geöffnet -> N erstellt werden.

Tagging erscheint vielleicht auf den ersten Blick für einen Newsletter ein wenig sinnfrei. Wenn man jedoch die GraphDB in die Rechnung mit einbezieht und das Tracking hinzu nimmt, dann entsteht die Möglichkeit "User-Interest-Tracking". Die Kobination Tag (T) sieht dann z. B. folgendermaßen aus (Die Pipe soll zwei Kanten darstellen):
T <- hat Tag <- N <- hat empfangen | hat geöffnet <- E.
Aus diesen Relationen können wir also, bei entsprechender Skalierung, ablesen, für welche Tags sich ein Empfänger interessiert.

Mit ownCloud iCloud nachbauen

 iCloud ist ja seit dem Erscheinen von iOS5 aus dem Beta - Stadium raus und wird ersetzt den bisherigen Me.com, bzw. den ganz alten .Mac Service. Ich bin recht froh, dass ich meine Me.com E-Mail nun kostenlos als Spamfänger weiter betreiben kann. Die 79€ im Jahr taten nach einiger Zeit ganz schön weh. Wer nun kein iPhone besitzt oder einfach nur kein Interesse hat iCloud zu nutzen, dem sei ownCloud ans Herz gelegt. OwnCloud basiert auf bekannten und bewährten Technologien, darunter PHP 5.2, MySQL (alternativ auch SQLite oder PostgreSQL) und dem WebDAV Protokoll. Hinzu kommen noch CardDav und CalDav. OwnCloud bringt, neben Kalender- und Kontaktsynchronisierung, auch Bookmarks und Datei-Storage mit. Hier wird noch zwischen Musikdaten, welche direkt a la GoogleMusic gestream'ed werden können, und anderen Daten unterschieden. Die "anderen Daten" können publiziert werden, ähnlich, wie man es vielleicht von Ubuntu One kennt. Die Installation gestaltet sich recht einfach, die Nutzung ebenfalls. Die UI wird durch jQuery unterstütz und der Doctype steht auf HTML5 - wobei ich jedoch keine in HTML hinzugekommenen Elemente bisher gesehen habe. Wer sich ownCloud anschauen will, der findet unter http://owncloud.org weitere Informationen. Es wäre jedoch ratsam, die Installation nicht auf einem unterdimensionierten Webspace zu versuchen. Wenn man eine mittlere Musiksammlung (als "mittel" nehm ich jetzt mal einfach 20 Gbyte) hochladen möchte, dann kann es beim Hostingangebot "WebVisitenkarte XYZ" doch recht schnell problematisch werden ;).

Weg von Squarespace - zurück zu Wordpress

ePress ist ja leider noch in der Planung, sonst hätte ich mir gern diesen Schritt gespart. Jedoch ist Squarespace einfach zu teuer geworden, gemessen an der erbrachten Leistung. Wordpress ist zwar auch nicht der Himmel auf Erden und ich hoffe, dass mir die Wahl nicht zum Verhängnis wird. Ich möchte noch mal dazu aufrufen Feature Requests für ePress zu erstellen. Macht einfach ein neues Ticket auf GitHub auf und wir schauen es uns an!

PageRank für Community Ratings nutzen - Teil 2

Im zweiten Teil der Serie nehmen wir uns mal das Datenmodell vor.
Zuerst brauchen wir einen Nutzer, der durch einen Knoten im Graph dargestellt wird. Dieser Nutzer erhält die Eigenschaften "id", welche in den Lucene Index von Neo4J übertragen wird, und einen PageRank. Vom Nutzer selbst gehen bis zu zwei verschiedene Kantentypen ab. Die "RATE_SUBJECT" Kante und die "RATE_USER" Kante. Beide werden mit der Eigenschaft "value" versehen. Daraus schließt sich schon die erste eingehende Kante, denn der User kann ebenfalls bewertet werden (in Form eines RATE_USER). Die RATE_USER Kante bekommt zusätzlich noch eine Eigenschaft, die einen Bezug zur Bewerteten Bewertung darstellt. Diese ist für unsere Berechnung nicht direkt relevant, lässt sich aber für Visualisierungszwecke gut nutzen. Die RATES_SUBJECT Kante bekommt die subject id aus dem selben Grund verpasst. Man könnte das Subject noch als Cluster Kriterium für den PageRank einsetzen, was aber die Komplexität deutlich steigern würde. Hinzu kommt ein Knoten für das zu bewertende Subject. Dieser bekommt auch die Eigenschaft "id" und einen aus dem Grahen errechneten Faktor, der in das Ranking der Suche einfließt. Aktuell evaluiere ich die Menge der Nodes, die bei einem Vollimport aller Ratings seit 2008 entstehen würden. 500.000 and counting. Es bleibt zu evaluieren, ob Neo4J sich bei diesen Mengen noch als praktikabel erweist...