[Cascavel-pm] script cgi de longa execucao

Luis Motta Campos luismottacampos em yahoo.co.uk
Sábado Fevereiro 9 02:14:30 PST 2008


Matheus Barros wrote:
> Obrigado Nilson!
> 
> tipow...eu nao sou programador avançado em Perl...tudo q aprendi foi 
> pelo livro do Deitel... eu utilizo essa linguagem para um trabalho de
> iniciacao cientifica....

Bom, pequenas dicas para enriquecer a sua iniciação científica e o seu
CV: não use gíria, que aqui não é apropriado. Regionalismos passam, mas
a gente tem potencial para ter problemas sérios para se entender. Tem
programadores Perl lendo isto de todas as partes do Brazil, até onde eu
tenho notícias.

Outra coisa: o Deitel é um bom /teaser/, ele consegue provocar vontade
de ler. Mas isso não quer dizer que ele é uma boa fonte de aprendizado.
A gente costuma recomendar o Livro do Camelo:

Programming Perl
Larry Wall, Tom Christiansen, Jon Orwant
O'Reilly, Jul/2000
ISBN 0-596-00027-8
http://www.oreilly.com/catalog/pperl3/

Sim, tem traduções em Português, se você preferir.
Sim, você vai conseguir encontrar ele na biblioteca da faculdade. :)
Sim, você pode usar seus privilégios de Aluno de Iniciação Científica
para descolar uma cópia para você.

E uma última coisa: não peça desculpas por não saber: até onde eu sei, 
não saber não é crime. Ninguém aqui nasceu sabendo Perl. A gente aprende 
e ensina, não necessáriamente mais uma coisa ou outra, e não 
necessáriamente nesta ordem ;)

> Se você tivesse algum exemplo eu agradeceria.

Bom, você pode começar com o que o MDA(1) mandou para você no outro
email, lendo sobre "Inter Process Communication" ("perldoc perlipc" no
shell do seu *nix);

Depois, tem o CPAN (2), de onde você pode puxar peças úteis como esta:

http://search.cpan.org/~ehood/Proc-Daemon-0.03/Daemon.pm

(leia o manual do módulo "CPAN" com o comando "perldoc CPAN" para 
entender como obter software a partir do CPAN).

Assim, a tua interface com o usuário fica separada (confinada do sistema
de CGI), e não precisa fazer trabalho pesado. Ela apenas recebe os dados
iniciais do usuário (um genoma para ser comparado, por exemplo), guarda
eles de alguma forma (ou transmite diretamente para o "Daemon" que você
tem rodando na máquina) e diz para o usuário "ok, eu aceitei a tarefa
que você me deu. Volta mais tarde que eu tenho resultado". Não se
esqueça de providenciar um número para identificar a tarefa que foi
recebida.

Quando o Daemon vê uma nova tarefa de comparação de genoma vindo do
programa CGI, ele cria um novo processo (com "fork()", leia a
documentação com o comando "perldoc -f fork" no seu shell), passa o
genoma que ele recebeu, e volta a aguardar um novo pedido.

O processo "filho" (que foi criado sob demanda pelo Daemon para atender
à tarefa) faz a comparação do genoma apresentado com os que ele tem
armazenados (deve ser uma base de dados, não?), chega no resultado que
ele precisa, armazena este resultado em algum lugar (de onde o CGI vai
conseguir pegar mais tarde para mostrar ao usuário) e termina.

Finalmente, quando o usuário volta com a identificação de tarefa dele, o
CGI pode encontrar o resultado final do processamento para aquela tarefa
e mostrar o resultado, quantas vezes forem necessárias.

Finalmente, ação:

#!/usr/bin/perl
use strict;
use warnings;

use Proc::Daemon;
Proc::Daemon::Init;
# Deste ponto em diante, somos um "Daemon Unix": não tenho acesso
# a I/O para terminais, e apenas posso abrir e fechar arquivos
# e iniciar processos novos.

# eu sento num loop e olho a vida passar:
while( sleep $tempo ){
   # Olho para a base de dados para saber se tem novas tarefas
   my @new_jobs = check_for_new_jobs;
   # para cada nova tarefa que tem, crio um processo filho
   foreach my $job ( @new_jobs ) {
     # Os processos-filho se encarregam de executar a comparação
     my $process_id = fork_child_to_process( $job );
     # mantenha algum controle sobre os teus processos-filho.
     # Este é simples e bobo. Você precisa de coisa melhor aqui.
     push @running_jobs, $process_id;
   }
}

# Olha para um banco de dados para saber se tem novas tarefas
# EU NAO TRATEI ERROS DE BASE DE DADOS E NAO FIZ LOGGING DE ATIVIDADE
# VOCE PRECISA IMPLEMENTAR ESTAS COISAS OU VAI FICAR LOUCO
sub check_for_new_jobs {

   # rotina básica de base de dados:
   my $dbi = DBI->connect( $dsn, $user, $password );
   my $sth = $dbi->prepare( q{SELECT * FROM Jobs WHERE status = 'new'} );
   $sth->execute;

   # Isto é didático, mas podia ter sido feito em uma linha.
   my @jobs;
   while( my $job_info = $sth->fetchrow_arrayref ) {
     push @jobs, $job_info;
   }
   return @jobs;
}

sub fork_child_to_process {
   my $job = shift;
   if( my $pid = fork ){
     # sou o pai, tenho um Process ID.
     return $pid;
   }else{
     # Eu sou o filho, executo a tarefa
     execute_job( $job );
   }
}

sub execute_job {
   my $job = shift;
   # Job é uma linha da base de dados que contém
   # a especificação do que eu tenho de fazer.

   # Aqui você precisa implementar o teu processo de
   # comparação de genoma, eu não sei que método você está usando,
   # e assim não vou escrever nada nesta função.

   return $resultado;
}

__END__

Eu espero que isso te ajude.
Eu sei que você vai ter milhões de perguntas depois de ler isso. E eu
sei também que isso "parece" praticamente todo o teu trabalho de
iniciação científica. Mas não é. Ainda tem muita coisa para resolver e
muita coisa para implementar. Não se empolgue muito, e continue
perguntando na lista.

Ah, e pare de ler a !@#$@%&* do livro do Deitel. :)

Quando você perguntar coisas daqui para frente, tenha certeza de que
você tem algum código para mostrar também. ;) Estimula a gente saber que
você está tentando se virar.

Boa sorte.
Putamplexos!
-- 
Luis Motta Campos (a.k.a. Monsieur Champs) is a software engineer,
Perl fanatic evangelist, and amateur {cook, photographer}

(1) Marco A P D'Andrade, um dos caras que respondeu para você.
(2) Comprehensive Perl Archive Network - Um monte de bibliotecas muito
úteis e que resolvem 90% dos problemas, organizadas de uma maneira mais 
ou menos útil. E viva a "preguiça" (do tipo saudável!) 
http://search.cpan.org/


Mais detalhes sobre a lista de discussão Cascavel-pm