неділя, 12 жовтня 2014 р.

Модифицируем AnyEvent::PacketReader

После продолжительных поисков ошибки в Erlang SMPP клиенте, который сам же и написал на основе oserl, ошибка нашлась в свеженаписанном сервере на основе AnyEvent::PacketReader.
Даже не ошибка. Скорее это фича, но меня она не устроила.

Итак, PacketReader замечательно работает, когда надо отвечать на входящие запросы. Но протокол SMPP подразумевает и исходящие запросы в сторону подключившегося клиента тоже.

Что я только не перепробовал. И timer подключал, и пытался генерировать события на основе входящих пакетов. Не получилось ни разу. Код работал, но в определенное время зависал, потому что сокет был намертво заблокирован.

Приходиться доставать рашпиль. our $debug = 1 внутри AnyEvent::PacketReader и очень быстро находится следующий код:
<code>
sub resume {
    my $data = ${shift()};
    if (defined(my $fh = $data->[1])) {
        $data->[2] = AE::io $fh, 0, sub { _read($data) };
    }
}
</code>

Раз тут используется AnyEvent::IO, то что мне мешает на этом же уровне добавить и timer ? Подумал я и сделал следующий ход:

<code>
sub resume {
    my $data = ${shift()};
    if (defined(my $fh = $data->[1])) {
        $data->[2] = AE::io $fh, 0, sub { _read($data) };
        $data->[11] =  AnyEvent->timer ( after => $data->[10], interval => $data->[10], cb => $data->[9] );
    }
}
</code>

data->[10] = 1; data->[9] = sub { warn "Timer ring-ring."; }; data->[11] = undef (будущий watcher, по аналогии к data->[2];

Предварительные тесты показали работоспособность такого варианта. Продолжение следует.

Немає коментарів:

Дописати коментар