ssh von unterwegs
Geschrieben von Harald Lapp in Closed Source Tools, iPhone um 11:16
Es kam schon oft vor, dass ich unterwegs gerne einen Blick auf einen Server geworfen hätte. Wie habe ich mich deshalb gefreut, als vor ca. einem Jahr die erste SSH Software für das iPhone angekündigt wurde -- pTerm. Leider erwies sich diese Bezahlsoftware als nicht wirklich ergiebig. Die ersten Versuche zu Hause im WLAN waren zwar erfolgreich, unterwegs über edge wollte das ganze jedoch leider nicht funktionieren. Bis heute weiss ich nicht warum -- die pTerm Diskussionsgruppe war in dieser Hinsicht auch nicht wirklich hilfreich. In der Zwischenzeit wartet man auf ein Update der Software, das nicht kommt.
Nun habe ich kürzlich ein wenig im App-Store gestöbert und bin bei dieser Gelegenheit auf das Tool TouchTerm gestossen, welches -- im Gegensatz zu pTerm -- auch in einer kostenlosen Variante erhältlich ist.

Auf den ersten Blick bietet TouchTerm in der kostenlosen Variante ähnliche Features wie pTerm, mit dem einen Unterschied: es funktioniert auch von Unterwegs über edge problemlos. Die kostenpflichtige Pro Variante -- derzeit mit einem Preis von € 11,99 nicht gerade eine der günstigen Anwendungen im App-Store -- bietet zusätlich Gestures (wobei ich da bei einer Shell Angst hätte versehentlich rm -rf zu erwischen
), Copy/Paste innerhalb der Anwendung, grafische Verzeichnisnavigation sowie umfangreichere Einstellungsmöglichkeiten.
gearman job queue server
Geschrieben von Harald Lapp in PHP um 17:28
Die letzten Wochen habe ich für die Arbeit einen Workflow Prozessor entwickelt, über den wir zukünftig unsere Medien Uploads verarbeiten werden. Unter anderem gehört zu seinen Aufgaben die Erzeugung von Still Images aus Videos, Wave- und Spektrum-Analyse aus Audiodateien, Erzeugung von Thumbnails und Previews für die Darstellung auf der Web Seite. Der Workflow Prozessor arbeitet von der Console bzw. als Hintergrundprozess (Dämon) und ist in PHP entwickelt. Wird er auf einem Server gestartet, kann der Hauptprozess beliebig viele Worker-Prozesse forken.
Ein Problem bei der Entwicklung war die Verteilung der Prozesse an die Worker. Hier habe ich zunächst auch auf eine reine PHP basierte Lösung gesetzt und die Verteilung der Aufgaben vom Hauptprozess übernehmen lassen, der über Socket-Pairs mit den Worker-Prozessen kommunizieren kann. Bei Tests während der Entwicklung im kleinen Rahmen und mit wenigen Jobs hat das auch wunderbar funktioniert. Bei umfangreicheren Tests traten dann allerdings die Probleme zu Tage.
Einmal abgesehen davon, dass die ganze Sache nicht wirklich der Performance-bringer war, war sie dank der direkten Kommunikation Client->Worker auch fehleranfällig und schlecht bzw. gar nicht skalierbar, denn wie soll man mit dieser Methode mehrere bzw. beliebige Worker-Server transparent ansprechen?
Zum Glück habe ich schon seit einiger Zeit gearman in meinen Lesezeichen. Gearman ist eine Serversoftware, die -- einfach ausgedrückt -- den Zweck erfüllt Jobs zu verteilen. Mögliche Einsatzgebiete sind z.b. die Verteilung von Jobs an Systeme, die besser für die jeweilige Aufgabe geeignet sind, die Lastverteilung auf beliebige Server oder um Jobs parallel abarbeiten zu können. Hierfür wird seitens gearman eine (persistente) Warteschlange implementiert, an die ein Client einen Job senden kann. Ein Worker kann sich einen Job aus der Warteschlange holen und diesen abarbeiten.
Gearman wurde ursprünglich von Brian Fitzpatrick (livejournal, memcached, ...) in Perl entwickelt und vor einiger Zeit von Brian Aker und Eric Day nach C portiert. Der Entwicklungsstand des C Zweiges von gearman ist seiner Version (0.3) zu schliessen noch relativ jung. Insgesamt aber scheint sich das ganze schon derart bewährt zu haben, dass gearman produktiv und unter hoher Last z.b. von digg und yahoo eingesetzt wird.
Zum erfolgreichen Kompilieren von gearman unter OSX muss sichergestellt sein, dass man eine aktuelle Version der libevent Bibliothek installiert hat. Danach lässt sich auch gearman problemlos unter OSX bauen und installieren. Sowohl für libevent wie auch für gearman funktioniert das wie üblich:
$ ./configure
$ make
$ make install
Anschliessend kann man gearman starten. Der Parameter "-d" bewirkt dabei, dass gearman als Hintergrundprozess losgelöst vom Terminal gestartet wird:
/usr/local/bin/gearman -d
Per default lauscht gearman auf Port 4370. Dies ist der offizielle Port, der von der IANA für gearman reserviert wurde.
Client/Worker APIs zur Kommunikation mit gearman gibt es bereits für C (enthalten im gearman Download), Perl, MySQL (als UDF) und PHP. Zum Ansprechen von gearman unter PHP gibt es ein pear package, net_gearman, sowie seit kurzem auch eine native Erweiterung für PHP, die allerdings noch experimentell ist und dementsprechend mit Vorsicht zu geniessen ist. Unter OSX konnte ich sie z.b. zwar einwandfrei kompilieren und installieren, die ersten Versuche scheiterten dann aber an segfaults. Nicht weiter tragisch, da das pear paket bisher einwandfrei seine Arbeit macht.
Eine Client Anwendung, die Jobs an den gearman Server übergibt, ist mit dem pear Paket schnell entwickelt:
#!/usr/bin/env php
<?php
require_once('Net/Gearman/Client.php');
$set = new Net_Gearman_Set();
function result($resp) {
print_r($resp);
}
$files = array(
'/Users/harald/Movies/00001.mov'
);
foreach ($files as $file) {
print "adding task $file\n";
$task = new Net_Gearman_Task('test', array(
'filename' => $file
));
// $task->attachCallback('result');
$set->addTask($task);
}
print "running set ...\n";
$client = new Net_Gearman_Client(array('127.0.0.1:4730'));
$client->runSet($set);
?>
Der erste Parameter beim Instanzieren der Klasse Net_Gearman_Task spezifiziert übrigens den Namen des Jobs, der vom Worker registriert werden muss, damit dieser entsprechende Jobs annehmen und verarbeiten kann. Normalerweise wartet der Client, bis alle Jobs abgearbeitet sind und kann wenn eine Callback Methode registriert wurde, mögliche Ergebnisse verarbeiten, die die Worker zurückliefern. Dieses Verhalten kann möglicherweise unerwünscht sein, z.b. wenn viele Jobs eingereicht werden und der Client während der Abarbeitung nicht blockiert sein soll. Hierfür implementiert die Net_Gearman_Task Klasse ein öffentliches Property:
public $type = self::JOB_NORMAL;
Um das Verhalten zu ändern, sind folgende Typen definiert:
- Net_Gearman_Task::JOB_NORMAL -- Standardverhalten: Client blockiert während der Abarbeitung der Jobs
- Net_Gearman_Task::JOB_BACKGROUND -- Client reicht Jobs an gearman weiter und blockiert nicht
- Net_Gearman_Task::JOB_HIGH -- selbes Verhalten wie JOB_NORMAL, allerdings wird die queue übersprungen und ein Job kann sofort von einem Worker verarbeitet werden. Sinnvoll z.b. für höher priorisierte Jobs
Eine einfacher Klasse, die die Aufgabe 'test' implementiert, könnte folgendermassen aussehen:
<?php
class test extends Net_Gearman_Job_Common {
function run($args) {
print_r($args);
print "sleeping 5 seconds ...\n";
sleep(5);
print "done!\n";
return "OK!";
}
}
?>
Der Worker selbst wird folgendermassen aufgebaut:
#!/usr/bin/env php
<?php
define('NET_GEARMAN_JOB_CLASS_PREFIX', '');
define('NET_GEARMAN_JOB_PATH', '.');
require_once('Net/Gearman/Worker.php');
$worker = new Net_Gearman_Worker(array('127.0.0.1:4730'));
$worker->addAbility('test');
$worker->beginWork();
?>
Normalerweise erwartet Net_Gearman Klassen, die Aufgaben implementieren unterhalb eines Verzeichnisses, das in der PEAR Verzeichnisstruktur angesiedelt ist. Weil man dies normalerweise nicht möchte, gibt es folgende Konstanten, die man mit eigenen Werten füllen kann um so alternative Verzeichnisse zu setzen:
// spezifiziert ein Prefix für den Namen der Klasse
define('NET_GEARMAN_JOB_CLASS_PREFIX', '');
// spezifiziert das Verzeichnis, in dem Klassen gesucht werden
define('NET_GEARMAN_JOB_PATH', '');
Unschön ist, dass für einzubindende Klassen Dateien mit folgendem Namensschema erwartet werden, z.b: test.php. Da ich meine Klassen immer z.B. -- test.class.php -- benenne, ist dies also leider eine kleine Unschönheit, mit der man offenbar leben muss.
Zum Abschluss sei noch zu sagen, dass gearman in den ersten Tests mit mehreren 1000 Jobs in der Queue seine Arbeit tadellos und sehr zufriedenstellend erledigt hat.
Empfohlene weiterführende Links:
JavaScript: The World's Most Misunderstood Programming Language
Geschrieben von Harald Lapp in Javascript um 08:13
Eigentlich sollte ich stolz sein: es gibt tatsächlich Leser meines Blogs, die meine Artikel aufgreifen und sich darüber kritische(?) Gedanken machen. Gestern bin ich zufälligerweise auf einen Artikel in einem Blog gestossen, in dem sich der Autor über meine Einstellung zu JavaScript lustig macht. Bei all seinem Sarkasmus vergisst der Autor leider Argumente vorzubringen warum er meine Einstellung so lächerlich findet. Die im Text eingestreuten Klischees, die man ähnlich so eigentlich nur aus dem Heise-Forum kennt, können es kaum sein.
Dabei kann ich die Einstellung tatsächlich sogar verstehen: In JavaScript lässt es sich ähnlich schmutzig und disziplinlos programmieren, wie mit PHP. Nur: dort wo PHP einem Steine in den Weg legt, weil der Parser viele dinge einfach nicht zulässt, ist JavaScript in der Regel offen und man kann einen sehr sauberen und eleganten Programmierstil fahren. Nun ist es bei JavaScript so wie mit jeder Programmiersprache: man muss sich damit beschäftigen. Was PHP und JavaScript darüberhinaus gemein haben ist, dass es für beide Sprachen wenig gute Literatur, dafür aber umso mehr schlechte Literatur gibt.
Bei ernsthaftem Interesse an JavaScript möchte ich an dieser Stelle auf einen Artikel von Douglas Crockford verweisen -- JavaScript: The World's Most Misunderstood Programming Language. Dieser Artikel räumt mit einigen Vorurteilen gegenüber JavaScript auf und macht vielleicht auch verständlich, warum JavaScript einen derart schlechten Ruf hat.






