Martin Lantzsch
Software Entwickler
24. März 2013

Dynamisches JavaScript in den Chrome Developer Tools

24. März 2013 - Geschrieben von Martin - Keine Kommentare

Das neue Resigame ist ja komplett Single Page, sprich alle Inhalte werden nachgeladen und dynamisch aufgebaut ohne dass die Seite auch nur ein einziges mal neu geladen werden muss.

Hierbei lade ich natürlich die JavaScript Dateien nur dann wenn ich sie brauche, also über eine Requirejs ähnliche Schnittstelle in meine App. Ich habe das ganze noch ein wenig „verfeinert“, bzw. an meine Bedürfnisse angepasst.

Das Problem an der Sache ist nur, dass diese Dateien dann natürlich in den Chrome Entwickler Tools unter „Source“ nicht auftauchen, weil dieser Tab nur die im HTML – beim Seitenaufbau – existenten Scripts erkennt. Um das zu umgehen hängt man einfach in die js Dateien ganz unten folgenden Kommentar:

//@ sourceURL=/static/lib/resigame/map.js

natürlich muss der Pfad angepasst werden. Übrigens ist dieses Verhalten ganz praktisch, wenn man auch in der Entwicklung schon mit kompilierten/komprimierten JavaScript Dateien arbeiten möchte, denn hängt man den Source Url Kommentar unten an jenes komprimiertes File an, wird das dort angegebene als sog. Source Map verwendet sprich, in den Entwickler Tools sieht man dieses und man kann bequem Breakpoints im Klartext Quellcode setzen. Allerdings muss hierzu ein Kompiler verwendet werden, der Source Maps unterstützt, dass ist meines Wissens nach momentan nur der Closure Compiler von Google. Mehr Informationen zu den Source Maps hier: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

12. Februar 2013

Python pip – Modul im Home Verzeichnis installieren

12. Februar 2013 - Geschrieben von Martin - Keine Kommentare

Bei älteren pip Versionen wird ein Python Modul wie hier z.B. „uptime“ mit folgendem Kommando in das Home Verzeichnis des aktuellen Benutzers installiert (z.B. /home/foo/.local/lib/pythonX.X/)

pip install --install-option="--user" uptime

bei neueren Versionen gibt es auch folgendes Shortcut

pip install --user uptime

11. Februar 2013

Telnet Client Session beenden

11. Februar 2013 - Geschrieben von Martin - Keine Kommentare

Zum beenden einer Telnet Session einfach STRG + * drücken.

telnet> open 127.0.0.1 1234
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
^]
telnet> q
Connection closed.

10. Februar 2013

visualstudio.com Computer Name geändert

10. Februar 2013 - Geschrieben von Martin - Keine Kommentare

Mit folgendem Kommando kann man das Repository wieder gangbar machen, wenn der Computername geändert wurde:

C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE>tf workspaces /updateComputerName:ALTERCOMPUTER /s:https://DEINWORKSPACE.visualstudio.com:443/DefaultCollection
Auflistung: https://DEINWORKSPACE.visualstudio.com/DefaultCollection
Arbeitsbereich  Besitzer        Computer Kommentar
--------------- --------------- -------- --------------------------------------
ALTERCOMPUTER   Martin Lantzsch NEUERCOMPUTER

23. Januar 2013

Die DLL „SQLite.Interop.dll“: Das angegebene Modul wurde nicht gefunden.

23. Januar 2013 - Geschrieben von Martin - Keine Kommentare

Ich habe eine C# Projekt Mappe mit einer WPF Anwendung und einer Konsolen Anwendung. Die WPF Anwendung besitzt alle Klassen, DLLs, etc. Der Konsolen Anwendung habe ich anschließend abhängig von der WPF Anwendung gemacht und die Build Reihenfolge so gestellt, dass die Konsolenanwendung bei erstellen der Projekt Mappe als zweites kompiliert wird.

Beim Debuggen trat dann immer folgender Fehler auf. Allerdings nur beim Debuggen, beim Ausführen der .exe aus dem /bin/Debug Ordner des Projektes gab es keine Probleme.
Die DLL "SQLite.Interop.dll": Das angegebene Modul wurde nicht gefunden.

Ich dachte erst an nicht aufgelöste Abhängigkeiten, also habe ich mir mit dem „Dependency Walker“ die DLL genauer angesehen:
Dependency Walker
Error: Modules with different CPU types were found.
CPU Type, das Problem kommt mir bekannt vor. Also habe ich mein Konsolen Projekt in den Projekteinstellungen von „Zielplattform“ – „Any CPU“ auf „x86“ gestellt und hey, nun startet es. Warum weiß ich leider nicht, ich kann es mir nur so erklären, das er beim kompilieren „Any CPU“ nicht auf die in x86 und x64 DLLs in dem GUI Projekt mappt. Denn das GUI Projekt startet mit „Any CPU“, den selben DLLs und der selben Klasse, die auf die DLLs zugreift.

10. Januar 2013

ResiOS lebt

10. Januar 2013 - Geschrieben von Martin - 2 Kommentare

ResiOS lebt
Eigenen x86 Kernel mit C und Assembler schreiben. Check.

6. Januar 2013

NodeJS MySQL pool

6. Januar 2013 - Geschrieben von Martin - 2 Kommentare

Momentan arbeite ich daran Resigame 2.0 auf NodeJS Basis zu entwickeln. Da abzusehen ist, dass auf Resigame wieder sehr hoher Traffic entstehen wird, wird das ganze Performance optimiert entwickelt. Cluster, SQL Pooling, etc.

Gestern habe ich mir ein Modul für den MySQL Pool geschrieben, denn bei vielen NodeJS Applikationen wird entweder für jeden HTTP Request eine MySQL Verbindung verwendet oder eine für alle.

Das Problem bei einer Verbindung pro HTTP Request ist, dass die Verbindungen bei hohen Nutzerzahlen sehr schnell ausgehen (MySQL max connections) und man ggf. ein paar Sekunden auf die nächste freie Verbindung warten muss.

Bei der Methode mit einer Verbindung, die für alle Nutzer verwendet wird, ist natürlich die Performance sehr bescheiden. Aufwändige Querys können die ganze Applikation stark ausbremsen.

Also habe ich einen MySQL Pool entwickelt, dieser wird beim starten der Anwendung erzeugt. Man übergibt die „poolsize“ – also die Anzahl der Verbindungen die hergestellt werden sollen (diese muss natürlich unter der maximalen Anzahl an Verbindungen, die der MySQL Server zulässt liegen) und die Zugangsdaten zum Datenbankserver. z.B.

var pool = new require('/helpers/pool')({
	poolsize: 50,
	mysql: {
		host: 'localhost',
		user: 'root',
		password: 'root',
		database: 'resigame'
	}
});

Querys können nun direkt an den Pool gesendet werden:

pool.query('SELECT * FROM users WHERE userID = ?', [userID], function(err, results) {
	// whatever
});

Der Aufruf fügt den Query zur Warteschlange hinzu und sieht nach ob gerade eine Verbindung frei ist. Wenn ja wird diese gleich verwendet, ansonsten dauert es bis wieder eine Verbindung frei wird. (Ergo, je mehr Benutzer die gleichzeitig auf die Datenbank zugreifen, desto höher die poolsize –> mehr Performance).

Hier der Quellcode, ich werde ihn die Tage noch ein wenig erweitern und dann auf GitHub stellen.

/** 
 * MySQL pool to hold multiple connections to the database server
 *
 * @author	Martin Lantzsch <martin@linux-doku.de>
 */
 
var mysql = require('mysql');
module.exports = function(config) {
	this.freeConnections = [];
	this.queryQueue = [];
 
	this.createConnection = function(details) {
		var connection = mysql.createConnection(details);
		connection.connect();
		connection.number = this.freeConnections.length;
		this.freeConnections.push(connection);
	};
 
	this.query = function(command, params, callback) {
		if(typeof(params) == 'function') {
			callback = params;
			params = [];
		}
 
		this.queryQueue.push({
			command: command,
			params: params,
			callback: callback
		});
		this.work();
	};
 
	this.work = function() {
		var self = this;
		if(self.queryQueue.length > 0) {
			if(self.freeConnections.length > 0) {
				var query = self.queryQueue.shift();
				var connection = self.freeConnections.shift();
				connection.query(query.command, query.params, function(err, results) {
					if(err) throw err;
					query.callback(err, results);
					self.freeConnections.push(connection);
					if(self.queryQueue.length > 0)
						self.work();
				});
			}
		}
	};
 
	for(i = 0; i < config.poolsize; i++) {
		this.createConnection(config.mysql);
	}
 
	return this;
}