[Moscow.pm] Coro + AnyEvent --- Что не так

Гришаев Анатолий agrishaev на gmail.com
Пт Окт 16 03:22:46 PDT 2015


15 октября 2015 г., 23:55 пользователь Ivan Petrov <i.petro.77.00 на gmail.com>
написал:

>
> > did you try to block inside an event loop callback?
>
> основная идея - из калбаков AE не делать ничего кроме уведомлений.
>
> соответственно что нельзя делать
>  - писать в Channel
>  - трогать что угодно что может позвать cede/schedule
>

Это понял.

>
> то есть идеология такая
>
>  - если пишем однократный ожидальщик то используем стандартный
>    механизм Coro::rouse_*
>

Не подходит, хотелось бы не однократно получать подключения по сети.


>  - если пишем многократный ожидальщик (например сервер), то лучше
>    всего использовать совокупность schedule + ready
>



>
> то есть заводим
>
> my $watcher;
> my @tasks;
>
>
> sub do_task {
>     тут можно создавать async, писать в каналы итп
> }
>
> async {
>     while (1) {
>         $watcher = $Coro::current;
>         Coro::schedule;
>         while(@tasks) {
>             do_task(shift @tasks);
>         }
>     }
> };
>
> В калбеке приема соединения как-то так:
>
> sub {
>     my ($fh) = @_;
>     push @tasks => $fh;
>     $watcher->ready if $watcher;
>     $watcher->undef;
> }
>

А вот тут я завис.

Вылетает с ошибкой DEADLOCK detected.
Зависает на Coro::schedule.

Переписал на Coro::Socket.
======================================
use Coro;
use Coro::Signal;
use Coro::AnyEvent;
use Coro::Handle;
use Coro::Socket;
use AnyEvent::Socket qw(tcp_server);


my @msg;
my $sem = Coro::Signal->new();
my $l = Coro::Socket->new( LocalPort => 2000, Listen => 1, ReuseAddr=>1 );
while () {
        my $fh = $l->accept();
        my $no = fileno $fh;
        Coro::async {
                while ( defined( my $line = $fh->readline ) ) {
                        chomp $line;
                        push @msg, "$no $line";
                        $sem->broadcast();
                }
        };
        Coro::async {
                my $i = @msg;
                while () {
                        $sem->wait();
                        while ( $i < @msg ) {
                            my $id = (split " ", $msg[$i],2)[0];
                            $fh->print("$msg[$i]\n") if $id ne $no;
                            ++$i;
                        }
                }
        };
}
====================================

Т.е. проблему свою я решил, но не так гладко как хотелось.
Остался вопрос можно ли совместить обычные повторяющие колбэки с Coro,
чтобы например
сервер написаный на голом AnyEvent использоватьс Coro без его переписывания
к примеру tcp_server.

Есть ли рабочие примеры?




> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20151016/59489b05/attachment-0001.html>


Подробная информация о списке рассылки Moscow-pm