await!

Bisher habe ich um das async/await Pattern in C# eher einen Bogen gemacht. Grundsätzlich war mir mehr oder weniger klar, was da vor sich geht, aber wozu syntaktischer Zucker, wenn es auch so geht? Es sieht schöner aus. Zumindest für diejenigen, die “Schönheit” für uns festlegen. Aber inzwischen trifft man auf Konstellationen, in denen man gar nicht mehr drumherum kommt, z.B. wenn eine Bibliothek, die man verwenden möchte nur noch LalaBlaBlubAsync(...) Aufrufe hat, wobei die Vorversion noch mit LalaBlaBlub(...) auskam. Tja.

Ich wollte dann doch mal etwas tiefer gehen und stieß auf diesen interessanten Artikel (Achtung MSDN Link). Ich finde, das Konzept wird hier wirklich schön erklärt. Das Beste daran ist jedoch dieses herrliche Zitat:

“Asynchronous code reminds me of the story of a fellow who mentioned that the world was suspended in space and was immediately challenged by an elderly lady claiming that the world rested on the back of a giant turtle. When the man enquired what the turtle was standing on, the lady replied, “You’re very clever, young man, but it’s turtles all the way down!”

Better late than never!

errorMode Custom

Hier eine kleine Anmerkung zu einem kleinen Ärgernis, AKA ungooglebarer Fehler:

Man betreibt man eine Site oder einen Webservice mit dem IIS (Version 7 in meinem Fall) möchte man in seltenen Fällen im Code explizit den StatusCode setzen. Das kann z.B. so aussehen:

WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.ServiceUnavailable;

Diese Zeile führt dazu, dass der Aufrufer 503 Busy zurückerhält. Neulich hatte ich die Situation, dass der Client stattdessen immer 500 bekam und die betr. Zeile ignoriert wurde. Weshalb? Es war zum Verrücktwerden. Offensichtlich war folgender Abschnitt in der web.config dafür verantwortlich:

<system.webServer>
<httpErrors errorMode="Custom" />
<system.webServer>

Heart failure

Gestern habe ich die OpenSSL Lib in unserer iOS App gepatcht. Die verwendete Version hatte den Heartbleed.

Am Tag 2 fragen sich jetzt alle wie das nur sein kann, daß so ein eklatanter Bug jahrelang unentdeckt in einer Open Source Software versteckt bleibt. Und .. ogott jaaa.. wer den wohl schon alles für seine finsteren Machenschaften ausgenutzt hat?!

Open Source muss doch sicher sein, es ist offener Quellcode, jeder kann reinschauen und damit sollten Fehler doch sofort entdeckt werden! Das klappt aber nur dann wenn es eine kritische Masse Leute gibt, die das auch tun und die verstehen, was sie dort vorfinden. Und das ist im Fall von OpenSSL sicherlich nicht so ganz leicht. Jeder der diese Lib schon verwendet hat weiß, wie gräßlich kompliziert das Ding ist. Und ich spreche hier nur von der korrekten Verwendung, vom Griff in den Code selbst ist das meilenweit entfernt. Das ist auch, was man z.B. bei Fefe lesen kann. Der sich selbst nicht zutraut, das Ding zu auditieren, weil, tja, einfach zu kompliziert das Ganze. Lieber selbst schreiben(!). Ich nehme zwar an, daß das ironisch gemeint war aber das ist eher einer der Cracker auf dem Gebiet.

Ich stelle dasselbe Phänomen auch bei uns fest: Je komplizierter ein Code-Komponente aufgebaut ist, desto länger halten sich darin die haarsträubendsten Fehler. Sitzen einem direkt vor der Nase, aber man kann sie nicht erkennen, weil man vor lauter Bäumen den Wald nicht sieht. Aus diesem Grund kann ich immer wieder nur eins meiner Dauer-Mantras wiederholen. Warum einfach, wenns auch kompliziert geht! Ne halt, das war jetzt nicht ganz richtig..

Wer wissen will wie Heartbleed funktioniert klickt einfach mal hier.

Codekicker: Was gut ist muss auch teuer sein?

Seit den Anfängen bin ich Fan und Mitglied von stackoverflow. Das ist eine Webseite, auf der Entwickler ihre Fragen loswerden können, die dann von anderen Entwicklern und Fachleuten beantwortet werden. Dafür bekommen sowohl Fragesteller als auch Beantworter Punkte, sogenanntes Karma. Das Karma vergibt nicht die Administration, sondern die anderen Benutzer, die ihre Stimme abgeben können, wenn ihnen eine Frage oder Antwort besonders gut gefällt. Für eine falsche Antwort oder eine nicht fachlich passende Frage kann sogar Karma abgezogen werden. Und weil die Menschen so fürchterlich angeben, wie toll sie sind funktioniert das Ganze ausgezeichnet. Stellt man eine Frage stürzen sich sogleich zig eifrige Karmajäger drauf und fabrizieren mehr oder weniger sinnvolle Antworten. Das Ganze kostet nichts – die Betreiber leben allein von der hohen Besucherzahl von ausgewiesenen Profis des Fachs und den dabei dezent (und vermutlich ziemlich teuer) geschalteten Anzeigen. Stackoverflow ist wirklich der Fundus bei Schwierigkeiten rund um die Entwicklung. Unsere firmeneigene iOS Anwendung hätte ohne diese Site eine zig-mal höhere Entwicklungszeit benötigt.

Benutzerprofil von puls200Seit ein paar Wochen gibt es jetzt den (wohl unvermeidlichen) Klon auf deutsch: Das Ganze nennt sich codekicker (wer hat sich nur den Namen ausgedacht?) und verfolgt genau dasselbe Geschäftsmodell. Dabei wurde sogar das Layout fast 1:1 übernommen, wer stackoverflow kennt fragt sich wo eigentlich die Unterschiede sind. Ich habe mich angemeldet und seit ein paar Tagen fröhlich mitgepostet. Das geht noch ganz gut, da die Menge der Teilnehmer noch etwas überschaubar ist. Mein erstes Fazit:

  1. Sehr .NET-lastig, kaum Fragen zu Java, Webentwicklung und Mobilem
  2. Wie bei stackoverflow gibt es die unvermeidlichen Dauer-Antworter, die zu jeder Frage ihren mehr oder weniger qualitativ wertigen Senf abgeben und das Karma horten
  3. Das Niveau der Fragen ist nicht besonders hoch. Ich vermute, dass diejenigen dann eher bei stackoverflow posten, des Englischen ohnehin besser mächtig
  4. Einige sinnvolle Features von stackoverflow wurden kurioserweise weggelassen, z.B. die Moderation und Überarbeitung von Fragen, die Acceptance-Rate, usw.
  5. Der speziell in deutschen Foren oft anzutreffende rechthaberische Ton ist gottseidank nur sehr selten zu vernehmen

Ich denke wenn sich die Gefolgschaft von dotNetPro geschlossen anmeldet besteht eine konkrete Überlebenschance. Ich werde die Site definitiv noch eine Weile aktiv begleiten.

Kleiner Test

Nachdem ich herausgefunden habe, dass in der Welt der Webprogrammierung seit Jahren tolle Sachen passieren ohne dass ich etwas davon mitbekomme habe ich beschlossen, mich ein bisschen kundig zu machen. Ein Kollege macht interessante Dinge mit html5 und jquery, das gefiel mir. Nachdem ich Raphael entdeckt habe, eine vielversprechende Bibliothek für Zeichnen in 2D musste ein kleiner Test sein. Hier gehts hin, ein Aufguß von Conway’s Game of Life. Ich gebe es ja zu, noch was altbackeneres hätte ich kaum aus dem Hut zaubern können, aber der Programmieraufwand sollte sich in Grenzen halten. Wir kennen sie, die sympathischen Blinker ;-)
Interessant war in diesem Zusammenhang die deutlich unterschiedliche Performance auf verschiedenen Browsertypen. Speziell wenn ein Objekt semi-transparent wird habe ich den Eindruck findet im Firefox ein Software-Rendering statt, denn dann bricht die Leistung komplett ein. Im IE ist es zwar besser aber weit entfernt von akzeptabel. Hier fehlt m.E. der Anschluß an die Hardware der Plattform. Oder ich bin nur einfach zu blöd die richtigen Einstellungen zu finden ;-)
Ich werde das Skript demnächst noch ein bisschen erweitern, so dass man die wichtigsten Optionen einstellen kann.

Ich werd langsam zu alt für so einen Mist ;-)

Ich schreibe hier nicht gern von meiner Arbeit. Mich versteht ja doch keiner. Aber manchmal ist es einfach zu schrill. Heute zum Beispiel fand ich einen wunderbaren Fehler leider erst nach über zwei Stunden. iPad Anwendung. Folgende Situation:
Ich habe ein UIView, das mit einer bestimmten Größe initialisiert wird. In dieses View werden im Nachhinein dynamisch Subviews und Controls hinzugefügt. Das View ist in einem SplitviewController eingebettet.
Damit das Ganze schön skaliert habe ich außerdem folgendes gemacht:

searchView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
searchView.autoresizesSubviews = YES;

und danach die Subviews hinzugefügt. Wenn man die Anwendung startet sieht optisch alles gut aus, die Controls sind am richtigen Fleck. Aber das Event-Handling funktionierte nicht mehr. Ich habe wirklich alles ausprobiert, bis ich testweise einen Button hinzugefügt habe. Dabei fiel mir auf, dass die Events doch ausgelöst wurden .. allerdings nur in einem sehr schmalen Streifen am oberen Ende des Button. Gottseidank habe ich überall rumgeklickt ;-) Danach habe ich das Flag UIViewAutoresizingFlexibleHeight weggelassen und siehe da, alles funktioniert wie erwartet. Wie es scheint, wird der View tatsächlich flexibel skaliert, seine Kind-Elemente jedoch nicht. Skaliert wird nur der Bereich in dem Events ausgewertet werden. Wir haben also zwei Views, eins mit den tatsächlichen Controls und eins mit den Grenzen des Event-Handlings. Die andere Erklärung ist die, dass Kind-Elemente einfach aus ihrem Parent herausragen können. Was auch immer passiert war, es war nicht auf Anhieb zu erkennen. Eher so auf Siebt- oder Achthieb.
Was lernen wir daraus?
– Öfter einchecken um funktionsfähige von kaputten Sourcecodeteilen besser unterscheiden zu können
– sich von der Annahme verabschieden, alles müßte so funktionieren wie man es sich gedacht hat
– manuelles Resizing muss in allen Ebenen der Viewhierarchie implementiert werden damit es zuverlässig funktioniert
– es ist verblüffend wieviel Zeit man in API-Spezialskills investieren muss, die man hinterher auf keiner anderen Plattform mehr gebrauchen kann

iPhone und Apple

In meinem “offiziellen” Job bin ich nun seit 8 Wochen (mit einigen Unterbrechungen) mit Softwareentwicklung für das iPhone beschäftigt. An dieser Stelle möchte ich kurz meine bisherigen Erfahrungen resümieren. Vorausschickend noch anzumerken ist, daß sich vieles wie Meckerei anhört. Das sollte nicht so sein. Ich bin dem Apple-Virus nicht anheim gefallen, verwende die Geräte privat nicht und habe daher einen neutralen Standpunkt. Es geht nicht darum, ob iPhones cool oder praktisch sind. Eher, was passiert wenn man dafür Software entwickelt.

iPhone Entwicklung – lohnt sich das denn?
Die Frage aller Fragen. Angesichts der unüberschaubaren Flut an Apps im Apple Store kann das Gefühl entstehen, daß dieser Markt komplett gesättigt ist. Das stimmt allerdings nicht, denn es werden immer noch Neugeräte (und damit Apps) verkauft. Allerdings – um “entdeckt” zu werden muß man entweder kostenlos (Blödsinn, wir wollen Geld verdienen) oder sehr gut sein. Wer früh kommt, verdient allerdings auch mit simpelsten Anwendungen Geld. Inzwischen geht das aus meiner Sicht für den Apple-Store / Consumermarkt nur dann, wenn es nur wenig Konkurrenz für die “Idee” gibt. Man muss berücksichtigen: Wenn man, sagen wir, in 2 Wochen eine sehr einfache App entwickelt (ganz optimistisch gerechnet) bei einem hiesigen, sehr konservativen Tagessatz von 500€ und noch die Hardwareeinstiegskosten (iMac Mini + iPod = 1.000€) + 100€ Entwicklerlizenz dazunimmt, liegt man bei einer initialen Investition von 6.100 €. Setzt man 1€ an muss die App 8.714-mal heruntergeladen werden (Apple Steuer: 30%), bevor man den break even erreicht. Ab diesem Zeitpunkt verdient man Geld. Aber nicht vergessen: Das ist der Consumer-Markt. Man ist zum Support verpflichtet. Bekommt man von nur einem Promille aller Anwender eine E-Mail (ganz dolle optimistisch), muß man bis zu diesem Punkt schon 8 Supportanfragen bearbeiten. Oh, lala. “Läuft” es einmal, wird die Anwendung in der Regel sehr schnell gecrackt und Plagiate tauchen auf, wie Kollegen von mir schon erfahren haben. Die Verkaufskurve zeigt dann unwillkührlich wieder nach unten. Ein großer Vorteil soll natürlich nicht verschwiegen werden. Als Entwickler im stillen Kämmerlein hat man mit dem AppStore eine fantastische Vertriebskette zur Verfügung. Die Kunden müssen nicht mehr gefunden oder geworben werden. Falls, tja, falls sie einen innerhalb der derzeit rund 200.000 angebotenen Apps selbst finden. :-)
Jetzt entwickeln wir nicht für den Consumer-Markt. Wir haben Geschäftskunden, die Masse ist nicht entscheidend. Allerdings bleibt die Gerätevielfalt dieselbe. Zur Anwendungsentwicklung auf einem Endgerät existiert eine preiswerte Alternative, und zwar die Implementierung einer für mobile Geräte optimierten Webseite. In vielen Fällen müssen ohnehin online auf Geschäftsdaten zugegriffen werden, eine Internetverbindung ist also erforderlich. Und ob HTC/Android, Berry oder iPhone, es läuft überall (mehr oder weniger ansehnlich) gleich. Im Funkloch tut sich dann nichts mehr, aber das ist dann vom Anwendungsfall abhängig. Man prüfe also, ob man sich das antun will ;)

Restriktionen
In der Apple-Welt lebt man auf einer Insel. Das ganze System ist darauf ausgelegt, dass der Anwender und der Entwickler ausschließlich Apple-Komponenten verwenden. Das fängt schon bei Kleinigkeiten an, wie dem Anschluß einer herkömmlichen PC Tastatur an einem Mac mini. Oder die Darstellung der Apple-Dokumentation in anderen Browsern außer Safari. Oder der Verbindung zu Windows Shares im Finder. Lauter kleine Ärgernisse, die man zwar irgendwann durch Googelei lösbar sind, aber trotzdem nerven, weil es sich um bewußt ausgelegte Stolpersteine handelt. Wer will sich schon gern die Arbeitsweise vorschreiben lassen. Ganz extrem ist natürlich dann die Entwicklungsumgebung fürs iPhone, ausschließlich mit XCode auf einem Mac Betriebssystem. Das hat keine technischen Gründe. Besonders zynisch dabei ist aus meiner Sicht, daß die darunterliegenden Komponenten aus der Unix-Welt stammen und wie der GCC beispielsweise der GPL unterliegen. Alles sicherlich rechtens, komisch riechen tut es trotzdem.

Entwicklung
Wie entwickelt man denn nun? XCode entpuppt sich als vollwertige und moderne Entwicklungsumgebung. In der Produktivität bleibt das Programm trotzdem meilenweit hinter Visual Studio zurück, was an dem umständlichen Debugger und am Fehlen von Funktionen wie “Edit & Continue” und der etwas zähen Intellisense Unterstützung liegt. Objective-C hätte ich mir schlimmer vorgestellt, ich habe mich trotz meines etwas vorgerückten Alters relativ schnell damit zurechtgefunden. Aber die Bibliotheksfunktionen! Immer wieder herrlich, wenn man selbst primitive Dinge wie das Zusammenfügen von Strings in der Doku nachschlagen darf, nur weil man den Funktionsnamen wieder vergessen hat. Man merkt auch, daß die Programmiersprache nur auf C übergestülpt ist. Probleme wie die Korruption des Speichers oder Stacks, Zugriff auf de-allokierte Objekte und ähnliche Schweinereien die ich schon ziemlich verdrängt hatte sind wieder an der Tagesordnung. Mit den damit verbundenen Programmabstürzen. Es ist problemlos möglich, eine Maske im Interface Builder so zu konfigurieren, daß das Programm an einer vollständig irreführenden Stelle einfriert. Nicht falsch verstehen. Das ist alles lösbar, nur würde man seine Zeit gern für andere Dinge verwenden. Im Grunde wird man ständig daran erinnert, daß man nicht wiederverwendbare Fähigkeiten für eine Insellösung aufbaut. So könnte man natürlich auch bei .NET, Java und ähnlichem argumentieren, nur sind die Inseln dort eher.. Kontinente.

Lernen
Wie ein guter Student habe ich mir zunächst ein Buch bestellt. “iPhone SDK Application Development” von Jonathan Zdziarski. Ein ehemaliger iPhone Hacker, ich dachte, das ist ganz sinnvoll. Leider erfüllte es nicht ganz meine Erwartungen. Die API hat sich inzwischen etwas verändert, so daß viele Beispiele etwas veraltet sind. An vielen Stellen hätte ich mir auch etwas mehr Tiefe gewünscht, dafür dann evtl. andere Bereiche wie Audio weggelassen. Auch der Index hilft nur begrenzt bei Problemen. Ein Buch im Sinne eines “Cookbook”, wie es für viele anderen Sprachen gibt ist sicherlich sinnvoller für den Einsteiger. Für Detailfragen muß man ohnehin auf Google zurückgreifen. Ich frage mich inzwischen ernsthaft, ob Bücher in dieser Form überhaupt noch einen praktischen Nutzen haben, außer auf der Biographie des Autors einen äußerst positiven Eindruck zu hinterlassen. (SterneSterneSterneSterneSterne).

Hack!! Arrrgh

Womit man so seinen Nachmittag verbringen kann. Alles fing damit an, daß der GeoURL Button unten rechts nicht mehr funktionierte. Die Tags waren drin, also an was konnte es liegen? Der GeoURL Support schlug vor, doch mal den W3 Validator auszuprobieren. Hä? Ich verwende doch Software von der Stange, aber warum nicht.. und siehe da, der Validator sagt, er könne mit Content-Type null nichts anfangen. Ich schaue in den Header des Themes, der Content-Type wird explizit gesetzt, genauso wie im Quellcode der Seite. Doch irgendwas ist komisch mit dem header.php..
Dann sehe ich es: In der ersten Zeile steht was völlig merkwürdiges:

<?php /**/eval(base64_decode(‘aWYoZnVuY3Rpb25 …

Etwas primitive Tarnung, das Skript (ziemlich obfuscated) in einem Base64 String. Das wiederum rief ein in einem entlegen Winkel meiner Webseite plaziertes Skript auf, das wiederum eine 100kb Datei dekodierte und dann evaluierte. Was das genau tut habe ich noch nicht herausgefunden. Eins jedenfalls hat die Infektion geschafft: Alle meine PHP Seiten waren damit infiziert (.php5 Seiten aber nicht!) Das hatte anscheinend nichts mit WordPress zu tun. Dem Änderungsdatum zufolge war das bereits vor einem halben Jahr geschehen. Ich hatte nichts bemerkt!
Wie das ganze hereingekommen ist weiß ich leider noch nicht. Ich vermute, daß es an der sehr alten WordPress-Version vom Blauen Heft liegt, speziell den dort verwendeten Javascript Editor (in dessen Unterverzeichnis das “Mutter-Skript” untergebracht war).
Ich mußte das natürlich zum Anlaß nehmen beide Blogs auf WordPress 3.0 anzuheben, alle anderen PHP Skripte manuell zu bearbeiten und mal wieder kräftig aufzuräumen. Aufräumen ist ja immer eine super Sache. Man muß es nur ab und zu tun. Danach funktionierte auch der GeoURL Knopf wieder.

Zusammenfassung:

  • Ab und zu in den PHP Quellcode schauen
  • Regelmäßige Backups der Files und Datenbank
  • Nie alte Versionen herumliegen lassen

Links dazu aus dem Web, hier und hier. Peinlich wenn man sich anschaut wie alt das schon ist..

Denglish for Programmers

In vielen Software-Firmen gibt es die Anweisung, daß Variablennamen, Kommentare und ähnliche Dinge in der Software auf Englisch verfaßt sein müssen. Bei uns beispielsweise auch. Warum eigentlich? Um den Chinesen die Einarbeitungszeit nach der Raubkopie zu verkürzen? Ich persönlich bin der Ansicht, daß diese Regel eher kontraproduktiv ist. Vor allem deshalb, weil die wenigsten Entwickler in meinem Kollegenkreis über die notwendige Fähigkeit verfügen, verständliche Kommentare zu setzen. Oft gleichen die Einträge dann Wort-für-Wort Übersetzungen aus Leo. Das hat schließlich einige dazu getrieben, einen Art Sprach-Kompromiß einzugehen. Hier eine Perle, die ich heute entdeckt habe:

private const string pleaseChoiseALiefernachweisText = "textSelectLiefernachweis";

Yeah! Ich soll bitte einen Liefernachweis wählen, äh, ich meine natürlich choisen. Muahaha. Also, das ganze ist wirklich völliger Quark. Setzt die Kommentare doch so, daß diejenigen sie verstehen, für die sie gedacht sind. Genau, die Kollegen. Die meisten von denen verstehen zwar auch denglisch, nur besteht immer das Risiko eines Mißverständnisses. Ich für meinen Teil habe von jeher diese Arbeitsanweisung ignoriert.

Daily WTF

Die Überschrift habe ich hier geklaut. Inzwischen ist es so daß das Monster, welches ich schon seit Jahren betreue, der meisten Schauerlichkeiten beraubt wurde. Aber hin und wieder tauchen einzelne Perlen auf, so wie das hier:

public bool Enthalten
{
     get { return !this.entity.Enthalten.Value; }
     set
          {
            if (!this.entity.Context.IsChangeTrackingEnabled)
                   this.entity.Context.EnableChangeTracking(true);
            this.entity.Enthalten.Value = !value;
          }
}

Die entsprechende Datenspalte trug übrigens den bedeutungsschwangeren Namen “Nicht“. Nicht was? Nicht geglückt? Nicht rechtzeitig ins Bett gekommen? Wir werden es nie erfahren.