de Finibus Bonorum et Malorum



Reclamações recentes

Seguindo em frente com o Bot Debian RC Tracker

O Debian RC Tracker, o pequeno bot que acompanha o número de bugs RC na distribuição Testing do Debian, está rodando desde Agosto. Embora ele tenha rodado quase sem problemas (houve alguns pequenos tropeços), tinha algumas coisas sobre ele que realmente me incomodavam.

O mais importante é que ele era implementado proceduralmente, o paradigma em que eu me sinto mais confortável. Mas conforme eu aprendo Python, eu percebo que a linguagem realmente é pensada em torno de orientação a objetos. E desde que eu implementei o bot pela primeira vez durante o congelamento da Buster eu queria fazer essa migração.

Não é fácil ser um bot

Outro problema era onde ele era instanciado (qual a tradução certa de “deploy”? socorro). O PythonAnywhere vinha sendo satisfatório, mas tem muitas limitações. Ele só permite uma tarefa por dia, e precisa que a tarefa seja estendida uma vez por mês. Eu cheguei a considerar maneiras de contornar essa limitação, mas isso envolveria implementar o controle de tempo dentro do próprio bot (o que levaria a um uso de CPU que mataria a minha cota do mês). E, embora seja irritante, eu estaria OK com entrar uma vez por mês pra atualizar a tarefa para que ela não parasse do nada.

Então eu estava procurando por alternativas. Algumas semanas atrás eu estava explorando alguma coisa no salsa (embora eu não consiga lembrar o quê) e vi uma opção de “deploy on Heroku” (era um exemplo de alguma coisa, se não me engano). A parte importante é que eu descobri a existência do Heroku, que por algum motivo não tinha aparecido no meu radar ainda.

Ele tem a vantagem de oferecer mais recursos e opções (especificamente, o Scheduler é menos restritivo com horários e tarefas); usá-lo para instanciamento é uma questão bem mais complicada que com o PythonAnywhere, no entanto. Precisa do uso de ferramentas específicas (que não estão no Arquivo do Debian, por sinal), e tem uma curva de aprendizado, também. Mas eu não vou falar disso aqui; está bem além do escopo deste post.

Pra encurtar a história, eu decidi migrar o bot para o Heroku. Isso ia requerer bastantes testes, no entanto, até que eu tivesse certeza de que o bot rodaria sem problemas (ou, no mínimo, sem mais problemas que no PA). A versão atual já estava rodando e fazendo o serviço, então só faria sentido trocar se valesse a pena.

Reescrevendo o app

Como eu disse no começo desta jornada, o processo de criar este app foi, no fundo, uma maneira de aprender mais sobre o Debian e sobre programação em Python. O primeiro, eu acho que consegui. O segundo ainda está em evolução.

Mas tem sido mais importante que nunca, na verdade. Eu estou no processo de entrar na Universidade de novo, no curso de Ciência da Computação (mais sobre isso em um post futuro); então é uma aposta certa q experiẽncia de programação é importante. Eu também comecei a fazer alguns trabalhos como freelancer, pra complementar o orçamento de casa, e saber como construir e instanciar um app é fundamental.

Enfim, eu me vi aprendendo como um app em Python funciona. Foi algo com que eu tinha mexido antes, mas aquele esforço foi abortado. Um passo importante também foi me distanciar um pouco da minha atitude original com respeito à programação: parar de tentar fazer tudo “do zero” toda vez. Foi assim que o meu primeiro treinamento formal ocorreu (quando aprendi C no começo da faculdade) mais de vinte anos atrás, e isso ficou comigo desde aquela época. O fato de que usar frameworks e pacotes é uma ENORME economia de tempo também teve algo a ver com isso…

Dividir para Conquistar

A nova versão tem duas partes. A primeira é a Classe DebianTracker, que implementa toda a funcionalidade do bot original, mas é mais confiável e permite futuras expansões. A segunda parte é a parte funcional que usa a classe para as tarefas envolvidas na operação do bot.

A Classe

Enfim, aqui estamos. Havia vários problemas com o código original que me incomodavam, então decidi reescrever completamente o app. Embora eu tenha adaptado uma parte do código original, a maior parte dele é completamente nova. É claro que está longe de uma classe “completa” ou de usar todas as capacidades que ela poderia. Mas é progresso mesmo assim.

Um dos upgrades mais importantes a partir da versão origianl é como os dados são guardados. Originalmente, eles eram salvos em um arquivo de texto. Essa abordagem é problemática por um milhão de motivos. O fato de que o Heroku usa um sistema de arquivos efêmero me deu o empurrão final pra fazer uma implementação com banco de dados. Primeiro eu pretendia usar o SQLite pra isso, porque trata-se de algo simples. Mas o SQLite também depende do sistema de arquivos, então eu fui direto para o PostgreSQL. Então agoora, em vez de ter gambiarras espalhadas pelo código pra lidar com arquivos de texto eu tenho um par de funções métodos que fazem o trabalho pesado (salvar e recuperar dados).

Além disso, já que esta ainda é uma experiência de aprendizado, eu decidi usar o SQLAlchemy. É uma camada extra de abstração, mas é uma abordagem melhor porque é… uma camada extra de abstração. É bizarro, mas é verdade. Tenho certeza que vocês vão entender. Então a classe implementa métodos para todas as tarefas diferentes. Isso inclui pegar os dados novos do UDD, processá-los, salvar e recuperar do banco de dados.

A DebianTracker também tem métodos para criar os gráficos dos dados dos bugs que ela busca no banco de dados; a maior parte do código foi reescrita, embora seja bastante derivada do original, usando o numpy e o pyplot. Agora ele tem maneiras de lidar com opções extras, como datas iniciais e finais para os gráficos, além de opções especiais. O código para lidar com datas também foi melhorado (e isso é uma boa coisa; lidar com datas em gráficos é sempre um pé no saco). Aqui, de novo, eu bati no problema de lidar com o sistema de arquivos efêmero do Heroku. Já que eu não posso contar com arquivos “normais”, eu escolhi uma abordagem diferenciada. Depois de gerar as imagens eu as salvo diretamente no banco de dados. E depois eu busco quando necessário.

Gráfico gerado pelo bot (tomado diretamente da API, então está atualizado)

O que ainda precisa de trabalho é o código para o Twitter. Ele cria o tuíte (que já estamos acostumados a ver) e o submete com uma imagem do gráfico do dia. Ele ainda depende do tweepy, mas usa código antigo e eu ainda preciso aprender mais a respeito dele para reescrever do jeito recomendado. Mas esse código também passou por algumas mudanças, então com alguma sorte não vamos mais ver aqueles números negativos.

O App e o Bot

Agora, o App. Ou Bot. Na verdade, ele tem algumas partes.

A primeira parte é uma coleção de scripts (que eu chamo de “bot”). Eles usam a classe para rodas as tarefas de rotina do app: buscar informação de bugs do UDD, salvar para o banco de dados e mandar os tuítes. Eles rodam no Heroku Scheduler, e com um pouco de checagem de horário eu tenho informação de bugs sendo atualizada a cada 6 horas (dá pra notar a diferença no gráfico), com tweets postados diariamente num horário um pouco mais cedo que antes (14:00 UTC).

A outra parte do App usa o Flask para ter uma interface web. Eu criei um views.py simples que tem um par de rotas conectadas a funções da classe. Dessa forma é possível checar os plots em qualquer momento, sem precisar esperar o próximo tweet. Ele roda com o gunicorn, e recebe pedidos em http://debiantracker.herokuapp.com. E já que eu estava com a mão na massa, o endpoint /image serve as imagens diretamente. /image/bugs retorna o gráfico geral, e /image/freeze serve o gráfico desde o início do congelamento.

E Agora?

Conforme o congelamento anda (a fase “dura” começa em mais ou menos uma semana), a mais algumas coisas que eu quero checar. Originalmente, o bot incluía uma função ajustada aos números de bugs. Talez eu dê uma olhada nisso de novo, mas vai precisar de algumas mudanças. Na época eu fazia o gráfico com o totais de bugs, em vez de curvas separadas por severidade. Não tenho certeza se ajustar curvas diferentes seria uma boa idéia. Ajuste de curvas consome CPU, e fazer isso pra três curvas diferentes poderia usar todo o tempo de CPU que eu tenho disponível na classe “grátis” do Heroku. Infelizmente o upgrade para um nível pago não é uma opção no momento.

Estou sempre aberto a sugestões. Se houver alguma coisa que você gostaria de ver o bot fazer, é só dizer!


Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *