PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Search Results

Velocity Europe Tag 2: Whao!

without comments

Speeeed! Genauso wie der letzte Tag geendet hat beginnt der zweite.

Steve und John eröffnen den zweiten Tag mit einer kurzen Opening Keynote, gefolgt von Jeff Veen der von den Problemen berichtet als Typekit einige Tage vor Weihnachten vom Erfolg überrollt wurde, und wie innerhalb eines Wochenendes das Problem kurzerhand gelöst werden musste und auch wurde. Das Grundproblem waren die vielen Kits die nicht zeitnah in das CDN gebracht werden konnten, und sich so eine massive Queue aufgebaut hatte. Ich mag solche praxisnahen Einsichten sehr. Eine These bzw. Grundsatz der Kultur der Firma: IRC über E-Mail. Im IRC kann man kurze Fragen und Antworten schreiben wie „no“. In E-Mails haben wir irgendwie den Zwang, formal zu schreiben und viele Sätze zu bilden. Das bläht schnelle interne Kommunikation unnötig auf.

Read the rest of this entry »

Written by Michael Kliewe

November 11th, 2011 at 12:57 pm

Mehrere Scripte via Cronjob parallel aufrufen

with 15 comments

Heute ein kleines Problemchen mit Cronjobs und Parallelität. Normalerweise empfehle ich Gearman wenn es darum geht, mehrere Scripte im Hintergrund laufen zu lassen, aber nehmen wir an dass wir es mit normalen Cronjobs ohne Gearman lösen wollen.

Wir haben also das Script work.php. Wir möchten alle 5 Minuten die Datenbank prüfen ob es Arbeit gibt, und wenn dem so ist, dann soll die Arbeit erledigt werden. Das geht relativ einfach mit einem Cronjob

*/5 * * * * /usr/bin/php /data/work.php

und in der work.php findet dann die Datenbankabfrage statt. Wenn X Ergebnisse in der Datenbank gefunden werden, wird eine Schleife X mal durchlaufen um alles abzuarbeiten. So weit so gut.

Nun sei die eigentliche Arbeit aber relativ zeitaufwändig, sodass ein Schleifendurchlauf 2 Minuten dauert, und bei 5 Aufträgen dauert es also 10 Minuten (wir arbeiten ja seriell in einer Schleife), der Aufruf von work.php überlappt und wir bekommen ein Problem. Angenommen die Aufgabe ist parallelisierbar, d.h. wenn man alle 5 Aufgaben zeitgleich starten würde gäbe es keine Probleme, und die ganze Arbeit wäre nach 2 Minuten erledigt. Wir könnte man soetwas einfach realisieren?

Read the rest of this entry »

Written by Michael Kliewe

Juli 19th, 2011 at 9:25 am

Posted in PHP

Tagged with , ,

Linkpool Nummer 7

without comments

Blogartikel über Mutation Testing, sehr interessant um seine Tests zu testen:

http://blog.astrumfutura.com/index.php?/plugin/tag/mutateme

Webseitengeschwindigkeit ist wichtig:

http://www.stevesouders.com/blog/2010/05/07/wpo-web-performance-optimization/

Zend Framework 1.10.4:

http://devzone.zend.com/article/12078-Zend-Framework-1.10.4-Released

Einfacher forken unter Linux mit PCNTL:

http://kore-nordmann.de/blog/0098_native_job_queue.html

Git post-receive Hooks mit Gearman umgesetzt:

http://weierophinney.net/matthew/archives/240-Writing-Gearman-Workers-in-PHP.html

PHP Microbenchmarking

http://code.ning.com/2010/05/php-microbenchmarking/

Der „Month of PHP Security“ hat begonnen:

http://php-security.org/

Written by Michael Kliewe

Mai 8th, 2010 at 1:31 pm

HTML 5 und Javascript 5: Clientseitige Datenbanken

with 13 comments

Nachdem sich die Web Hypertext Application Technology Working Group (WHATWG) 2004 gegründet hat, die aus einigen bedeutenden Internet-Riesen besteht (u.a. Apple, Mozilla, Opera), kommt wieder Fahrt in neue HTML- und Javascript-Standards. Die Gruppe hat viele Proposals erstellt, von denen jetzt einige vom W3C übernommen werden. Stichworte sind da HTML 5, ECMAScript 5, Web Workers, Web Storage, Web Sockets und einiges mehr.

Zu den Web Workern hatte ich ja bereits etwas geschrieben.

Web Sockets wird die Pushing-Technik werden, mit der Server bei Änderungen Nachrichten an den Browser schicken können, dann erübrigt sich das derzeitige Pullen und Nachfragen via AJAX, ob es Neuigkeiten gibt. Das entlastet die Server und spart Traffic, und Nachrichten kommen genau dann im Browser an wenn sie auf dem Server passieren, nicht erst beim nächsten Pull.

Heute soll es um den Web Storage gehen, die clientseitige Datenbank im Browser. In der Vergangenheit konnte man Daten nur auf der aktuellen Seite in Javascript-Variablen vorhalten, sobald aber der nächste Full-Page-Reload kommt sind die Daten futsch. Die zweite Möglichkeit waren Cookies, in denen man Daten speichern kann. Da aber Cookies bei jedem Request mitgesendet werden, ist das kein guter Speicherort für größere Datenmengen, Cookies sollte man höchstens für eine SessionID nutzen.

Read the rest of this entry »

Written by Michael Kliewe

Januar 6th, 2010 at 7:53 am

Verteiltes Rechnen mit Javascript und Google Gears

with 20 comments

timegate_scrWie ich ja bereits des öfteren anmerkte, habe ich früher ein Browsergame programmiert. Begonnen habe ich 2003, als es erst recht wenige Browsergames gab, und diese auch alle von Privatleuten als Hobby betrieben wurden. Da man natürlich Alleinstellungsmerkmale braucht gegen „die Konkurrenz“, baut man viele Ideen ein, die andere nicht haben. Unter anderem war in meinem Browsergame (es handelte sich um ein Aufbauspiel a la OGame, Stoneage etc.) das erste Mal auch ein Turniermodus (1on1) möglich, so dass man abseits der lang laufenden Welten auch in einem KO-Modus gegen andere antreten konnte. Dazu wurden Speed-Server für die ausgelosten Paare gestartet, wo dann 2 Spieler gegeneinander antreten mussten und gewisse Siegbedingungen erreichen mussten. ICQ-Benachrichtigungen bei bestimmten Ereignissen hatte ich auch recht früh eingebaut.

In der folgende Version (die leider nie das Licht der Welt erblickt hat) kamen noch viele weitere interessante Features hinzu. Der Quellcode wurde komplett neu geschrieben in PHP5, war nun voll objektorientiert (in PHP4 war das ja nur sehr beschränkt möglich), und auch neue „Web2.0“ Funktionalitäten waren mit drin.

So gab es zum Beispiel eine Möglichkeit, dass Spieler sich selbst Weltkarten zusammenbauen konnten mit einem einfachen Editor. Der Spieler hat dazu mehrere Feldtypen (Gras, Fels, Wasser, Berg, Moor) und kann daraus eine Karte basteln, auf der er dann gegen andere antreten kann (und wenn sie gut bewertet wird, kann es auch eine Karte für einen „großen“ Server werden, wo tausende Spieler drauf spielen). Eines der Probleme, die es dabei gab, war die Berechnung der Wege. Man muss, um seine Armee zu bewegen, nur das Zieldorf anwählen und kann dort angreifen. Der Dijkstra-Algorithmus bestimmt dann die Zeit, die die Armee unterwegs ist. Dazu muss man den genauen Weg kennen, denn es gibt auch unpassierbares Gelände (in diesem Fall Berge) oder Flächen, auf denen die Armee langsamer ist (Moor). Da die Karten mitunter sehr groß sind (zB 1000*1000), dauert diese Berechnung recht lang. Diese Berechnung bei jeder Armeebewegung zu machen macht die Webseite ziemlich lahm. Also habe ich für die „Standardkarten“ diese Berechnungen bereits erledigt und die 500.000 Ergebnisse (von jedem Feld zu jedem anderen) in einer Datenbank gespeichert.

dijkstraWenn nun aber viele Spieler neue Karten basteln, schafft das der Server nicht mehr, er muss ja auch nebenbei noch für die eigentlichen Webseiten und Datenbanken herhalten. Eine Berechnung für eine Karte dauert mitunter 20 Stunden (Dijkstra Algorithmus in PHP).

Was also tun? Richtig, wir verteilen die Arbeit auf die Client-Rechner. Die 500 Spieler, die auf der Webseite rumsurfen und das Spiel spielen, können nebenbei auch bei der Berechnung helfen. Doch wie macht man das? Aufwendige Dinge wie ein eigenes Client-Programm schreiben, oder Plugins für BOINC etc. sind zu aufwändig und übertrieben. Wie so häufig gibt es eine einfache Lösung: Gears von Google.

Mit Gears kann man asynchron Javascripte ausführen, die die Webseite nicht beeinträchtigen, indem man sogenannte WorkerPools mit Arbeit versorgt.

Hier habe ich mal ein einfaches Beispiel:

main.html

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
var workerPool = google.gears.factory.create('beta.workerpool');

workerPool.onmessage = function(a, b, message) {
	alert('result from worker ' + message.sender + ': \n' + message.body);
};

var childWorkerId = workerPool.createWorkerFromUrl('worker2.js');

workerPool.sendMessage([5, 1, 8], childWorkerId);
</script>

worker2.js:

var wp = google.gears.workerPool;
wp.onmessage = function(a, b, message) {
	// do calculation here
	var reply = message.body[0] + message.body[1] + message.body[2];
	wp.sendMessage(reply, message.sender);
}

Wenn man die entsprechende Webseite aufruft, wird man gefragt, ob der Zugriff auf Gears erlaubt werden soll. Wenn man Gears installiert hat, kann man also noch von Fall zu Fall unterscheiden, ob man der Webseite seine Resourcen zur Verfügung stellen möchte oder nicht.

gears_question

Was passiert nun? Die Webseite startet einen WorkerPool, in diesem Workerpool wird ein Worker gestartet, der das Script worker2.js ausführen soll. Wir senden an den darin befindlichen Worker ein Array mit 3 Zahlen.

Der Worker errechnet dann die Summe dieser Zahlen, und sendet das Ergebnis zurück an den WorkerPool. Diese Nachricht fangen wir mit dem „onMessage“ Eventhandler ab und zeigen das Ergebnis mittels alert() an.

Wie würde nun die Kartenberechnung funktionieren? Wir übergeben statt dem einfachen Array ein komplexes großes Array mit dem Graphen, den Kantengewichten usw.  Im Worker findet dann die eigentliche Dijkstra-Berechnung statt. Dort wäre es sinnvoll, nicht die ganze Karte zu berechnen (Dauer 20 Stunden), sondern nur kleine Häppchen, die in wenigen Sekunden bearbeitet sind. Statt das Ergebnis dann via alert() auszugeben, schicken wir es via AJAX zurück an den Webserver, der das Ergebnis in die Datenbank einträgt.

Leider ist es bei diesen ersten Tests geblieben, ich habe die eigentlichen umfangreichen Dijkstra-Berechnungen nie in Javascript mit Gears umgesetzt. Aber möglich ist es.

Eine einzige Hürde gibt es: Auf dem Clientrechner muss Gears installiert sein. Mit einer guten Community und Nutzern, die einem vertrauen, ist aber auch das machbar.

Alternativ kann man natürlich auch ohne Gears die Berechnungen in Javascript durchführen lassen. Dabei muss man jedoch beachten, dass der Browser dadurch nicht unbenutzbar wird. Man muss also die Berechnung künstlich bremsen, außerdem muss man eine Lösung dafür finden, dass der Browser lang laufende Javascripte gern auch mal abbrechen möchte.

longrunning

Mit Gears passiert sowas nicht.

Anwendungsfälle des Dijkstra-Algorithmus sind beispielsweise das bekannte „Friend of a Friend“ Problem (soziale Netzwerke zeigen an, über wieviele Kontakte man eine andere Person kennt) oder alle anderen Arten, wo man in einem Graphen den kürzesten Pfad ermitteln möchte. Man kann so sicherlich auch noch andere, komplexe Berechnungen auf die Clients auslagern.

Gears kann man natürlich auch noch für viele weitere Dinge nutzen, wie schöne Benachrichtigungen, als lokalen Speicher für Dateien oder Daten (Datenbank), Geolocation (was ja mittlerweile die Browser schon nativ beherrschen) usw.

Habt ihr Erfahrungen mit Gears, oder Ideen welche revolutionären Dinge man damit umsetzen könnte?

Written by Michael Kliewe

September 29th, 2009 at 10:35 pm