tl;dr: Wenn ihr neue Musik finden wollt und einen Soundcloud Account habt, seht euch Rain an. Habe ich geschrieben, weil ich einen modernen Web Development Prozess mal von der Datenbank bis zum CSS durchziehen wollte. Code steht hier.

Eigentlich läuft immer Musik, wenn ich mein Rechner eingeschalten ist. Das können leicht acht bis zehn Stunden täglich sein. Der Verschleiss von Musik ist dabei ziemlich hoch, an sich tolle Podcasts sind nach zwei Nachmittagen langweilig. Vor etwa einem Jahr brauchte ich wieder neue Musik, wollte aber wegen der Prüfungszeit keine Zeit für die Suche aufwenden. Was macht der Geek?

Optimierung

Er schreibt etwas, das ihm automatisch neue Musik besorgt. Dabei habe ich mich an Favematic orientiert, welches das Prinzip vom großartigen FlickrFavr übernimmt: Zeige mir favorisierte Tracks von Leuten, denen ich auf Soundcloud folge. Favematic hatte allerdings für meine Anwendung einen großen Nachteil: Es erforderte alle 10 Tracks einen Seitenrefresh, was es als Radio unnütz machte. Die Entwicklung zog sich über mehrere Iterationen.

Zuerst war es eine Single Page Webseite wie Favematic, die Soundcloud Widgets lädt und mit einem jQuery Plugin eine Playliste draus macht. Wegen den vielen Widgets und deren unkoordinierten DOM Operationen war es aber unglaublich träge und der Code die Callback Spaghettihölle (kein MVC, Promises oder irgendetwas, was strukturieren geholfen hätte).

Favematic

Es musste etwas getan werden! Also baute ich einen Server ein, der mir die Widgets als vollständige DOM Knoten schickt, die dann als ganzes mit einem Mal eingefügt werden können. Natürlich half die Lösung nichts und dass ich DocumentFragment noch nicht kannte, war auch kein Vorteil.

Ich sah das Problem noch immer bei den DOM Operationen, weil die Musik stockte, wenn neue Tracks in die Playliste kamen. Nachdem es mit Soundcloud Widgets einfach nicht klappen wollte, musste ich eine eigene Repräsentation der Tracks bauen. Dafür verwendete ich Backbone für die Aufteilung in Models und Views sowie waveform.js um die Soundcloud-typische Waveform aus einem Audiostream zu generieren.

Nachdem alles mit Backbone umgeschrieben war, spielte ich Rain auf Heroku. Heroku fand es aber nicht so scharf, dass die Tracks von Soundcloud synchron eingesammelt wurden, meine Seite also ewig keine Antwort gab. Ich musste eine Queue und Worker einbauen. Dafür nahm ich Navvy, weil es zusammen mit Sequel gute Arbeit macht und ich aus Kostengründen sowieso nicht mehr als einen Worker aktiv haben wollte.

Favematic

Okay, schön. Nun tat ein Worker die harte Arbeit, welche abhängig von der Anzahl an Tracks mehr oder weniger lang dauern konnte. Da er aber asynchron arbeitet, stellt sich die Frage wie der geneigte Musikliebhaber informiert werden soll, dass es losgehen kann? Ich entschied mich für ein Email von Pony. Die Email-Adresse wird nach dem Senden gelöscht, weil sie erstens nicht weiter benötigt wird und Rain zweitens möglichst kein Ziel für Angreifer sein soll. Weil die Soundcloud UserID nur gehasht (SHA-512) verwendet wird, weiß Rain außerdem gar nicht, wer es benutzt. Reiner Selbstschutz.

Zum Schluss musste nur noch alles etwas poliert werden: Bootstrap anpassen, User Input validieren, konsistente Alertboxen, schicke Navigationsleiste, Memory Leaks stopfen, Performance überprüfen etc.

Von Funktionalität und Aussehen her war Rain fertig, aber etwas störte mich noch: Der Worker auf Heroku kostet 35 $/Monat, wenn er durchläuft. Mit so viel Interesse an Rain war (und ist) nicht zu rechnen, das heißt nach der ersten Woche wird er hauptsächlich idlen. Wäre doch super, wenn man den Worker automatisch einstellen und feuern kann, oder? HireFire macht genau das, unterstützt aber Navvy nicht. Also schrieb ich einen Ruby Gem (Sklaventreiber), der den Heroku Worker triezt, wenn nötig. Außerdem war eine modifizierte Version von Navvy nötig, welche einen neuen Adapter für Sequel enthält. Das originale Navvy benutzt nämlich keine Sequel Model Hooks. Aber natürlich klappte das auch nicht so richtig, weil irgendwo in der Befehlskette von Navvy::Worker ausgehend die Hooks verloren gingen. Der Autor von Navvy konnte mir leider auch nicht weiterhelfen (verständlich nach 2 Jahren!), also musste ich die Checks, ob ein Heroku Worker benötigt wird, hardcoden.

Jetzt läuft Rain einigermaßen so, dass ich mich ums nächste Projekt kümmern kann. Es ist möglich, dass keine Emails versendet werden, weil Google “suspicious activity” im Rain Account erkennt. Einfach später wieder reinschauen, irgendwann sind Tracks in der Playliste.

Also, gebt Rain eine Chance.