Git on Windows

December 8, 2010

Gibts hier eigentlich Leser die Git unter Windows verwenden? Ich wollte unser angestaubtes Trac & Subversion diese Woche gegen Redmine & Git tauschen, der Server sollte unter Ubuntu 10.10 laufen. Kommunikation über SSH mit Key-Authentifizierung. Den Team Foundation Server nehmen wir nicht weil wir gelegentlich auch unter Mac OS X entwickeln, teilweise haben wir auch noch Altprojekte in Python unter Linux/Eclipse.

Auf den Windows Clients sollte msysgit und TortoiseGit laufen. Allerdings habe ich den Eindruck das der Client unter Windows noch nicht ausgegoren ist, zumindet wenn es darum geht Änderungen wieder auf den Linux Server zu pushen/pullen. Egal ob ich Putty oder OpenSSH als SSH Client verwendet habe, es war immer relativ langsam in der Key-Authentifizierung und die Fehlermeldungen von Git & Tortoise ergaben oft keinen Sinn.Zudem gab es Probleme mit den PATH-variablen unter Ubuntu bei der SSH Anmeldung, das kann aber Ubuntu spezifisch sein.

Ich überlege jetzt erstmal Subversion & Redmine zu verwenden und - vielleicht in 1-2 Jahren - dann nur das Repository auf Git umzustellen.

Wie macht ihr das denn?

 

Vielleicht kann ja der ein oder andere sowas gebrauchen?

 

using System.Globalization;

    /// <summary>
    /// Diese Klasse bietet Extension-Methods für DateTime Objekte
    /// </summary>
    public static class DateTimeExtensions
    {
        /// <summary>
        /// Liefert die letzte Kalenderwoche des jeweiligen Jahres zurück.
        /// </summary>
        /// <param name="date"></param>
        /// <returns>Die letzte Kalenderwoche des Jahres</returns>
        public static int GetLastCalendarWeekOfYear(this DateTime date)
        {
            GregorianCalendar cal = new GregorianCalendar(GregorianCalendarTypes.Localized);
            return cal.GetWeekOfYear(new DateTime(date.Year, 12, 31), CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        }
    }

Der Aufruf ist nach einbinden des Namespaces trivial:

// Wie viele Kalenderwochen hat das aktuelle Jahr?
int lastWeek = DateTime.Now.GetLastCalendarWeekOfYear();

// Wie viele KWs hatte 2009?
int lastWeek2009 = new DateTime(2009, 1, 1).GetLastCalendarWeekOfYear();

In meinem aktuellen Projekt hatte ich die Chance Event Based Components mal in der Praxis auszuprobieren. Ich arbeite nun 3 Tage daran und habe mich entschlossen abzubrechen und wieder auf eine klassische Komponenten-Orientierte Architektur zu setzen. Auf dem Papier und in kleinen Spielprojekten sah das ganze Konzept sehr gut aus. Die Modellierung wird Prozessorientierter, man kann sehr einfach Parallelisierung und Verteilung vornehmen da nicht mehr ein Call-Stack abgearbeitet wird sondern nur Messages durch die Gegend gesendet werden. Ich bin auch immer noch davon überzeugt dass sich das Konzept durchsetzen wird.

In der Praxis traten allerdings zahlreiche Probleme auf. Ich verwende ein WPF Frontend und meine Platinen (Ich habe Sie LogicBoards genannt) bzw. Komponenten müssen zur Laufzeit häufig mit dem Frontend kommunizieren. Nicht unmöglich - aber meiner Meinung nach später schlecht wartbar. Ich habe mir zu jedem Anwendungstask ein Prozessdiagramm erstellt, dann die nötigen EBCs geschrieben und auf den LogicBoards verdrahtet. Ich hätte aber keinem Kollegen zumuten wollen ohne die Diagramme den Code später zu warten. Immer wenn ich mehr als 6-7 "Bausteine" hatte wurde das ganze Event-Binding extrem schwer zu durchschauen. Nicht das wir uns falsch verstehen - es hat alles prima funktioniert, aber ich kam recht schnell an einen Punkt an dem die Kommunikation mit dem Frontend so komplex wurde dass es einfach nicht mehr übersichtlich war. Das Problem könnte man evtl. durch einen grafischen Editor erschlagen - aber ich habe leider keine Zeit einen zu schreiben.

Die Anwendung betreibt sehr viel Datenaggregation, liest aus verschiedenen Datenquellen diverse Informationen, zeigt Sie dem User und verarbeitet die Daten evtl. weiter. Die klassischen Komponenten der Anwendung in noch kleinere Software ICs mit In- und Out Pins aufzubrechen ist, zumindest für meine Anwendung, irgendwann "zu genau" weil ich hunderte ICs schreiben müsste um alle Anforderungen abzudecken. Sicher, ich muss jezt auch mindestens genau so viele Methoden schreiben - aber ich kann meine Anwendungsarchtiektur aus einer anderen Sichtweite planen. Bei EBCs bin ich gezwungen sehr detailiert im Vorfeld zu planen. Das mag für manche ein Vorteil sein, skaliert in einem Team aber auch nicht besonders gut weil viel doppelter Code entsteht.

Meine EBC Architekturplanung hätte niemals auf eine Serviette gepasst.

 

Media Center Hardware

July 16, 2010

Schon seit knapp 10 Jahren bastle ich mit Media Center Hardware rum. Ich wollte schon immer einen PC am Fernseher mit dem ich Sendungen aufnehmen, schneiden, ggf. auf DVD sichern sowie surfen kann. In den ersten Jahren gab es keine Software und Probleme mit der Hardware. ATI Karten hatten später einen guten TV-Out, irgendwann gab es mit "Show-Shifter" die erste MediaCenter Software für Windows, aber die CPUs waren nicht schnell genug für ein Realtime Encoding, DVB gab es noch nicht.

Ich bin auf einen Barebone umgestiegen, hab MediaPortal ausprobiert (zu frickelig, ohne schnelle Grafikkarte sehr langsam), TV Central (schlechter Support, umständliche Konfiguration) und so ziemlich alles was es sonst noch gab, später auf Windows MCE (Media Center Edition - schon ganz gut, aber es gab nur wenig Hardware die mit den nötigen BDA Treibern kam). Irgendwann hatte ich einen der ersten Windows Media Center Extender der mehr schlecht als recht lief (zu langsam beim spulen, Rechner musste laufen und nicht im Standby sein), irgendwann dann auch mal die XBox360 im Extender Modus (zu laut, gleiche Probleme wie mit dem anderen Extender)

So richtig rund läuft es eigentlich erst jetzt, bei allen anderen Lösungen war irgendwas nicht okay (Zu laut, zu langsam, zu umständlich, zu teuer, ... ). Lange Rede, kurzer Sinn - das hier ist das System das ich jetzt seit ca. einem Jahr im Einsatz habe und uneingeschränkt empfehlen kann.

Asrock ION 330 - sehr kleiner, leiser Barebone mit 2 Intel Atom CPU's und 300GB Platte und HDMI Anschluss. Alles was man braucht (bis auf WLAN) Onbard. Braucht unter MAXIMAL-LAST nur ca. 40 Watt, besteht aus Standard Laptop Elementen ( Slim-Line Laufwerk, 2,5" Platte ) und ist vor allem dank des NVidia ION Chipsets schnell genug für alle möglichen Full HD Formate und auch aktuelle Spiele. Die Rechen- und Plattenperformance nicht nicht so phänomenal - aber das System ist wirklich schnell genug für alle Media Center Anforderungen und zum surfen und für Office arbeiten sowieso. Preis: Unter 300 Euro.

Zubehör:

 

  • Windows 7 Home Premium OEM, ca. 100 Euro, Windows Media Center steckt mit drin.
  • Windows Media Center Fernbedienung von Microsoft mit USB Reciver, ca. 25 Euro. Qualitativ sehr gut, im dunklen beleuchtet, funktioniert ohne Konfiguration sofort perfekt. Eigene Taste um MC zu starten.
  • Terratec Cinergy DT XS Diversity - DVB-T Usb Stick mit 2 Tunern für parallele Sendungen. Wird von MC Problemlos unterstützt und erkannt, ca. 50 Euro.
  • BluRay Slimline Laufwerk - Hab ich günstig bei Ebay bekommen, zusammen mit Home Theather als BR Player Software. Die Software hängt sich auch ins Media Center und kann mit der Fernbedienung bedient werden.

 




 

EBC Architektur

July 15, 2010

Ich habe mir heute mal die von Ralf Westphal propagierte Event Based Component Architektur angesehen. Ich bin begeistert. Die Komponenten sind klein, übersichtlich und nach unten auf einem immer kleiner werdenden Abstraktionsgrad. Ich habe noch ein paar Detail-Probleme - die hatte ich aber bei jeder neuen Architektur-Idee.

Ich hab ein kleines Spielprojekt erstellt bei dem ich erst mal den gesamten Code ins Frontend gepackt habe. Anschließend habe ich auf eine klassische mehrschichtige Architektur erstellt und zuletzt die EBC Version erstellt. Im direkten Vergleich fällt vor allem das niedrige Hintergrundrauschen auf. Dinge wie Aspektorientierung benötigt man bei konsequenter Anwendung eigentlich kaum noch. Die Testbarkeit ist phänomenal da die Abhängigkeiten einer Komponente sehr klein sind.

Schön fände ich mal irgendwo ein größeres Referenzprojekt zu sehen bei dem man sich was abgucken kann, oder eine Toolbox mit elementaren Bausteinen wie Split, Join, Synchronize usw. Ich bin mir auch noch nicht sicher wie groß oder klein die Component sein sollte und wie ich sie auf Assemblies verteile.

Erstmal Code:

http://ralfw.blogspot.com/2010/05/asynchrone-kommunikation-mit-ebcs-statt.html

Die Idee dahinter:

http://ralfw.blogspot.com/2010/04/holarchie-event-based-components-fur.html

Bullshit!

May 12, 2010

"Unnötigerweise fordert die versierte Interaktion der Nutzungsdauer eine bipolare Spekulation der gewinnbringend chemischen Querverbindung und unterminiert wahrscheinlich einen immanent Teamgeist in Einklang mit der Unsicherheit der Manipulation."

 

Wer mal in langweiligen Besprechungen sitzen muss kann vielleicht den Bullshit Generator verwenden.

Laut diesem Blogeintrag wird Mac OS X 10.7 nur noch Software ausführen die von Apple signiert wurde und dann über den AppStore verkauft wurde. Die Lizenz für den AppStore wird es vermutlich auch hier nicht mehr geben wenn die Anwendungen mit Compilern wie MonoTouch erstellt wurde.Wenn ich die Lizenzbedingungen richtig verstehe kann man trotzdem Enterprise Anwendungen entwickeln die mit mit 3rd Party Developer Tools erstellt wurden sofern man von Apple für 99$ eine SDK Lizenz erwirbt, aber das Deployment über den AppStore bleibt dem User verwehrt.

Klingt als müsste mal jemand einen alternativen AppStore an den Start bringen.

Vielen Dank auch an Apple dafür das ich mir mein Wissen über Softwareentwicklung für MacOS und iPhone OS jetzt in die Haare schmieren kann.Heute Abend installiere ich Windows 7 auf meinem überteuerten MacBook.

 

Einen fahren lassen...

April 8, 2010

Wer mal unter Windows automatisch Text suchen und ersetzen (in mehreren Dateien) will kann dazu das Find And Replace Text Tool verwenden ( http://fart-it.sourceforge.net/ ) - kurz FART.

Wir verwenden das Tool in einer Batch um bei unserem Release Build in die AssemblyInfos einen Datumsstring einzufügen. Schön ist, das man es rekursiv verwenden kann.

Der "Preprozessor" von C# gibt leider nicht viel her, die Variante über MS-Build oder Nant war uns zu kompliziert zu warten und ein Tool wie FinalBuilder haben wir nicht mehr.

I like to fart!

 

 

.NET 4.0 Parallel-O-Gram

March 18, 2010

Seit bereits mehreren Jahren ist der Trend erkennbar - CPUs skalieren nicht mehr über ihre reine Rechenleistung sondern vor allem mit der Menge an physikalischen (oder heißt es physisch?) CPU Kernen. Will man dies in einer .NET Applikation nutzen macht man einfach weitere Threads auf die dann im idealfall parallel auf mehreren Cores abgearbeitet werden. Im .NET Ökosystem hat Microsoft in den letzten Jahren mehrere Extensions zur Unterstützung von Multithreading Entwickelt und zur Verfügung gestellt.  Mit .NET 4.0 wurde nun voher seperat verfügbare Extensions in das Core-Framework installiert, höchste Zeit also einen Blick darauf zu werfen was es dort neues gibt. Die Komponenten sind im wesentlichen:

  • TPL (Task Parallel Library)
  • CCR (Concurrency and Coordination Runtime)
  • PLinq (Parallel Linq)


Wieso nicht weiter wie bisher?

Zunächst einmal muss folgendes festgestellt werden. Paralelisierung ist nicht gleichzusetzen mit Multithreading! Nur weil eine Anwendung ( oder ein Service ) zwei Thread habs bedeutet das nicht dass diese auch parallel abgearbeitet werden. Dies hängt unter anderem vom Betriebbsystem, der Menge der CPU Kerne und zahlreichen weiteren Faktoren ab.

Die Menge an Thread muss sich folglich an der Mege der verfügbaren CPUs orientieren um einen Performance-Vorteil zu erzielen, aber auch dies allein ist nur eine grobe Lösung. Wenn andere Applikationen ebenfalls mit ihren Threads CPU-Kerne belegen sollte dies berücksichtigt werden, und was wenn die eigene Applikation in mehreren Instanzen läuft? Generell kostet die Erzeugung eines Threads Ressourcen und ist auch häufig nicht der schnellste Weg zur Lösung einer Aufgabe.

Was ist neu?

Die neuen parallelisierungsfunktionen setzen in einer Zusatzschicht auf dem Threadpool auf und werden über einen TaskScheduler (der auch selbst implementiert werden kann) verwaltet. Einzelne Tasks werden in eine Queue eingestellt und über den TaskScheduler auf physikalische Threads verteilt. Die Menge der Threads wird dabei permanent dynamisch angepasst. Der TaskScheduler hat eine recht ausgefuchste Routine zur Lastermittlung und kann so z.B. auch I/O Last, Netzwerklast usw. zur Laufzeit ermitteln, ebenso wird aktuele CPU Last, Art der Threads und weitere Informationen berücksichtig. Alle 0.5 Sekunden findet diese Überprüfung statt und passt anschließend ggf. die Anzahl der physikalischen Threads dem Ergebnis der Auswertung an.

Trotz der neuen Automatisierungs-Features wird eine Anwendung durch Parallelisierung immer noch komplexer und schwerer zu debuggen. (Stichworte Deadlocks, Race Conditions, etc.)

Bevor man sich an die parallelisierung einer bestehenden Anwendung begibt sollte Code immer erst optimiert und Refactored werden - häufig ist hier noch deutlich mehr Performance zu finden als durch stumpfe Teilung in Threads. Für den geschätzten Performance-Gewinn einer parallelisierung kann man sich an http://de.wikipedia.org/wiki/Amdahlsches_Gesetz orientieren. Ideal geeignet ist Code der langwierige Berechnungen ausführt, lange dauernde Service-Requests durchführt und leicht "zerlegbar" ist.

Was ist mit Code?


Hier ein paar Codeschnipsel die zeigen wie die neuen Features verwendet werden können. Für alle Beispiele ist zunächst der Namespace System.Threading.Tasks zu importieren.

Manuelle Tasks erzeugen

Task newTask = Task.Factory.StartNew(() => Console.WriteLine("hello from task1!"));

(Extension Method .ContinueWidth ermöglicht eine Reihenfolge der Tasks festzulegen)

Synchronisierung:

Sicherstellen das alle Tasks fertig sind

Task.WaitAll( task1, task2 );

Sicherstellen das Task 1 beendet ist...

Task.Wait(task1);

Warten bis irgendeiner der Task beendet ist:

Task.WaitAny(....);

(Dann wird auch die IsCompleted-Property des Tasks true)


Abfrage von Rückgabewerten:

Task<string> task1 = new Task<string>(() => GetResult());
task1.Start();


string result = task1.Result;  // Das funktioniert weil der Result-Getter Code erst ausgeführt wird wenn der Task beendet ist.


Die zwei einfachsten Möglichkeiten:

Parallel.For() und ForEach()


            Parallel.ForEach(numbers, number =>
                {
                    work.Process(number);
                });

Achtung! Hier ist nicht garantiert in welcher Reihenfolge die Liste abgearbeitet wird! Ist die Liste z.B. mit 1,2,3....50 gefüllt und sind 2 CPUs vorhanden beginnt der erste Thread mit der 1, der zweite mit der 25. Das muss aber nicht immer so sein - siehe Erklärung des TaskSchedulers.



ParallelOptions options = new ParallelOptions { MaxDegreeOfParallelism = 2 };

Parallel.For(0, numbers.Count, options, number =>
{
  work.Process(number);
});


Viel Vergnügen beim ausprobieren!

.NET 4.0 kommt unter anderem mit dem neuen Namespace System.IO.MemoryMappedFiles daher und bietet darüber Zugriff auf MemoryMapped Files.

Was sind MemoryMappedFiles?

MMFs enthalten den Inhalt einer Datei im Adressraum der eigenen Applikation. Veränderungen an der Datei können gemacht werden indem also direkt der Speicher verändert wird. Es gibt zwei Typen von MMFs:

Persisted: Sind mit einer Datei auf der Disk verbunden. Sobald der letzte Prozess Änderungen vorgenommen hat werden diese in die Datei gesichert, dies ist für sehr große Dateien geeignet.

Non-Persisted: Sind nicht mit deiner Datei verbunden. Wenn der letzte Prozess den Zugriff beendet hat wird der Speicher vom GC freigegeben. Diese Version ist für Interprozesskommunikation geeignet.

Interprozesskommunikation mit virtuellen Dateien?

Ja. MMFs können über verschiedene Prozesse hinweg geteilt werden. Über einen Common-Name, der vom erzeugenden Prozess vergeben wird kann der Zugrif erfolgen. Das ganze ist aber eher ein Relikt aus der Win32 Welt. Nach ein paar Experimenten kann ich davon abraten. Zuerst einmal ist diese Kommunikation natürlich nur auf der physikalisch oder virtuell gleichen Maschine möglich. Vor allem gibt es aber keine festen Regeln für die Kommunikation, unterm Strich erinnert das ganze immer an WinSock-Zeiten und selbst ausgedachte TCP/IP Protokolle, auch die Synchronisation für den Zugriff muss z.B. über einen Mutex selbst geregelt werden.

Zugriff per Views:

Um mit der Datei zu arbeiten muss ein View auf die MMF oder einen Teil von ihr erzeugt werden. Mehrere überlappende Views sind möglich. Mehrere Views sind auch nötig wenn die Datei größer ist als der von der Applikation adressierbare Speicher ( 2GB bei 32 Bit OS ) Es gibt 2 Typen Views: Stream Access und Random Access. Stream Access bietet sequentiellen Zugriff auf die Datei (empfohlen für PIC und non persisted Files). Random Access views sind empfohlen für die Abreit mit Persisted-Files. Der Zugriff erfolgt durch den Memory-Manager des OS, die Datei wird in Pages zerlegt und wird wie benötigt geladen, man muss sich nicht um die Speicherverwaltung kümmern.

Unterm Strich bleibt also eine gute Möglichkeit sehr große Dateien schnell zu verarbeiten, mit mehreren Views können die Dateien problemlos mehrere Gigabyte groß sein.