Schrift
[thread]6523[/thread]

[POE] Subaufrufe

Tags: Ähnliche Threads

Leser: 3


<< |< 1 2 >| >> 12 Einträge, 2 Seiten
eisbeer
 2004-08-22 17:22
#49556 #49556
User since
2003-08-29
347 Artikel
BenutzerIn
[Homepage] [default_avatar]
Und wieder ich ;)

Ich benutze momentan POE für ein ziemlich vielseitiges Server
Programm. Und da dieses viele Dinge (nicht nur Client annehmen
und irgendwas zurückschicken, sondern z.B. von einem serielen
Port Daten holen, alle paar Minuten ein paar verzeichnisse aus-
lesen und und und) erledigen muss, die nicht gleichzeitig laufen
können, habe ich mir gedacht, mache ich eine JobQueue-Session.
So die Sessioninititierung:
Code: (dl )
1
2
3
4
5
6
# Jobprocessor
  POE::Session->create( inline_states => {
                                       _start => \&init_processor,
                                       _stop  => \&clean_processor,
                                       iter   => \&iter_processor,
                                       addjob => \&add_job });

So die Subs:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
sub init_processor {
   my ($kernel, $heap) = @_[ KERNEL, HEAP ];
   $poe_kernel->alias_set( 'prc' );
   $heap->{'JobList'} = [];

   $kernel->yield('iter');
}

sub clean_processor {
   my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
   delete $heap->{'JobList'};
}

sub iter_processor {
   my ($kernel, $heap) = @_[ KERNEL, HEAP ];
   my $Job = shift    @{$heap->{'JobList'}};

   print &{$Job->{'Sub'}}(@{$Job->{'Args'}}); # print $Job->{'Sub'}; ergibt CODE(0x1234567)
   
   $kernel->yield('iter') if (scalar @{$heap->{'JobList'}});
}

sub add_job {
   my ($kernel, $heap, @arg) = @_[ KERNEL, HEAP, ARG0 .. ARG9 ];
   push @{$heap->{'JobList'}}, { Name  => $arg[0],
                                 Sub   => $arg[1],
                                 Args  => $arg[2] };
   $kernel->yield('iter');
}

Aufruf:
Code: (dl )
$_[KERNEL]->post('prc','addjob','CheckInbox',\&CheckInbox,[$SerialHandle]);


Geht nicht, kommt sich Fehler:
Quote
Tk::Error: Undefined subroutine &main:: called at server.gpl line 195, <DATA> line 164.
Tk::After::once at G:/perl/site/lib/Tk/After.pm line 83
[once,[{},undef,100,once,[\&POE::Kernel::_poll_for_io]]]
("after" script)


Wie bekomm ich das dann hin? Bzw. wieso kennt er auf einmal
die Subroutine nicht mehr?\n\n

<!--EDIT|eisbeer|1093181281-->
Die meisten PC Probleme befinden sich zwischen Bildschirm und Stuhl...
sri
 2004-08-23 12:59
#49557 #49557
User since
2004-01-29
828 Artikel
BenutzerIn
[Homepage] [default_avatar]
Verbindest du da POE mit Tk?
Wenn das der Fall ist hast du die falschen Code Schnipsel gepostet.\n\n

<!--EDIT|sri|1093251624-->
eisbeer
 2004-08-23 19:37
#49558 #49558
User since
2003-08-29
347 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja, ich benutze es in Verbindung, ich habe aber nicht den falschen Codeschnippsel gepostet.
Der Fehler, den ich am Ende gepostet hab, kommt genau so. Ich hab keine Ahnung wieso...

Und wenn ich widererwarten deiner Meinung nach die falschen Schnippsel gepostet habe,
wärs recht nett wenn du mir sagen würdest, was du erwartest ;).

Achja: Der Fehler tritt auch auf, wenn ich das ganze ohne
Tk ausführe, nur sieht der Fehler dann so aus:

Code: (dl )
Undefined subroutine &main:: called at G:\Apache\root\public\projekte\SMgwd\Server\v0.20\server.gpl line 252, <DATA> line 164.
\n\n

<!--EDIT|eisbeer|1093275779-->
Die meisten PC Probleme befinden sich zwischen Bildschirm und Stuhl...
renee
 2004-08-23 20:34
#49559 #49559
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Und was steht in der Zeile 252 von server.gpl??
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
eisbeer
 2004-08-23 21:00
#49560 #49560
User since
2003-08-29
347 Artikel
BenutzerIn
[Homepage] [default_avatar]
Oh entschuldigung, hab ich vergessen zu posten, hab es sogar noch in der Zwischenablage:
Code: (dl )
print &{$Job->{'Sub'}}(@{$Job->{'Args'}}); # print $Job->{'Sub'}; ergibt CODE(0x1234567)

Siehe den code oben im Zusammenhang (sub iter_processor).

Eine Session übergibt per $kernel->post einer anderen Session (namens 'pcr', s. ebenfalls. o.) den
Befehl für "addjob" und zwar mit den Parametern Name (Name des Jobs, nur zum Logschreiben bzw.
Bildschirmausgabe und Debug), Sub (eine Referenz auf eine "globale" Subroutine, die schon ganz am
Anfang des Skripts steht) und diverse Parameter als Arrayref.
Der state "addjob" pusht einen Hahsref mit den ganzen Daten in einen Array (JobList) im HEAP von der Session
'pcr' und schubst den Jobabarbeiter iter_processor an, wieder anzufangen die Jobs in jenem Array $heap->{'JobList'}
abzuarbeiten. Und jetzt soll der die bis dahin erfolgreich übergebene Referenz auf den auszuführende Sub (im
obigen Beispiel die Subroutine &CheckInbox) auch ausführen. Tut er aber nicht, er sagt das es die Subroutine
"" (=> leer) nicht gibt (siehe wiederum oben (=>Fehlermeldung)).

Alle Klarheiten beseitigt ? ;)

Warum tut er's aber nicht?
Die meisten PC Probleme befinden sich zwischen Bildschirm und Stuhl...
ptk
 2004-08-23 21:17
#49561 #49561
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Das einfache Skript
Code: (dl )
1
2
3
$Job->{Sub} = sub { join "_", @_ };
$Job->{Args} = [1,2,3];
print &{$Job->{'Sub'}}(@{$Job->{'Args'}}); # print $Job->{'Sub'}; ergibt CODE(0x1234567)
funktioniert wie erwartet. Vielleicht wird print irgendwo ueberladen und macht Schweinereien? Geht es, wenn du den Sub-Aufruf seperat in einen String schreibst und diesen ausgibst?
eisbeer
 2004-08-23 21:53
#49562 #49562
User since
2003-08-29
347 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja das einfach skript wie du es hast funzt bei mir au, auch wenn ich die Funktion
ganz normal in die Subroutine schreibe funktioniert sie.

Der Fehler kommt auch, wenn ich die Funktion ausführe ohne ihren return wert zu
printen (Also einfach das print weglasse ;) ). Ich denke inzwischen, dass das was
mit der POE Technologie zu tun hat. Ich versteh aber nicht warum, ich finde auhc
nichts in der Doku...

Hat jemand ne Idee, wie ich das umgehen könnte?
Die meisten PC Probleme befinden sich zwischen Bildschirm und Stuhl...
ptk
 2004-08-23 22:11
#49563 #49563
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Code: (dl )
print $Job->{'Sub'}; ergibt CODE(0x1234567)

Vielleicht $Job->{'Sub'} hier bereits die "stringification" der Referenz? Was gibt denn
Code: (dl )
ref $Job->{'Sub'}
aus (es muesste CODE sein)?

Wenn nicht, dann ist das vielleicht ein Fall fuer B::Deparse...\n\n

<!--EDIT|ptk|1093284675-->
eisbeer
 2004-08-24 03:58
#49564 #49564
User since
2003-08-29
347 Artikel
BenutzerIn
[Homepage] [default_avatar]
Während ich diesen Post geschrieben habe bin ich genau auf die gleiche Idee gekommen.
ref $Job->{'Sub'} ergibt: CODE :(

Von B::Deparse (bzw. überhaupt B) habe ich immer erfürchtig Abstand gehalten, wenn du
mir auf die Springe helfen könntest (=näheres erklären), wär' ich dir echt dankbar... ;)
Die meisten PC Probleme befinden sich zwischen Bildschirm und Stuhl...
ptk
 2004-08-24 12:40
#49565 #49565
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Es sieht aus, als ob irgendwo im POE-Framework deine Subroutine verloren geht, weil sie nicht richtig serialisiert/deserialisiert werden konnte. Evtl. gibt es gar keine Unterstuetzung fuer Referenzen oder es gibt nur keine Unterstuetzung fuer CODE-Referenzen.

Mit B::Deparse koenntest du den Sourcecode der Subroutine erzeugen und irgendwo ablegen. Dann koenntest du auf der anderen Seite ein eval() oder vielleicht besser (da sicherer) ein Safe::reval machen, um die Subroutine wieder zu erhalten. Das machen z.B. auch Data::Dumper (wenn $Deparse auf wahr gesetzt ist) und Storable (ebenso).

Anwendung:
Code: (dl )
perl -l -MB::Deparse -e '$sub = sub { print "Hallo, Welt!" }; print "sub " . B::Deparse->new->coderef2text($sub)'
ergibt
Code: (dl )
1
2
3
sub {
print 'Hallo, Welt!';
}
. B::Deparse ist nicht perfekt. In seltenen Faellen wird falscher Sourcecode erzeugt. Ausserhalb definierte lexikalische Variablen sind nach dem Deserialisieren normalerweise nicht sichtbar.
<< |< 1 2 >| >> 12 Einträge, 2 Seiten



View all threads created 2004-08-22 17:22.