Controlo de uso de CPU em perl

Fica aqui o codigo que escrevi simples mas modular o suficiente para ser replicado por mais pessoas.

GPLv2

Desculpem a mistura de Inglês com o Português.


#
# Verificar o tempo de idle do cpu e agir de acordo
#
# @version $Id: idletime.pm 5432 2011-05-05
#
#

# Permitir um tempo maximo de idle de x segundos
# Definir o tempo permitido em idle por esta var
#
our $processcount_cpuallowidletime = 120;
# Maximo de tempo que o processo ira ficar com controlo de idle time
our $processcount_cpuallowtotalidletime = 500;

# dormir durante x tempo porque o processo esteve sem fazer nada
our $process_sleeptime = 2;

#
# Guardar dados sobre idle process count
#
# Estrutura de dados para indicar o tempo de idletime
#
our %idletime = (
start => 0,
end => 0,
total => 0,
);

# $processcount pertence ao ficheiro "main" e nao deve ser definido aqui
# esta var indica se o processo esta a fazer algo se > 0

=item checkidle

Called function to validate idle time

=cut

sub checkidle {
if ($DEBUG > 0 ) {
syslog("debug", "inicio Verificar idle time pcount=".$processcount." t=".$idletime{'total'}." allow=".$processcount_cpuallowidletime." pslp=".$process_sleeptime);
}

if ($processcount == 0 ) {

if ( $idletime{'start'} == 0 ) {
$idletime{'start'} = time();
}

$idletime{'end'} = time();

$idletime{'total'} = $idletime{'end'} - $idletime{'start'};

}

if ($idletime{'total'} > $processcount_cpuallowidletime ) {
$process_sleeptime = $process_sleeptime*2; # recalculate value of sleep time
if ($DEBUG > 0 ) {
syslog("debug", "A dormir durante ".$process_sleeptime." seconds...");
}
syslog("info", "Sleeping:".$process_sleeptime);
sleep($process_sleeptime);
}

if ( ($processcount > 0 || $idletime{'total'} > $processcount_cpuallowtotalidletime) && $idletime{'start'} != 0 ) {
resetIdleTime();
}

if ( $DEBUG > 0 ) {
syslog("debug", "fim Verificar idle time ".$processcount." ".$idletime{'total'}." ".$processcount_cpuallowidletime);
}

if ($process_sleeptime > $processcount_cpuallowtotalidletime ) {
$process_sleeptime = 1;
}
}

=item resetIdleTime()

Reset idle time counters

=cut

sub resetIdleTime {
$idletime{'start'} = 0;
$idletime{'end'} = 0;
$idletime{'total'} = 0;
}

1;

Fecho do ano de 2010

Se 2009 foi um ano de mudanças 2010 não lhe ficou atrás.

Tive uma prenda fantástica em Setembro apesar de não ser o meu aniversário, prenda de 3.296kg e 51 cm de comprimento, algo fantástico e uma esposa que se revelou uma excelente mãe com a ajuda de um excelente pai 😛 , dos 3.296kg para 5.625kg e dos 51cm para os 60cm de hoje foram 3 Meses fantásticos nesse aspecto toda a evolução (adoro a evolução), o agarrar o rir o espernear-se quando quer colo, “levantar-se” a procura e reclamação pela constante atenção, o alimentar-se de duas em duas horas o evitar que os pais(principalmente a mãe) se afastem durante mais que 1 minuto é no fundo fantástico.

Entre várias complicações monetárias no final podemos dizer que tudo correu como tinha de correr 😛 (isto não diz nada). Iva a +2% aí vamos nós. Pedido de factura sempre que compro algo tornou-se um MUST estou farto de pagar pelos outros.

Em termos de trabalho o projecto no qual estou inserido tem corrido bem apesar dos solavancos chegou a um ponto estável da aplicação em que permitiu fazer melhoramentos que não tinha tempo nem oportunidade para fazer no principio e não era prioritário naquele momento.

Apercebi-me que quanto mais codigo mantenho comentado é mais provavel que o que eu estou
a fazer não seja 100% seguro.
Os testes unitários nem sempre ajudam a prever todos os problemas os issues de conectividade foram um caso desses ( bem disse que precisava de um switch para inventar com rate limiting e criar outro tipo de problemas, que um simples desligar de cabo não serve para testar ).

#javascript
Impressionante como evolui na web e daquilo que era, “filho da mãe do javascript e os browsers” passou a “assim com javascript fica muito mais user friendly”.

#php
A ideia no projecto desde o principio era criar um auto Loader mas ainda uma certa falta de direcção do projecto e ainda algumas dúvidas colocaram isto para uma feature implementada mais tarde, acabou por ter uma resolução rápida em uma manhã inspirada(?!).
Limpeza do frontend look and feel que acho que não se adequavam à aplicação e após ter usado algum tempo a aplicação de acordo com as necessidades que haviam surgido apercebemos-nos de pontos a melhorar.

#perl
As falhas de conectividade foram uma constante e aquilo que mais provocou problemas, algo que supostamente seria simples com milhares de registo viu-se complicado. Pensei em algo na tentativa de simplicidade e rapidez de execução e após uns tempos revelou-se uma dor de cabeça em termos de
gestão porque coisas que não deveriam acontecer aconteceram (dammit SQL transactions). Para corrigir resumidamente segmentei codigo, alterei codigo e consegui um bom ganho de performance.

#webservices
A tal regra do if it works don’t touch it, aplica-se aqui. Resincronizar registos de um lado para outro num sistema tipicamente Async é doloroso. Século 21 e alguns sistemas ainda são predominantemente asincronos numa tentativa de ganhar velocidade. Ganha-se velocidade perde-se eficiência e eficácia.
Algo que também se percebeu como já referi anteriomente é que, o que é colocado para testes nem sempre representa o que nos vão enviar para produtivo.

#mysql
Tem respondido bem e na minha opinião nem está optimizado a 100% configurações relativamente basicas mas o novo ano vai puxar por ele (eu pelo menos já fiz codigo para puxar por ele).
InnoDB é algo que deveria ser padrão quando se cria uma tabela.
Calcular uma max+1 de uma tabela nunca me deu tantos problemas como este ano e como método já foi encostado para canto não vá voltar a usa-lo sem querer.
Em falar nisso, temos mais umas tabelas para alterar malta.

#sysadmin
Para uns spam está a deixar de ser um problema eu saí disto à um ano, fiquei com aquilo que se chama a manutenção de serviço, alterar raid 1 para raid 5 é cool mas pode dar chatices, como:
– dear god we have to reboot now
– Resize the disk after reboot
– Where are the files?!
* Comprem a máquina com os slots cheios 😛 ou então don’t migrate usem nova partição ou espetem LVM em cima parece-me mais simples que alterar o raid.
Nem todo o equipamento que se compra caro vale o cash que se paga.
Nem tudo o que parece facilitar facilita.
Backups continuam a ser um must have e um make sure it’s working. Se possível arranjem alguém só para ver isto.

#sap
Just because it’s expensive it doesn’t mean it’s good. It means it has years in the market and many people got problems, you now don’t have to worry about. Also means a huge system with tons of maintenance and complexity above the normal. Scalability, will talk in the future…

#phpunit
Testes unitários são bons quando temos tempo para os fazer e pensar, em muitos casos ajudam a evitar entrarmos nos mesmos erros quando alteramos codigo.
(esquecia-me de falar deste factor importante de 2010 que foram os testes unitários com phpunit)

huawei e220 perl smstools

Num outro artigo tinha escrito sobre o envio de sms com o huawei e220 usando a libraria do CPAN Device::Modem para este caso comigo não resultou. O envio das sms nem sempre funciona, o texto enviado pelo atsend não é emitido pelo modem.
Sem conseguir confirmar de onde originava o problema pois a mesma string pelo minicom funciona sem problemas, usando um outro pc isto tudo funciona sem problemas sobrou a possibilidade de ser diferença na $LANG ou problema de configuração dos locales mas nada tem a ver pois as config’s estão iguais muda sim a versão do perl.

Para contornar todas estas dores de cabeça decidi-me a usar o smstools que funciona sem problemas só preciso de ler as mensagens ler os dados que pretendo dos ficheiros e está a funcionar sem grandes dores de cabeça.

De qualquer modo fica o código para envio das sms usando o Device::Modem funciona no ubuntu 8.04.

# Enviar sms
sub Enviar{
my ( $number, $out, $fromqueue ) = @_;
# Start modem connection
my $OK;
my $new;

my $modem = new Device::Modem( port => ‘/dev/ttyUSB0′ );

if ( $modem->connect( baudrate => 115200 ) ) {
} else {
print “Problem with connection… \n”;
exit 0;
}

# don’t echo my output
$modem->echo (0);

# Initialize
$modem->atsend( ‘ATZ’ . Device::Modem::CR );

# set text mode
$modem->atsend( ‘AT+CMGF=1’ . Device::Modem::CR );
chomp($out);
chomp($number);
# Start sending response
$modem->atsend( ‘AT+CMGS=”‘.$number.'”‘ . Device::Modem::CR );
$modem->atsend( $out . ” \cZ”  );
$modem->atsend( “\cZ”);

# Get Answer
$OK = $modem->answer();
chomp($OK);

if ( $OK =~ /OK/ ){
print “\tenviado\n”;
return 1;
}else {
if ( $fromqueue != 1 ) {
#QueueOut($number, $out);
print “Queue to send later\n”;
}
print “\tnot enviado\n”;
}

$modem->disconnect();

}

Esta função integra-se no meio de outras que “servem um propósito maior”.

perl + huawei e220 + sms

A necessidade de criar um serviço para receber mensagens de telemóvel (SMS) surgiu, um ex-colega aqui no trabalho já tinha andado a “inventar” à uns tempos com isto, eu sabia que ele tinha posto a coisa a andar com o huawei e220 e pelos vistos funciona com mais modelos para além deste, sendo para isto necessário estabelecer a porta de ligação para o dispositivo.

Um tutorial à maneira e um script de perl não muito perfeito  para testar a coisa…

#!/usr/bin/perl

use Device::Modem;

# Validade do numero
sub autorizado {
my ($numero) = @_;

open( numeros, “< numeros.txt”);
@contactos = <numeros>;

foreach $tlf (@contactos){
chomp($tlf);
# debug code
# print ” — “.$tlf . ” ” . $numero . “\n”;
if ( $tlf == $numero ) {
return true;
}
}
return false;
}

$modem = new Device::Modem( port => ‘/dev/ttyUSB0’ );

if ( $modem->connect( baudrate => 115200 ) ) {
} else {
exit 0;
}

$modem->echo (0);

if ( $modem->atsend( ‘AT+CMGL=”all”‘ . Device::Modem::CR )== 1 ) {
# done ;
}
$an = $modem->answer( );
@a     = split(/\n/, $an);

$k = $hit = 0;

foreach $answer (@a){
if ( ($answer =~ /.READ./)) {

($cm, $linha)  = split(/:/, $answer);
($id,undef, $number, undef, $data)  = split(/,/, $linha);
$number =~ s/\”//gi;
$hit = 1;
}else{
if($hit == 1 ) {
$bool = autorizado($number);
if ( $bool eq true ) {
print “numero = “.$number.” msg = “.$answer.”\n”;
$hit = 0;
}
}
}
}

$modem->disconnect();

Ficou a funcionar incluindo com verificação de números o que permite usar respostas automáticas a mensagens.

Nota: Apenas um programa pode usar a porta a cada execução a comunicação com o equipamento é  assíncrona e a lista de numeros.txt tem de conter o +351 antes do número ou altera-se o código.

Um breve teste que resultou em algo produtivo viva a class do cpan Device::Modem

Europe top ten com perl e lynx –dump

Estava à frente do laptop a tentar me lembrar do título de uma musica no top ten. Após uma pesquisa no google encontrei o site que me dá a informação e por brincadeira em menos de um minuto surgiu o código em perl para me fazer a listagem na shell.

$ vi top10.pl

#!/usr/bin/perl

@var = `/usr/bin/lynx –dump http://www.seekalyric.com/music_charts/Europe`;

$go=0;
foreach $me (@var) {
chomp($me);
if ( $me =~ /.Chart last updated at./ ) {

print $me.”\n”;
$go = 1;
}

if ( $go == 1 && $me =~ !/.Chart last updated at./) {
$me =~ s/\[up\.gif\]//i;
$me =~ s/\[\d+\]//;
print $me.”\n”;
}

if ( $me =~ /Recommended Links/ ) {
exit 1;
}
}

:wq

$ chmod 755 ; ./top10.pl

Obrigado “Spidering Hacks” e http://www.seekalyric.com/music_charts/Europe

Perl é o meu novo amigo

À três semanas contínuas que só vejo perl à frente para diferentes trabalhos, é o problema de php não estar nativamente incorporado em *nix.

Back to work…