Quanto aos leaks: existe um módulo especialmente voltado para detecção de
leaks em aplicativos feitos com AnyEvent, Devel::Leak::Cb (nunca cheguei a
usar; mas, em todo caso...)
Me corrija se eu estiver errado, mas o seu aplicativo é uma espécie de um
daemon, que só pára quando mandarem parar, correto? Se for o caso,
conditional variables se tornam irrelevantes. O propósito dos
AnyEvent->condvar é criar "checkpoints". Isso é, sincronizar o que é
assíncrono. Isso somente se faz necessário quando existe interdependência
de dois (ou mais) fluxos. Exemplo: você dispara ping para vários hosts e
reporta o de menor latência ("checkpoint": todos precisam retornar ou dar
timeout). Outro exemplo: baixar uma fila de N URLs em paralelo, sem exceder
K conexões simultâneas ("checkpoint" periódico: verificar se K == conexões
ativas e tomar providências).
Agora, um servidor HTTP seria um contra-exemplo: os requests não dependem
um do outro (sorry, Microsoft).
Resumindo a história: você pode muito bem criar um único $cv =
AnyEvent->condvar; e depois de inicializar todos os callbacks, dar um único
$cv->recv. E o único cara que enviará o $cv->send será um hook no SIGTERM.
Já os guards dos streams, você está fazendo isso certo. Mantenha-os num
hash e apague-os conforme perecem.P.S. - assumi várias coisas idiossincráticas para mim aqui; não que seja a melhor forma para resolver o seu problema, mas é por onde eu começaria :) ABS() 2013/2/22 Solli Honorio <[email protected]> > > Estou com um sistema que abre vários stream no twitter e fica processando > cada retorno, para isto estou utilizando o AnyEvent::Twitter::Stream. > > Uma versão simplificada do meu código é assim : > > <code> > use common::sense; > use AnyEvent; > use AnyEvent::Twitter::Stream; > > # Definição de variáveis globais > my %process > my %CONFIG = load_from_database_my_configuration(); > > my $done = AnyEvent->condvar; > > for my $key ( keys %CONFIG ) { > $process{$key}{twitter} = create_twitter_stream( $key, $CONFIG{$key} ); > } > > # running > > > sub create_twitter_stream { > my ($key, $config) = @_; > > # cria uma transação para este stream > $done->begin; > > return AnyEvent::Twitter::Stream->new( > consumer_secret => $config->{consumer_secret}, > consumer_key => $config->{consumer_key}, > token => $config->{access_token}, > token_secret => $config->{access_token_secret}, > method => 'filter', > track => $config->{terms}, > timeout => 60, > on_error => sub { > $done->end; > delete $process{$key}; > # must do something to re-load this > stream > must_reload_this_stream($key); > }, > on_tweet => sub { # do something }, > on_keepalive => sub { # do something }, > on_connect => sub { # do something }, > ); > } > > sub must_reload_this_stream { > my $key = shift; > > $process{$key}{twitter} = create_twitter_stream( $key, $CONFIG{$key} ); > } > </code> > > A minha dúvida é como reiniciar o stream que gerou o erro. Antes eu estava > desviando o fluxo através do $done->send($key), e depois pegava o valor > enviado pelo sendo em outro ponto. O problema é que o 'send' desvia todo o > processo do AE, inclusive de quem está trabalhando bem. > > Então resolvi utilizar o begin/end, conforme sugestão do Stan. Como ficou > no exemplo acima, então eu apago a chave do hash referente ao evento. > > Da maneira como estou fazendo tem risco de criar um memory leak ? Stan, > estou fazendo da maneira correta pensando em AE ? > > Obrigado, > > Solli Honorio > > -- > "o animal satisfeito dorme". - Guimarães Rosa > > =begin disclaimer > Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ > SaoPaulo-pm mailing list: [email protected] > L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> > =end disclaimer > >
=begin disclaimer Sao Paulo Perl Mongers: http://sao-paulo.pm.org/ SaoPaulo-pm mailing list: [email protected] L<http://mail.pm.org/mailman/listinfo/saopaulo-pm> =end disclaimer
