<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">22 сент. 2016 г., в 12:39, Ruslan Zakirov <<a href="mailto:ruslan.zakirov@gmail.com" class="">ruslan.zakirov@gmail.com</a>> написал(а):</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">2016-09-22 11:16 GMT+03:00 Eugene Ponizovsky <span dir="ltr" class=""><<a href="mailto:ponizovsky@gmail.com" target="_blank" class="">ponizovsky@gmail.com</a>></span>:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Руслан, если я правильно все рассчитал, то этот callback не будет вызван, если не осталось ни одной нормальной ссылки на $self, так как сам callback помещается в $self далее по коду, и он будет уничтожен вместе с последней ссылкой на объект клиента. Есть ли у Вас пример, в котором это приводит к ошибке?</blockquote></div><br class="">Возможно вы правы. Это были домыслы на основе чтения кода.</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Вот натолкнулся на более актуальную проблему и это уже в тестах:</div><div class="gmail_extra"><p class="gmail-p1"><span class="gmail-s1">EV: error in callback (ignoring): Can't call method "_process_reply" on an undefined value at /Users/ruz/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/AnyEvent/RipeRedis.pm line 448, <DATA> line 2231.</span></p><div class=""></div></div></div></div></blockquote><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="">Хм. Да, действительно. При некоторых случаях ошибка воспроизводится. Внес небольшой фикс. Спасибо за репорт.</div><div class=""><a href="https://cpan.metacpan.org/authors/id/I/IP/IPH/AnyEvent-RipeRedis-0.27_01.tar.gz" class="">https://cpan.metacpan.org/authors/id/I/IP/IPH/AnyEvent-RipeRedis-0.27_01.tar.gz</a></div><div class=""><br class=""></div></div></div></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra">Это как раз случилось из-за того что клиент прибиваю раньше времени. Ошибка конечно у меня, но она не привела к "Client object destroyed prematurely."</div>







<div class="gmail_extra"><br class=""></div><div class="gmail_extra">Кстати как вы это решаете у себя? Я в большинстве случаев создаю коннект, выполняю ряд операций без callback'а и только на после последней передаю callback, где резолвлю promise (дергаю переданный callback). В некоторых случаях совсем нетривиально подсчитать какая команда будет последней.<br clear="all" class=""><div class=""><br class=""></div></div></div></div></blockquote><div><br class=""></div><div>Если выполнять простые операции (get, set, incr и т.д.), то последовательность их выполнения совпадает с последовательностью вызова методов в коде, так как они все выполняются через один коннект. Но для составных операций (например для такой как eval_cached), последовательность выполнения может быть другой, так как под капотом может быть выполнено две команды EVALSHA и следом EVAL.</div><div><br class=""></div><div>В общем случае синхронизировать асинхронные операции можно через счетчик операций. Например так:</div><div><br class=""></div><div><div>my $oprn_num  = 10; </div><div>my $reply_cnt = $oprn_num;</div><div>my @errors;</div><div><br class=""></div><div>my $cv = AE::cv;</div><div><br class=""></div><div>my $cb = sub {</div><div>  my $reply = shift;</div><div>  my $err   = shift;</div><div><br class=""></div><div>  if ( defined $err ) { </div><div>    push( @errors, $err );</div><div>  }</div><div><br class=""></div><div>  return if --$reply_cnt > 0;</div><div>  </div><div>  if ( @errors ) { </div><div>    # обработка ошибок</div><div>  }</div><div>  else {</div><div>    # выполняем код, который нужно выполнить, когда все асинхронные операции</div><div>    # успешно выполнены.</div><div>  }</div><div><br class=""></div><div>  $cv->send;</div><div>};</div><div><br class=""></div><div>foreach ( 1 .. $oprn_num ) { </div><div>  $client->execute( $cb );</div><div>}</div><div><br class=""></div><div>$cv->recv;</div></div><div><br class=""></div><div>Или воспользоваться таким модулем как Future <a href="https://metacpan.org/pod/Future" class="">https://metacpan.org/pod/Future</a></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra">-- <br class=""><div class="gmail_signature">Best regards, Ruslan.</div>
</div></div>
-- <br class="">Moscow.pm mailing list<br class=""><a href="mailto:moscow-pm@pm.org" class="">moscow-pm@pm.org</a> | <a href="http://moscow.pm.org" class="">http://moscow.pm.org</a><br class=""></div></blockquote></div><br class=""></body></html>