Ich habe ein "Checker" -System geschrieben, das verschiedene "Checks" für verschiedene Dienste, Systeme, Datenbanken, Dateien usw. durchführt. Ein "Check" ist generischer Natur und kann alles Mögliche sein. Alle Überprüfungen werden in einem gemeinsamen Format gemeldet, unabhängig davon, ob sie erfolgreich sind oder nicht.Perl async Aufgaben für "Any" -Code, egal was es ist?
Es ist in einer modularen OO-Mode geschrieben, so dass Entwickler das Framework einfach verfolgen und unabhängig voneinander Prüfungen schreiben können. Jedes Objekt enthält ein gemeinsames Berichtsobjekt, das nach der Überprüfung einfach $ self -> {'reporting'} -> report (params) anzeigt. Die Parameter sind definiert und es wird angenommen, dass die Entwickler angemessen berichten. Das Berichtsobjekt indiziert diese Berichte dann. Mein Haupt loader Skript enthält Einträge wie die folgenden:
my $reportingObject = new Checks::Reporting(params);
my @checks;
push @checks, new Checks::Check_One($reportingObject, params));
push @checks, new Checks::Check_One($reportingObject, params));
.
.
push @checks, new Checks::Check_N($reportingObject, params));
Um die Kontrollen zu beginnen und den Bericht abzuschließen, sobald sie fertig sind, ich habe zu tun:
foreach my $check (@checks) {
$check->run_stuff();
}
$reportingObject->finalize_report();
Nun, da diese Kontrollen sind völlig unabhängig (Mach dir keine Sorgen über das Berichtsobjekt) sie können parallel ausgeführt werden. Als eine Verbesserung habe ich getan:
my @threads;
foreach my $check (@checks) {
push @threads, async { $check->run_stuff(); }
}
foreach my $thread (@threads) {
$thread->join;
}
#All threads are complete, and thus all checks are done
$reportingObject->finalize_report();
Wie ich schon sagte, die Entwickler schreiben Checks unabhängig voneinander. Einige Überprüfungen sind einfach und andere nicht. Die einfachen Überprüfungen können nicht asynchronen Code in ihnen, aber andere könnten asynchron intern wie
sub do_check {
my @threads;
my @list = @{$self->{'list'}};
foreach my $item (@list) {
push @threads, async {
#do_work_on_$item
#return 1 or 0 for success or fail
};
foreach my $thread (@threads) {
my $res = $thread->join;
if($res == 1) {
$self->{'reporting'}->report(params_here);
}
}
}
}
ausführen müssen Wie Sie das Threading-Modell sehen können mir Dinge in sehr vage zu tun erlaubt. Jedes "Check", egal was es ist, läuft unabhängig in seinem eigenen Thread. Wenn ein einzelner Entwickler asynchrone Aufgaben zu erledigen hat, egal was es ist, macht er es einfach unabhängig in seinem eigenen Thread. Ich möchte ein ähnliches Modell.
Leider sind die Threads langsam und ineffizient. Alle Async-Bibliotheken haben spezielle Beobachter wie IO usw. Ich möchte nichts Spezifisches. Ich hätte gerne ein ereignisbasiertes Modell, das es mir ermöglicht, einfach asynchrone Aufgaben zu starten, ganz gleich, was sie sind, und einfach zu benachrichtigen, wenn alles erledigt ist, damit ich weitermachen kann.
Hoffentlich erklärt das und Sie können mir in die richtige Richtung zeigen.
Nur eine Stilnote, es ist eine gute Idee, [indirekte Objekt-Syntax] zu vermeiden (http://modernperlbooks.com/mt/2009/08/the-problems-with-indirect-object-notation.html) – friedo
AFAIK "async libraries" arbeiten immer als "do special IO" und dann "call func, der IO-Ergebnisse sammelt" –
Was meinen Sie mit "Threads sind langsam und ineffizient"? Warum verwenden Sie eine asynchrone Bibliothek, wenn Sie dies mit dem [builtined threading] (http://perldoc.perl.org/threads.html) tun könnten? –