• Skip to main content
  • Skip to primary sidebar

Mark Goldenstein

  • Blog
  • Über mich
  • Impressum
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy

Blog

Monday, 29. June 2015 by Mark Goldenstein Leave a Comment

Spotify and others use an unfair formula to pay artists

Tomorrow, Apple introduces its own music streaming service. It seems to be the right moment to explore how the music streaming industry splits its revenue.

There have already been some articles written about the unfairness of Spotify’s model (one, two, three) but I’m looking at the issue from a different perspective.

Ready? Let’s go.

Is this about the whole music streaming industry or just Spotify?

I’m focussing on Spotify but the thoughts probably apply to all other offerings as well.

So… how much does Spotify pay rights holders?

According to its own website for artists, Spotify pays out about 70% of its revenue to rights holders. Those rights holders then pay the actual artists according to their own contract terms.

Spotify Revenue Split Overview

This doesn’t look too bad! So what exactly is unfair?

Glad you asked! The devil is in the detail. Spotify uses roughly the following formula to split its revenue:

Spotify Royalty Formula

The interesting part here is part two of the formula, the Artist’s Spotify Streams divided by Total Spotify Streams which Spotify describes as calculating the artist’s popularity or market share . The problem is, in a nutshell, that it does not matter how many streams a user listens to, each stream counts the same. Those users who listen to the most streams also exert most of the influence over how much rights holders and, consequently, artists get paid.

What does that mean in practice?

Imagine the following simplifying scenario: There are two users, let’s call them Alice and Bob, and two artists, let’s call them Amazing Rock and Junk Pop. Just for the sake of argument of course. So Alice loves listening to Amazing Rock. Because she is a workaholic she has only time to listen to 100 streams per month. In contrast, Bob likes to listen to Junk Pop and, because he’s a student, he has a lot of leisure time. Hence, he listens to about 5000 streams per month. Alice and Bob each pay $10 to Spotify. Now Spotify splits its revenue of $20 according to the formula quoted above; for the sake of simplicity we disregard taxes. Spotify takes 30% or $6 to cover its own costs. This means that $14 remain to pay rights holders. Amazing Rock gets $0.27 and Junk Pop get $13.73.

Wow! That does not seem right!

Exactly! It also means that your subscription fee pays for artists that you don’t give a shit about.

What? Are you fucking kidding me?

Nope. See those artists in the Global Top 50 charts that you never listen to? You pay for them![1]This is true if you listen to fewer streams than the average stream count per user.

It sucks! But maybe that’s just how a flat rate model works?

While it is true that a flat rate model often means that those who use a service less tend to cross-finance those who use it more, I believe that this is not the right model for music streaming. It simply gives “power listeners” too much power.

So what would be a fair revenue split model?

In my opinion the customer that pays the subscription fee should also have decisive influence over which artists receive his money. This model is much closer to traditional album sales where the customer knows that his purchase supports the actual artist. With Spotify’s current royalty system this is not necessarily true.

Are there any other benefits to a fairer system?

In fact there are. Changing the formula could also fix the problem that indie labels are getting almost nothing from Spotify.

Cool! How does the improved royalty system look like?

We only need to adjust part two of the current formula a bit. Instead of

\text{Artist's Popularity} = \frac{\text{Artist's Spotify Streams}}{\text{Total Spotify Streams}}

we should instead use

\text{Artist's Popularity} = \frac{\sum_{i=1}^{N} \frac{\text{Artist's Spotify Streams by User i}}{\text{Total Spotify Streams by User i}}}{N}

where N is the total number of users.

What is the advantage of this alternative formula?

This improved formula would make sure that the subscription fee of any customer is distributed according to his own listening habits and not those of others. Another way to describe it: If you pay $10 a month, Spotify would still take $3 out of them but the remaining $7 would be split according to your listening habits, and not according to the listening habits of others.

By the way, this is similar to how flattr works, a micro donation service.

Got it! So why is Spotify not using this formula?

That is a good question.

Update: I just saw that there has been a similar discussion a few months ago: Jack Stratton’s take on the same topic and corresponding HN thread.

Notes   [ + ]

1. ↑ This is true if you listen to fewer streams than the average stream count per user.

Filed Under: English

Tuesday, 22. April 2014 by Mark Goldenstein 9 Comments

Building a Websocket client to btcwallet using Scala and akka

I’ve been experimenting with the Bitcoin wallet daemon btcwallet for some time. btcd and btcwallet provide support for notifications via websockets which allows to process bitcoin payments in an event-driven programming style instead of polling. As of this writing proper notification support in bitcoind seems to be in limbo state (cf. this and that). It is possible to get notifications using scripts and the *notify command-line options but this seems to be a rather hackish solution.

So let’s build a websocket client to btcwallet. How do we do that in my favorite programming language, Scala?

Implementation

Usually, it’s inconvenient to use websocket or json APIs directly. As an abstraction to btcwallet’s websocket API I use akka, a library that implements the Actor model. Actors are threadless, stackless units of execution that process messages (events) serially. Messages are delivered to an Actor’s mailbox, and the Actor processes them by looping over a method that pops the first message from the mailbox.[1]David Pollak, Beginning Scala, Apress, Berkely, CA, 2009 I want to talk to btcwallet using Actor messages and receive Futures in return. Those messages will then be forwarded to btcwallet using its websocket API. When a response is available the corresponding Future will be completed.

Therefore, we can design our websocket client as follows. We define our BtcWalletActor such that it establishes a websocket connection to btcwallet as soon as it starts. If it loses the connection, it tries to reconnect in five seconds intervals. Objects that need to talk to the websocket service use the ask pattern to send requests to our actor. Finally, we define the reactions to notifications and requests by implementing the receive method of our actor.

In order to connect to our service we need a websocket library. There are several different options available. I’ve chosen Java-WebSocket because it is actively maintained, popular, and has support for TLS connections (right now only in the 1.3.1 development snapshot).

We also need a library for serializing and deserializing JSON. Again, there are numerous libraries available. I’ve chosen play-json. We also define some case classes for our actor messages, and for the JSON serialization.

Websocket messages are asynchronous, there is no request-response standard in the protocol. To work around this, btcwallet uses IDs in the request and response messages. Hence, when we make a request we need to supply and store an id for it. Then we can match the response message to our request.

To account for this aspect we implement our actor as follows. When our actor processes a message from another object that requests information from the websocket service, it creates a Promise and pipes the corresponding Future to the object that requested it. Then it generates a UUID for the request and saves it together with the Promise in a Map. After it receives the response (which also contains the UUID), it pops the Promise from the Map and fulfils it with the response. If you’re wondering what Futures and Promises are, then check out this introductory guide.

Once we put everything together, we get something like this (GitHub). I’ve provided an example in which I’m processing incoming transactions by sending the bitcoins back to the sender address. I’m using the outputs of the incoming transactions as inputs of the corresponding outgoing transactions. Therefore, there is no need to wait for confirmations.

Notes   [ + ]

1. ↑ David Pollak, Beginning Scala, Apress, Berkely, CA, 2009

Filed Under: English Tagged With: actor, akka, bitcoin, btcd, btcwallet, scala, websocket

Saturday, 28. December 2013 by Mark Goldenstein 4 Comments

Complex Event Processing: Language-level integration into Scala

Last month I’ve completed my bachelor thesis on the Integration of Complex Event Processing (CEP) into a programming language. In a nutshell, I’ve combined the interface of EScala, a Scala DSL that features simple to use events as object attributes (similar to C#) with Esper, a Java CEP engine.

My library allows the use of Esper while writing type safe Scala code that is statically checked at compile-time; there is no need of using Esper’s own Event Processing Language (EPL) anymore. If you’re interested in my work you can have a look at the presentation or read my bachelor thesis. The corresponding code is accessible via GitHub.

Here are some quick examples:

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Declaring Events
 
// with one property
val e1 = new ImperativeEvent[Int]
 
// with multiple properties
val e2 = new ImperativeEvent[(Int, String)]
val e3 = new ImperativeEvent[(Int, String)]
 
// Declaring a Reaction
val r2 = (e: (Int, String)) => println(e._2)
 
// Binding a Reaction to an Event
e2 += r2
 
// Triggering an Event
e2(42, “Hello World!”)
 
// Transforming an Event
val e4 = e2.map((e: (Int, String)) => e._2.length)
 
// Filtering an Event
val predicate = (int: Int, string: String) => int == 42
val e5 = e2 && predicate
 
// Composing Events
val e6 = e2 || e3
 
// Joining Events
val e7 = e2 join e3 window time(30 sec) on ((a,b) => a._1===b._1)
 
// Declaring and binding a Reaction to a Joined Event
// (a joined event contains all properties of the underlying events)
val r7 = (e: (Int, String, Int, String)) => println(e._2 + “ “ + e._4)
e7 += r7
 
// Declaring a Repeat Event Pattern
// corresponds to every [n] event in Esper, cf.
// http://esper.codehaus.org/esper-4.10.0/doc/reference/en-US/html/event_patterns.html#pattern-repeat
val e8 = e2 repeat 3
 
// Declaring and binding a Reaction to a Repeat Event Pattern
val r8 = (e: Seq[[(Int, String)]) => println(e(0)._2 + “ “ + e(1)._2 + “ “ + e(2)._2)
e8 += r8

Filed Under: English Tagged With: bachelor, cep, complex event processing, line, thesis

Monday, 3. June 2013 by Mark Goldenstein Leave a Comment

2nd Next Generation Forum Roundup

This weekend I had the joy of taking part in the 2nd Next Generation Forum. In this post I’m going to summarize the three presentations and discussions that were most interesting to me.

Europe for a better future

The first panel discussed the state of Europe and the Euro-Zone today, what the current problems are and which policies should be implemented to increase economic prosperity. I found that the most striking idea was Frank Mattern’s reasoning: He said that the core reason for the increasing frustration of European citizens and the inaptitude of policy-makers to solve the on-going Euro-Zone crisis was the lack of emotional goals and values.

Instead of setting clear priorities and addressing the problem at its root, issues are addressed as they arise, without any foresight. Which emotional need does the existence of the European Union serve today? One goal which is often cited in newspapers is peace. But how can peace be a goal if it’s already here since more than 60 years and is already taken as granted today? Peace can’t be a motivator anymore. What about economic prosperity? Well, this goal does indeed fulfill an emotional need. However, the Euro Zone is failing miserably in this regard and hence it’s obvious that this goal is not pursued seriously.

Personally, I strongly agree with this view. There is an apparent lack of values and long-term goals in politics. Today, several years after the beginning of the crisis, there are still no indications of any plans for the key issues (diverging competitiveness, trade balance differences, unsustainable debt, over-regulation of all industries except the financial one, misplaced subsidies) to be addressed in a feasible way. Instead, with regard to the upcoming Bundestagswahl at the end of this year, there are many decisions made that go completely against any reason and seem to have the single motivation of increasing the party’s popularity within the population (Betreuungsgeld etc).

Globalization and its impact on economy and society

Prof. Hans-Olaf Henkel managed to captivate the audience with an incredibly passionate speech about globalization. In his opinion, globalization has almost exclusively positive effects, namely a dramatic increase of productivity and the spread of capitalism, democracy, and human rights. The productivity increase is particularly visible in the software industry, in which some companies have adopted the Follow-the-sun workflow which dramatically reduces project durations and enables global teams to literally work around the clock on the same project parts. Globalization has also boosted the spread of capitalism (since it’s the economic system which led to the most well-being). Capitalism has in turn often transformed the respective states to democracies and granted its citizens fundamental rights.

I liked Prof. Henkel’s speech. However, I think that globalization has also brought new problems which can only be resolved by international cooperation and coordination of law making and policy implementation. And so far it seems that states are unwilling to give up any part of their sovereignty. Global coordination of e.g. environmental, privacy protection and tax policies proves to be extremely difficult.

Smart Risk in Times of Financial Repression

The last presentation, held by Hans-Jörg Naumer, started out very promising. The speaker explained that the Federal Reserve, the European Central Bank and now the Bank of Japan are flooding the markets with liquidity and that they won’t stop this practice in the near future. Some of the official goals of the Fed and the ECB are price stability and low unemployment. However, recent policy decisions point to a shift of priorities: Price stability and unemployment seem to recede into the background, the only important emergent goals are (1) to keep the economy running and (2) to stabilize the financial markets. Thus, new bubbles are being created and the cornerstones for the next financial crisis are being set.

At the same time this monetary policy, especially when combined with new regulations (Basel III), serves the interests of highly-indebted governments: Since the growth of the economy is higher than bond yields, government debt as a portion of GDP gets eroded. How does a smart investment strategy in this environment look like?

Unfortunately, Mr Naumer talked only briefly about solutions after he explained the challenges. But as far as I understood, the solution seems to mostly consist of allocating more capital to risky and real assets, and buying well-managed Allianz products. Or at least this is what Mr Naumer from Allianz recommends.

Concluding Remarks

The 2nd Next Generation Forum was a well-organized event with fantastic speakers, fascinating presentations and panel discussions, and, above all, many amazing participants from all over Europe. I’ve even met some students who have successfully launched their own startups and raised venture capital and this motivated me to look for ideas myself. The time at NGF went by so fast that I wish it lasted more than just two days.

Filed Under: English Tagged With: conference, economics, n/f, next generation forum, review

Sunday, 3. February 2013 by Mark Goldenstein Leave a Comment

Präsentation 2.0 – es muss nicht immer PowerPoint sein

Täglich machen sich gewiefte Redner Gedanken darüber, wie sie ihr Wissen am besten dem Publikum vermitteln können. Dabei hat sich heute die “Slide-Technik” durchgesetzt – meist mit Hilfe von Microsofts PowerPoint angefertigte Folien (manchmal wird auch auf Apples Keynote zurückgegriffen), die sequenziell abgespult werden und dabei einer immer gleichen Grundstruktur folgen: Inhaltsübersicht, Einleitung, Hauptteil, Schluss. Im Laufe der Zeit haben sich bei diesem Prozess einige Gewohnheiten durchgesetzt, die von sehr zweifelhaftem Nutzwert sind, wie beispielsweise die vielfach gefürchtete “Vielen Dank für Ihre Aufmerksamkeit”-Schlussfolie. Zugleich wird die bestehende Präsentationsstruktur jedoch nur äußerst selten hinterfragt, oft wird auf die Folien einfach großzügig Inhalt verteilt, und davon möglichst viel. Die PowerPoint-“Experten” setzen dabei gerne auf einen Folienoverload, bei dem die einzelnen Folien mit einer Aneinanderreihung von ganzen Sätzen besetzt werden. Diese Sätze werden dann möglichst bildschirmfüllend platziert, sodass auf jeder einzelnen Folie nur wenig Freiraum bleibt und dadurch der Umwelt zuliebe wertvolle Lichtpixel gespart werden können.

Abgesehen von solchen Faux-pas muss man sich in jedem Fall die Frage stellen:

Sind Folien überhaupt die beste Präsentationsmethode?

Ich glaube: Nein.

Eine Präsentation erfolgt in der Regel mit der Zielsetzung, ein Publikum mit einem bisher unbekannten Sachverhalt vertraut zu machen. Dabei machen eine gelungene Präsentation aus meiner Sicht vor allem die folgenden Aspekte aus:

  • inhaltliche Präzision
  • die Vermittlung einer strukturierten Übersicht über den Themenkomplex
  • leichte Verständlichkeit
  • eine gute Merkbarkeit der vorgestellten Informationen

Unser Gehirn ist nicht so konzipiert, dass wir uns sequenzielle Inhalte leicht merken könnten. Stattdessen verknüpfen wir unsere Gedanken mit Erlebnissen, Orten, Gerüchen und Emotionen. Daher setzt beispielsweise die jahrtausendealte Loci-Methode auf die Verknüpfung von Wissen mit Orten. Diese Methode wird von ausnahmslos allen Gedächtniskünstlern zumindest zu einem Teil verwendet. Durch die räumliche Anordnung von Informationen können wir uns Informationen also deutlich besser merken – da bietet es sich doch an, sich dieser Methode auch bei Präsentationen zunutze zu machen. Wie sich herausstellt, gibt es einen solchen Ansatz bereits:

Prezi[1]alternativ gibt es auch ein ähnliches Open Source-Tool: impress.js

Mithilfe von Prezi lassen sich unglaublich dynamische, einprägsame und herausragende Präsentationen erschaffen. Ich kann daher jedem, der sein Wissen auf eine innovative Art weitergeben möchte, empfehlen sich dieses Werkzeug einmal genauer anzuschauen.

Notes   [ + ]

1. ↑ alternativ gibt es auch ein ähnliches Open Source-Tool: impress.js

Filed Under: German Tagged With: powerpoint, präsentation, prezi

Saturday, 5. January 2013 by Mark Goldenstein 4 Comments

Scala vs Java: weniger Code, mehr Inhalt

Scala ist eine Programmiersprache, die weitgehend unter dem Radar geblieben ist und im Unternehmensumfeld nur sehr langsam Fuß fasst.[1]im Dezember 2012 war sie nur auf Platz 34 des TIOBE Index, mit 0,32% im Vergleich zu Java auf Platz 2 mit 17,57% Zu unrecht wie ich finde, denn zum einen bietet Scala viele Möglichkeiten für einen Produktivitätsgewinn, zum anderen ist die Sprache 100%ig mit bestehenden Java Bibliotheken und Anwendungen kompatibel und läuft ebenfalls in der Java Virtual Machine (JVM).

Was sind also die wichtigsten Vorteile von Scala? Ich habe drei aus meiner Sicht herausragende Features ausgesucht, die ich im Weiteren näher beschreiben werde.

Funktionale Programmierparadigmen

Scala unterstützt alle objektorientierten Features von Java, bietet darüber hinaus aber auch viele Möglichkeiten, die sonst lediglich funktionale Programmiersprachen wie z.B. Lisp erlauben. Dies ermöglicht einen sehr prägnanten Programmierstil und führt direkt zu einer besseren Code-Verständlichkeit und -Qualität.

Experience with Scala shows that it typically takes one half to one third of the lines of code to express the same application as Java yet executes at about the same speed.[2]http://www.scala-lang.org/node/3069

Im Folgenden werde ich dieses Argument verdeutlichen. Zunächst ein Beispiel einer sogenannten for-Comprehension. For comprehensions ähneln den for loops aus Java, sind jedoch ein deutlich mächtigeres Werkzeug. So erlauben sie unter anderem, eine neue Collection durch die Iteration über eine bestehende zu erstellen (ähnlich zu den aus Python bekannten list comprehensions).[3]mehr zu dem Thema hier: http://www.scala-lang.org/node/111

Scala
1
2
3
4
// berechnet alle natürlichen Teiler einer Zahl
def factorsOf(number: Int) = for (i <- 1 to number if number % i == 0) yield i
 
factorsOf(42) // Ergebnis: Vector(1, 2, 3, 6, 7, 14, 21, 42)

Im folgenden Beispiel verwende ich eine Funktion als Filter – es werden nur diejenigen Elemente der Liste gezählt, die die übergebene Bedingung erfüllen: Ein Aufruf von factorsOf auf das Element soll einen Vector der Länge 2 zurückgeben.

Scala
1
2
3
4
5
6
// gibt die Anzahl der Primzahlen in einer Liste zurück
// Primzahlen haben exakt zwei natürliche Teiler: 1 und sich selbst
def countPrimeNumbersIn(list: List[Int]) = list.count(factorsOf(_).size == 2)
 
val range = 1 to 10 // Ergebnis: Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
countPrimeNumbersIn(range.toList) // Ergebnis: 4

Programmiere ich hingegen in Java, so würde die gleiche Logik zu folgendem Code führen:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static List<Integer> factorsOf(int number) {
  List<Integer> result = new ArrayList<Integer>();
  for (int i = 1; i <= number; i++) {
    if (number % i == 0)
      result.add(i);
  }
  return result;
}
 
public static int countPrimeNumbersIn(List<Integer> list) {
  int count = 0;
  for (int x : list) {
    if (factorsOf(x).size() == 2)
      count += 1;
  }
  return count;
}
 
public static void main(String[] args) {
  List<Integer> list = new ArrayList<Integer>();
  for (int i = 1; i <= 10; i++) {
    list.add(i);
  }
  countPrimeNumbersIn(list); // Ergebnis: 4
}

Die Methoden factorsOf und countPrimeNumbersIn, die zuvor prägnant in einer Zeile definiert waren, benötigen nun jeweils acht(!) Zeilen. In Java verschwindet die Logik also hinter Code-Bausteinen (boilerplate). Mit wachsender Code-Komplexität wächst auch der Wartungsaufwand der bereits vorhandenen Codebasis, sodass die Reduzierung von Code-Bausteinen mithilfe von Scala nicht nur die Sichtbarkeit der eigentlichen Logik erhöht, sondern auch die Software-Wartung vereinfacht und damit zu weniger Fehlern führt. Algorithmen, die mithilfe von Scalas for-comprehensions und maps programmiert wurden, lassen sich nachweislich etwa 30% schneller verstehen als solche mit Javas iterativen while-Schleifen.[4]http://www.scala-lang.org/node/3069

Scala DSLs

Nein, damit ist nicht der Breitbandanschluss gemeint, sondern DSL steht für Domain Specific Languages. Dieses Scala Feature ermöglicht es Software-Entwicklern eigene Sprachkonstrukte zu definieren, die sich nahtlos in die Programmiersprache eingliedern. Das vereinfacht die Enwicklung und verschafft auch Nicht-Programmierern die Möglichkeit, den Code zu verstehen. Im Folgenden ist ein Beispiel, wie Tests mithilfe der populären Library ScalaTest definiert werden können. Auffallend ist die sich selbst erklärende Syntax sowie die Prägnanz der Testfälle: Es sind keine Code-Bausteine nötig.

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class GoogleSearchSpec extends FlatSpec with ShouldMatchers with HtmlUnit {
 
  "The blog app home page" should "have the correct title" in {
    go to (host + "index.html")
    title should be ("Awesome Blog")
  }
  "The search page" should "have ten results" in {
    click on "searchbox"
    textField("searchbox").value = "Scala"
    submit()
    findAll(className("result")).size should be (10)
    capture to "search.png"
  }
}

In Java hingegen sind durch die Programmiersprache klare Grenzen gesetzt, solche Konstrukte lassen sich da nicht realisieren. Im Gegensatz zu den entsprechenden Testfällen in JUnit kommen die ScalaTest-Fälle mit deutlich weniger Code aus. Auf den direkten Vergleich mit JUnit werde ich in diesem Fall verzichten, denn dann wäre dieser Post mit Bildschirm füllenden Code-Bausteinen überladen.

Traits: Interfaces on Steroids

Oberflächlich gesehen entsprechen Scalas Traits den Interfaces aus Java; mit einem wichtigen Unterschied: Traits können Methoden nicht nur deklarieren, sondern auch bereits implementierte Methoden beinhalten.

“Das ist ja nichts Anderes als eine abstrakte Klasse!”, wird sich der mit Java erfahrene Leser nun vielleicht denken. Das stimmt so allerdings nicht. Während eine Klasse in Java lediglich von einer einzigen anderen (abstrakten) Klasse erben kann, können Klassen in Scala beliebig viele Traits einbinden. Das ist praktisch, weil dadurch die Implementierungen von mehrfach verwendeten Methoden an einem einzigen Ort (dem Trait) auftauchen, und nicht über verschiedene Klassen redundant verteilt werden müssen. Beispiel:

Scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// eine Klasse, die einen Bruch darstellt und Operatoren
// zum Vergleich mit anderen Brüchen bereitstellt
class Rational(n: Int, d: Int) {
  // numer ist der Zähler, denom der Nenner
  // ...
  def < (that: Rational) =
    this.numer * that.denom > that.numer * this.denom
  def > (that: Rational) = that < this
  def <= (that: Rational) = (this < that) || (this == that)
  def >= (that: Rational) = (this > that) || (this == that)
}
 
// Vereinfachung mithilfe des Ordered Traits: die Methoden
// "<", ">", "<=" und ">=" werden vom Trait implementiert
class Rational(n: Int, d: Int) extends Ordered[Rational] {
  // ...
  def compare(that: Rational) =
    (this.numer * that.denom) - (that.numer * this.denom)
}

In Java hingegen ist es nicht möglich in einem Interface Methoden zu implementieren.

Heute setzen bereits Twitter, Foursquare und LinkedIn auf Scala. Nach Daten von indeed.com, ist die Nachfrage nach Scala-Entwicklern seit 2010 rapide gestiegen. Es lohnt sich also diese Programmiersprache im Auge zu behalten.

Notes   [ + ]

1. ↑ im Dezember 2012 war sie nur auf Platz 34 des TIOBE Index, mit 0,32% im Vergleich zu Java auf Platz 2 mit 17,57%
2, 4. ↑ http://www.scala-lang.org/node/3069
3. ↑ mehr zu dem Thema hier: http://www.scala-lang.org/node/111

Filed Under: German Tagged With: java, jvm, scala

Wednesday, 12. December 2012 by Mark Goldenstein Leave a Comment

git – warum ich nur noch ungern Subversion nutze

Als ich zum ersten Mal auf das Thema Versionsmanagement gestoßen bin, hat die ganze Welt CVS genutzt. Zu dem Zeitpunkt hatte ich es mir kurz angeschaut und mir war sofort klar, dass CVS kein geeignetes Tool für mich ist. Bereits die Tatsache, dass die Versionsgeschichte lediglich auf Basis von einzelnen Dateien getracked wurde und es somit nicht möglich war Änderungen in mehreren unterschiedlichen Dateien als atomaren Commit zu speichern war für mich ein Dealbreaker. Enttäuscht wandte ich mich wieder ab.

Einige Zeit später, als ich kurz vor dem Abitur mit mehreren Mitschülern eine umfangreiche Webanwendung entwickelt habe, wurde das Thema wieder aktuell. Ich entdeckte Subversion, ein Fork von CVS, der alle wichtigen Schwachpunkte auszumerzen schien. Und lange Zeit habe ich nichts Anderes mehr benutzt. Heute sehe ich insbesondere an der Uni, dass Subversion sich offenbar durchgesetzt hat, denn viele Studenten kennen gar nichts Anderes! Aber auch in vielen Unternehmen, wo häufig zentralisierte Strukturen vorherrschen, ist es mittlerweile zum Standard geworden. (Mit Ausnahme natürlich von solchen Unternehmen, die ausschließlich auf proprietäre Microsoft-Produkte wie – Gott bewahre! – Team Foundation Server o.ä. setzen.) In der Open Source Gemeinde hingegen hat ein anderes Tool zunehmende Beliebtheit erlangt: git.

Für mich entdeckt habe ich es vor etwa zwei Jahren, als ich für einen Kunden eine Website mit Hilfe des Symphony CMS entwickelt habe. Das Projekt hat eine kleine, aber eng zusammen arbeitende Community, die fleißig Plugins und Erweiterungen programmiert und diese auf GitHub veröffentlicht. So bin ich auf git gestoßen und neugierig wie ich bin habe ich es mir gleich genauer angeschaut – und seitdem könnte ich nicht mehr darauf verzichten!

In meinen weiteren Ausführungen setze ich voraus, dass du, werter Leser, bereits mit Versionsmanagement-Tools und insbesondere mit SVN vertraut bist. Ich werde davon ausgehend erläutern welche Vorteile git für den Workflow bietet und wie es dadurch zu einer Steigerung der Produktivität führen kann.

Zunächst ist der auffälligste Unterschied, dass git im Gegensatz zu SVN ein verteiltes Versionsverwaltungssystem ist: Es gibt keinen zentralen Server, jeder Nutzer besitzt eine vollständige Version des Repositorys. Dies führt zum einem dazu, dass die meisten Operationen ohne Internetverbindung möglich sind, zum anderen dazu, dass es immer mehrere Backups (entsprechend der Anzahl Nutzer) des Repositorys gibt – ein Ausfall des Servers ist also selbst falls dieser nicht regelmäßig gesichert wird leicht zu verschmerzen. Häufig genutzte Operationen wie Vergleiche zwischen verschiedenen Datei- und Repository-Versionen, die Erstellung von Branches sowie das lokale Speichern von Commits erfolgen sehr schnell und ohne der Notwendigkeit einer Internetverbindung.

Ein weiteres Feature von git sind lokale Commits. Diese haben sich in meiner Erfahrung als äußerst praktisch erwiesen. Bei der Entwicklung einer umfangreichen Projektkomponente will ich zwar regelmäßig meine Änderungen speichern, sodass ich bei dem Auftreten eines Bugs zu einer früheren Version zurückkehren kann. Gleichzeitig will ich meine Änderungen aber noch nicht mit anderen Team-Mitgliedern teilen, wenn sie noch nicht einen bestimmten Reifegrad erreicht haben. Dieser Workflow ist mit git Standard, Commits erfolgen zunächst lokal und müssen zur Veröffentlichung auf den Server gepushed werden. Zur besseren Dokumentation kann man die Commits vor dem Pushen mithilfe von git rebase sogar neu organisieren und mit besseren Kommentaren versehen. Dagegen tendieren SVN-Nutzer dazu, jede einzelne lokale Änderung gleich auf den zentralen Server zu commiten, sodass die History mit unnötigen Commits aufgeblasen wird und es erschwert wird sich einen Überblick über den Entwicklungsverlauf zu verschaffen. Lokale Commits sind bei SVN gänzlich unmöglich.

Das nächste große Plus von git sind die oben erwähnten Branches. In git ist es üblich, bei der Arbeit an einem neuen Feature sogenannte feature branches zu verwenden. Diese Vorgehensweise erleichtert es, alle zu der Arbeit an einem bestimmten Feature oder zu einem bestimmten Bug gehörenden Commits nachzuverfolgen. Das Erstellen einer neuen Branch ist eine simple lokale Operation: git checkout -b bug-1337. Bei SVN hingegen würde die gleiche Operation folgendermaßen aussehen: svn copy http://meinwebserver.de/svn/projekt/trunk http://url-zum-repository.de/svn/projekt/branches/bug-1337 -m "Neue Branch für Bug 1337"; svn switch ^/branches/bug-1337. Schon die Länge des Befehls lässt erahnen, warum Branches bei SVN selten benutzt werden. Zugleich sind Branches nur sinnvoll, wenn mächtige merge-Werkzeuge zu Verfügung stehen. Dies ist bei git der Fall; bei SVN hingegen ist ein Merge oft ein langwieriges und schmerzvolles Unterfangen. Warum das so ist, ist schnell erklärt: Während bei git gespeichert wird, von welcher Revision ein Branch abstammt bzw. welche Revisions eigentlich gemerged wurden, war dies bei SVN bis vor kurzem nicht der Fall. Mit SVN 1.5 wurde diese Funktionalität zwar eingeführt, aber soweit ich weiß ist das bisher nur rudimentär implementiert. So gibt es insbesondere Probleme mit Merges von umbenannten Dateien, die bei git nicht auftreten.

Ebenfalls ein Feature das ich oft verwende ist git stash: Wenn ich angefangen habe an etwas zu arbeiten und plötzlich ein wichtiger Hotfix ansteht, hilft dieser Befehl aus der Klemme: Alle Änderungen, die noch nicht committed wurden, werden vorübergehend gespeichert und die Working Copy wird auf den Stand des letzten Commits zurückgesetzt. Sobald der Hotfix fertig ist und ich wieder zu der ursprünglichen Arbeit zurückkehren will, kann ich mit git stash pop die zuvor gemachten Änderungen wieder in meine Working Copy mergen und an der Stelle weitermachen wo ich zuvor aufgehört hatte. Bei SVN hingegen ist dies nicht möglich; und weil es bei SVN auch keine lokalen Commits gibt, bleibt in diesem Fall eigentlich nur noch die Möglichkeit eines manuellen Backups der einzelnen Dateien und dem anschließenden Revert der Änderungen. Oder aber man erstellt auf dem Server eine neue Branch und committed die unfertigen Änderungen dorthin. Beides sind sehr umständliche und nicht zufrieden stellende Workflows.

Damit komme ich zum Ende dieses Beitrags. Zwar habe ich nur einen sehr kurzen Überblick über die Vorteile von git gegenüber SVN verschafft, aber ich hoffe, dass ich trotzdem das Interesse für git wecken konnte. Eine kleine Einführung findet man auf der offiziellen Website, einen umfassenderen Vergleich zwischen git und SVN gibt es hier. Und schließlich möchte ich noch folgenden Workflow empfehlen: git flow.

Filed Under: German Tagged With: cvs, git, subversion, svn, tfs, vcs

Thursday, 29. November 2012 by Mark Goldenstein Leave a Comment

Bring your own device – die Flexibilisierung des Arbeitsplatzes

Vor rund zwei Jahren habe ich im Auftrag von T-Systems ein White Paper unter dem Titel Mobile Enterprise verfasst. Und heute habe ich auf neuerdings.com einen Post zum gleichen Thema gesehen. Eine Gelegenheit meine damaligen Erkenntnisse zu rekapitulieren.

Key Facts:

  • Im Zuge der Globalisierung steigt die Zahl der mobilen Mitarbeiter rasant.
  • Der technologische Fortschritt ermöglicht es heute, mit mobilen Geräten wie einem Tablet oder auch schon einem Smartphone produktiv zu arbeiten. Allerdings hinkt die geschäftliche Nutzung der privaten Nutzung solcher Geräten stark hinterher.
  • Der demographische Umbruch, der Fachkräftemangel sowie eine neue Generation von sogenannten “Digital Natives” führen dazu, dass heute zunehmend Unternehmen um neue Mitarbeiter werben müssen – und nicht mehr Mitarbeiter um Unternehmen.
  • Diese neue Generation von jungen Menschen erwartet von ihren Arbeitgebern, Trends aus dem Konsumentenbereich zu übernehmen und in die Arbeitsumgebung zu integrieren.
  • Viele Unternehmen können diese Erwartungen bislang nicht erfüllen, sondern setzen weiterhin auf rigide Lösungen aus der Unternehmenswelt, im Smartphone-Bereich z.B. RIMs BlackBerry, anstatt die Integration von weiteren mobilen Betriebssystemen wie Android oder iOS voranzutreiben.
  • Gleichzeitig stellt der Trend zur Consumerization die Unternehmen vor neue Herausforderungen: Wie lässt sich eine gute Service-Qualität sowie strikte Anforderungen an IT-Sicherheit in einer wechselhaften und undurchgängigen IT-Landschaft durchsetzen?

Mittelfristig werden Unternehmen meiner Meinung nach nicht daran vorbeikommen ihre Mobilitäts-Strategie zu überarbeiten. Einerseits verschmelzen Privat- und Geschäftsleben, Unternehmen erwarten von ihren Mitarbeitern auch außerhalb der üblichen Arbeitszeiten erreichbar zu sein. Andererseits wollen Mitarbeiter nicht mehr unterschiedliche Systeme im Privat- und Geschäftsumfeld verwenden, sondern setzen auf eine Konsolidierung ihrer IT-Landschaft. Die Zeit in der ein Mitarbeiter stets mehrere gleichartige Geräte mit sich führt – beispielsweise ein BlackBerry für Geschäftszwecke und ein iPhone für private Anwendungen, oder mehrere Notebooks – geht zu Ende. Mobilität bedeutet heute auch, dass die Geräte immer kleiner und Redundanzen eliminiert werden.

Eine strikte Trennung des Privaten und Beruflichen sowie der Einsatz von streng kontrollierten IT-Landschaften wie es bisher oft gehandhabt wurde wird meines Erachtens lediglich in extrem sicherheitssensitiven Bereichen wie dem Militär Bestand haben. In allen anderen Bereichen werden Unternehmen auf die neuen Erwartungen ihrer Mitarbeiter eingehen müssen.

Filed Under: German Tagged With: digital natives, mobilität, mobility, smartphone, t-systems, tablet, white paper

Primary Sidebar

Categories

  • English
  • German

Recent Posts

  • Spotify and others use an unfair formula to pay artists
  • Building a Websocket client to btcwallet using Scala and akka
  • Complex Event Processing: Language-level integration into Scala
  • 2nd Next Generation Forum Roundup
  • Präsentation 2.0 – es muss nicht immer PowerPoint sein

Recent Comments

  • Mark Goldenstein on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka
  • Mark Goldenstein on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka
  • Julio on Building a Websocket client to btcwallet using Scala and akka

Copyright © 2021 · Executive Pro on Genesis Framework · WordPress · Log in