[SP-pm] Duvida em fluxo de controle com o AnyEvent
Stanislaw Pusep
creaktive at gmail.com
Sat Feb 23 06:35:48 PST 2013
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 <shonorio em gmail.com>
>
> 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: SaoPaulo-pm em pm.org
> L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
> =end disclaimer
>
>
-------------- Pr�xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20130223/5927a85d/attachment-0001.html>
More information about the SaoPaulo-pm
mailing list