/ / È possibile creare qualcosa come longjump in Perl all'interno dei richiami EV? - perl, anyevent, dbd-pg

È possibile creare qualcosa come longjump in Perl all'interno dei richiami EV? - perl, anyevent, dbd-pg

Sto cercando di emulare il flusso di controllo sincrono in un ambiente asincrono.

Lo scopo è supportare le richieste DB senza callback o blocchi su richiesta.

Sto cercando di usare il Coro modulo, ma penso di non capirlo completamente.

Ecco i frammenti di codice:

sub execute {
my ($sth, @vars) = @_;

my $res   = $sth->SUPER::execute(@vars);
my $dbh   = $sth->{Database};
my $async = new Coro::State;
my $new;
$new = new Coro::State sub {
my $w;
while (!$dbh->pg_ready) {
$w = AnyEvent->io(
fh   => $dbh->{pg_socket},
poll => "r",
cb   => sub {
if($dbh->pg_ready) {
$w = undef;
$new->transfer($async);
}
}
) if not $w;
print "run once before statement: $sth->{Statement}n";
EV::run EV::RUN_ONCE;
}
};
$async->transfer($new);
$res = $dbh->pg_result;
$res;
}

Ecco il codice di test:

my $cv = AE::cv;

ok(my $dbh = db_connect(), "connected");
ok(my $sth = $dbh->prepare("select pg_sleep(2)"), "prepared");

my $start_time = time;
ok($sth->execute(), "executed");

my $duration = time - $start_time;
ok(($duration > 1 && $duration < 3), "slept");
is(ref($dbh), "DBIx::PgCoroAnyEvent::db", "dbh class");
is(ref($sth), "DBIx::PgCoroAnyEvent::st", "sth class");

my $status   = 0;
my $finished = 0;

for my $t (1 .. 10) {
$finished += 1 << $t;
}

for my $t (1 .. 10) {

my $timer;

$timer = AE::timer 0.01 + $t/100, 0, sub {

ok(my $dbh = db_connect(), "connected $t");
ok(my $sth = $dbh->prepare("select pg_sleep(" . $t . ")"), "prepared $t");
my $start_time = time;
ok($sth->execute(), "executed $t");

my $duration = time - $start_time;
ok(($duration > $t - 1 && $duration < $t + 1), "slept $t");

print "duration: $t: $durationn";

$status += 1 << $t;
if ($status == $finished) {
$cv->send;
}

undef $timer;
};
}

$cv->recv;

Il modulo completo e gli script di test sono qui DBIx::PgCoroAnyEvent e qui 01_sleeps.t

Qualcuno può dare un'occhiata e spiegarmi cosa c'è che non va?

risposte:

0 per risposta № 1

eval + die è il metodo tipico in Perl.

eval { some_function( @args ); };
if( $@ ){
# caught longjmp
}
...
sub some_function {
...
if( some_condition ){
die "throw longjmp"
}
...
}