Mosh: Mit SSH in der Bahn

Wer kennt es nicht: Abends noch eine SSH-Session laufen gehabt, Laptop zugeklappt und zuhause ist die Session tot. An ein Arbeiten im Zug ist noch nichtmal zu denken.

Anderes Szenario: Man trennt sein Netzwerkkabel um kurz einem Kollegen was zu zeigen und obwohl man immernoch mit dem WLAN verbunden ist, ist die SSH-Session nicht mehr zu retten.

SSH ist ein super Tool, um remote Aufgaben zu erledigen. Das Problem an SSH ist nur, dass es eine durchgehende TCP-Verbindung braucht.

Mobile Shell

Hier kommt Mosh (MobileShell) ins Spiel: Mosh setzt auf UDP und braucht keine persistente Verbindung zum Server. Roaming mit verschiedenen IPs ist somit kein Problem mehr. Als zusätzlichen Vorteil bringt Mosh noch die Erkennung der Tastenanschläge mit, so dass nicht erst auf die Antwort vom Server gewartet wird, bis der Anschlag auch in der Shell angezeigt wird. Ein Traum für alle Bahnfahrer und Tastaturvirtuosen!

Type Class 101: Category and Monads

I found a post by Qiaochu Yuan that has the following definiton: A comathematician is a device for turning cotheorems into ffee.

Apparently this is a very funny joke. Could someone explain it to me and tell me where I could learn about the subject in question? Thank you very much in advance.

+1 for “Apparently this is a very funny joke”. math.stackexchange.com

Category and Monads

By the way, the above joke has nothing to do with todays topic, I just found it funny.

I had a little bit of a writers block since the last episode in the series about ApplicativeBuilder, since I was not sure how to approach the coming topics. Hence we take a little bit of time to disgress. Semigroups, Monoids, Functors and Applicatives are all concepts found in category theory. Category theory is a very general mathematical theory, but it deals with something which is at the core of functional programming, and hence makes it so attractive for programmers. It is dealing with:

  • Abstraction
  • Composition

And composition is something which we want to exploit, and there stems our interest in category theory.

Safeguarding destructive functions on the MongoDB shell

The Gist

You can redefine the behaviour of the mongodb shell. In this post, we use this to safeguard against accidental calls of destructive functions.

The same principle can also be used to remove access to any functionality of the mongodb shell.

The Story

A couple of months ago, in one of our projects, during a live deployment, the deployer accidentally dropped all indexes on a central collection. I can’t blame him - this can happen to (almost) anyone given enough time, and he’s very experienced with a history of splendid work.

We do post mortem analyses for incidents, so we tried to figure out some causes for this one. We came up with:

  • the wonderful tab completion the mongodb-shell has
  • fingers being quicker than the brain
  • working manually on the live database

There’s already some things to easily take away from this one:

  • don’t perform manual work on the live database, write scripts that are tested on a test database
  • if you need to manually apply migrations, do this in pairs, be attentive

Today, I want to present to you another quickwin we came up with to protect us from this kind of thing happening again.

I love the mongodb shell. I happen to have a good grasp on javascript, so I can apply this knowledge 1:1 when querying the database. In contrast to SQL shells, I have a context and state, so I can use the output of a query for mangling the data or even as input for another query or even multiple queries. Overall, I’m a happy camper and am not looking back to SQL shells. And you can configure it via an rc file on a system (/etc/mongorc.js) and user (~/.mongorc.js) basis.

Javascript is a dynamic language. This allows for Monkey Patching - replacing functions at runtime. We decided to implement a safeguard for destructive functions with the goal of reducing errors due to tab completion and fingers quicker than the brain.

In order to achieve that, we wanted to replace a function with a safeguard that stopped the normal execution of the destructive function, but kept it available in a convenient manner. We decided to republish the destructive function under the same name, but with a random string appended. This way, tab completion will always stop at the safeguard. Let’s see it in action:

Note that the name under which the function is republished (in this case “dropIndexeskgk”) changes for each new instance of the mongo shell.

The code actually is quite simple:

Take it apart

So, let’s dissect this snippet.

In line 1, the whole functionality is wrapped in a so called IIFE. This is a standard Javascript pattern to prevent namespace pollution.

Since we want to append random strings to our function names, we define a function for generating random strings on lines 3-5 (in a javascript specific, concise manner).

The main action happens in the obfuscate function (lines 7-24). First, we safeguard against invalid input (objects without prototype, line 8, and functions that don’t exist, line 13), so that if any object or function names change in future MongoDB versions, the script will at least notify the user. Then we publish the original function under the obfuscated name (line 17) and then put the safeguard function in place of the original function (lines 18-20).

On lines 26-49, the destructive calls are defined and passed to the obfuscate function.

Wrap it up

We roll this out to all our servers using chef. Our experience has been positive. It’s not too intrusive, but achieves its goal.

If you want to give your users the ability to skip the safeguarding, roll it out to ~/.mongorc.js, sourcing of which can be prevented by calling the mongo shell with the –norc parameter. Otherwise, roll it out to /etc/mongorc.js, which will always be sourced.

How to log slow async requests with Play Framework 2

In our current project we just wanted to see which requests exceeded a certain response time threshold. Additionally we wanted to know where the time was spent, i.e. which backend requests (e.g. hitting the database or search engine) contributed how much to the overall response time. So we’d like to get log entries like this:

2014-12-13 22:12:30 SLOW "GET /search?q=foo" (139 ms), segments: solrQuery (67 ms), dbLookup (69 ms)

In a synchronous/blocking application measuring subordinate requests/operations and associating them with the main request thread is fairly easy (just use ThreadLocal). In an application that runs async requests this is not the case, because there’s not that single thread that can be used as “global” state to associate measurements with.

Here comes Kamon into play, a toolkit for monitoring of reactive applications built on top of Play, Spray or Akka. Kamon uses bytecode instrumentation to introduce metrics and tracing logic into your application, so it already solves the problem of transferring the context of a request to other, subordinate asynchronous operations (segments). In Kamon this is called the TraceContext (see also their Trace documentation).

The awesome guys of Kamon also just introduced trace subscriptions, that allow users to receive information about recorded traces. And that’s exactly what we need to log slow requests and details about segments: Kamon maintains the TraceContext over async operations, we record segment information, and after the request is finished Kamon passes the combined trace information back to us so that we just need to format + log the slow trace.

In the following it’s shown what needs to be done to log slow requests using Kamon’s trace subscription.

Type Class 101: ApplicativeBuilder

Admiral Ackbar

Today we talk about the little wiggly operator |@|. Being slightly deaf and one of the few living persons on this planet who never watched a Star Wars movie, I always thought people call this the allah al akbar operator, when in fact it is called the Admiral Ackbar operator. If you haven’t so far, please read the post about Applicatives as this blog post builds on top of it.

Applicatives as alternatives to for comprehensions

Say we have some values in an Option, want to retrieve that value and create a case class instance from that, which is again optional, than using the monadic for comprehension we could write:

case class ABC(a: Int, b: Int, c: Int)

val result : Option[ABC] = for {
  a <- aOpt
  b <- bOpt
  c <- cOpt
} yield { ABC(a,b,c) }

This is all fine and dandy, and a common pattern in Scala code. For comprehensions are actually translated into calls of flatMap, map and filter (more on that when we cover Monads) and one property of this translation is that it is sequential. Despite the fact, that we could calculate a,b and c independently, we don’t.

Jump - ein Technologie-Sprung bei Galeria Kaufhof

Jetzt ist es offiziell: Seit 6 Monaten arbeiten wir von inoio zusammen mit weiteren Dienstleistern und Galeria ­­­­­­­­­­Kaufhof an deren neuer Multi-Channel Online Plattform - Projektname “Jump”. Mit dem neuen System soll die Time-to-Market erheblich reduziert werden, wenn es um die Einbindung und Entwicklung neuer Features geht.

Makroarchitektur

Die monolithische Architektur des bisherigen Systems wird im Rahmen des Projektes durch eine moderne, skalierbare “Shared Nothing”-Architektur abgelöst. Die verschiedenen fachlichen Domänen werden dabei im Sinne einer funktionalen Modularisierung durch voneinander getrennte Systeme umgesetzt. Die Systeme arbeiten ähnlich wie Microservices - passender ist hingegen der Begriff der “Self Contained Systems”, wie ihn Stephan Tilkov in Sustainable Architecture beschreibt.

Jump Struktur

Domänen- und Querschnittsteams

Frontend-Integration: Integration der Vertikalen zu einer zusammenhängenden Website | Explore: Teaser-Steuerung | Search: Produktsuche u. Navigation | Evaluate: Produktdetails | Order: Bestellen | Control: Kundenkonto | Foundation Systems: Querschnittsdienste wie Media o. Feature Toggles | Platform Engineering: Tools, Deployment u. Betrieb

Die einzelnen Domänen werden dabei von externen, spezialisierten Teams zusammen mit Galeria Kaufhof-internen Programmierern entwickelt. Dabei ist jedes Team für eine einzelne Domäne verantwortlich. Für das Zusammenspiel zwischen den Systemen (Makroarchitektur) gibt es einige Regeln: Um eine lose Kopplung zu gewährleisten darf es z.B. kein fachliches Code Sharing (für vermeintlich gemeinsame Datenklassen) geben, genausowenig eine gemeinsame Datenhaltung. Die Kommunikationen zwischen den Systemen erfolgt ausschliesslich über REST-Schnittstellen. Die Kommunikation muss dabei asynchron erfolgen, um verteilte Call-Stacks im Client-Request zu vermeiden. Alle Systeme müssen zustandslos implementiert sein, damit Ausfallsicherheit und Skalierbarkeit gewährleistet werden. Während die Makroarchitektur weitestgehend vorgegeben ist, ist die Mikroarchitektur, also der Aufbau eines einzelnen Systems in der Verantwortung des Teams. So gibt es beispielsweise keine verpflichtende gemeinsame Programmiersprache/Technologie.

Mikroarchitektur / Technologien

Von den 5 Domänen haben sich 4 für eine Lösung auf Basis von Scala und Play Framework/Akka entschieden und ein Team für Ruby on Rails. Die von uns entwickelten Systeme Explore und Search werden auf Basis von Scala und Play implementiert. Für Scala haben wir uns zum Einen aufgrund der Paradigmen der funktionalen Programmierung entschieden - weil wir davon überzeugt sind, dass Programmieren unter Vermeidung von Seiteneffekten letztendlich zu qualitativ besserer Software führt und dies durch einen funktionalen Programmierstil einfacher zu erreichen ist. Zum anderen läuft Scala auf der JVM und man hat Zugriff auf eine Vielzahl von Java-Bibliotheken. Das Play Framework wiederum passt durch seinen HTTP-freundlichen Ansatz, seine hohe Skalierbarkeit durch Zustandslosigkeit und Unterstützung von asynchronen, nichtblockierenden Implementierungen (Buzz: “reactive”) sehr gut in das Projekt. Für Persistenz wird Cassandra eingesetzt - u.a. wegen seiner sehr guten Skalierungs- und Verfügbarkeitseigenschaften. In unserem Search Team verwenden wir Solr als Suchtechnologie, hauptsächlich weil Solr im Vergleich zu ElasticSearch bessere Eingriffsmöglichkeiten bzgl. Suchqualität bietet.

An diesem Punkt ist die Integration eines asynchron/nicht-blockierend arbeitenden Frameworks mit Backend-Schnittstellen (wie Datenbank etc.) interessant: Häufig existieren für Backend-Technologien nämlich nur synchrone/blockierende Treiber, sodass der Nutzen eines asynchron arbeitenden Frameworks (u.a. effizientere Verarbeitung und bessere Skalierbarkeit durch Minimierung der Anzahl benötigter Threads) zunichte gemacht wird. Entweder man verwendet das Web-Framework dann synchron (was das Play Framework auch anbietet), oder man muss die sychronen Zugriffe durch eine separate Schicht mit einer asynchronen API versehen (z.B. mit Akka kapseln). Glücklicherweise bietet der Datastax Java Treiber für Cassandra bereits eine asynchrone API (die Implementierung basiert auf Netty), die sich sehr einfach in Scala Futures übersetzen lässt. Für Solr wiederum haben wir uns einen eigenen asynchronen Client geschrieben (auf Basis des Async Http Client), der die gleiche API wie SolrJ anbietet, aber eben asynchron. Somit lässt er sich im Wesentlichen genauso bedienen wie SolrJ.

Mit diesen Treibern an Bord können wir die Webanwendung “End-to-End” asynchron und non-blocking entwickeln, ohne unnatürliche oder künstliche Übergänge (async/sync) zu haben. Bei der Entwicklung asynchronen Codes kommt uns die Eleganz von Scala sehr zu gute, da bspw. Futures sehr schön mit for-Comprehensions kombiniert werden können - ohne dass man sich in einer “Callback-Hölle” wieder findet.

Wie geht’s weiter?

Wir sind sehr glücklich, in Galeria Kaufhof einen Partner gefunden zu haben, der diese Technologiewahl (v.a. die Wahl von Scala) befürwortet. Für Galeria Kaufhof ist das besonders relevant, weil sie bald die Weiterentwicklung der Platform komplett im eigenen Haus haben wollen. Durch die Wahl moderner Technologien gibt es sicherlich einen Vorsprung im ”War for Talents”, um neue Entwickler anzuwerben - bei inoio haben wir diese Erfahrung jedenfalls gemacht.

Zu diesem Zweck stellt Galeria Kaufhof das Projekt Jump auch “persönlich” vor, am nächsten Donnerstag (25.9.) im Startplatz (Köln). Zunächst wird Nina Ehrenberg die fachlichen Hintergründe des Projekts erläutern. Jan Algermissen (Plattform-Architekt) wird dann etwas zur Makro-Architektur und dem Zusammenspiel der verschiedenen Systeme erzählen. Im Anschluss werde ich noch etwas mehr Einblick in die technologischen Details geben, und anhand von Beispielen zeigen, wie wir in unserer Domäne Search Play/Akka/Scala einsetzen, welche Themen hinter uns und welche Aufgaben noch vor uns liegen. Natürlich sind Entwickler, die gerade neue Herausforderungen suchen besonders gern gesehen :-) Ich freue mich jedenfalls auf spannende Fragen und interessante Diskussionen - vielleicht sehen wir uns ja!

Type Class 101: Applicative

Gestaltwechsel

In the last installation of this series, we covered the Functor and now we take a turn to discuss the Applicative type class.

It’s all about functions

Being functional programmers, the thing we embrace most are functions. Despite scala being an object-functional language, I fell in love with it, due to it’s possibilities to write code using the functional paradigm and not state mutating object nonsense. And I believe it is a good exercise, if you (like me) come from a java background to emphasize functions over objects first. It is a different way of approaching problems, and it needs getting used to, but it pays of in the end.

Type Class 101: Functor

Functor

In the last installation of this series, we covered the Foldable and now we take a turn to discuss the Functor type class. Basically we cover some building blocks out of which more complex type classes can be build.

The Functor is usually well understood, as each scala programmer has made intensive contact with it already:

trait Functor[F[_]] {
  def map[A, B](F: F[A])(f: A => B): F[B]
}

Type Class 101: Foldable

Foldable

The last two articles in this series were concerned with introducing the concepts of a Semigroup and a Monoid.

Today we turn to a type class which was inspired by Mad magazines fold-ins. If you prefer not to stray into pop culture and stick with computer science, we could also say, that Foldable gives us the semantics of the Map/Reduce paradigm, though that comparison is a little bit stretched as well.

Here is the type class:

trait Foldable[F[_]] {

  def foldMap[A, B](fa: F[A])(f: A => B)(implicit F: Monoid[B]): B
  def fold[M: Monoid](t: F[M]): M = foldMap[M, M](t)(x => x)
  def foldRight[A,B](fa: F[A], z: => B)(f: (A,B) => B) : B
  ... foldRight and foldLeft...
}

Type Class 101: Monoid

In the last installment of this series, we had a look at one of the most primitive type classes, the semigroup. Today we add one nifty feature to it, namely the notion of an identity element zero:

trait Monoid[A] extends Semigroup {
  def zero : A
}