Don't break my Pipe without telling me!

2015-03-06
3 min read

The Background

No dia de Ontem, descobri uma artimanha bem interessante do Node.js, meu aplicativo em produção começou a ficar parado sem motivo ou razão para mim. Chegava em certa parte do Log ele simplesmente parava de funcionar e a partir dai nem com reza brava eu conseguia pegar o problema real da coisa.

Conforme eu incluía mais logs no sistema menos informações apareciam, cheguei a cogitar com a equipe vários possíveis problemas, minha lógica errada, um componente que podia estar com algum bug, na real foram algumas horas até conseguir, como diriam meus avós: “Pegar o fio da meada”.

The Problem

Acontece que grandes quantidades de log ao usar Child Process do Node.js são um pequeno problema. Na verdade no meu caso acabou sendo um grande problema!

Eu usava o método Spawn da api Child Process, até então nos meus testes em desenvolvimento, nunca tive qualquer problema com isso. Meu aplicativo que pega um script(leia aqui como roteiro, não script de códigos) em Json e executa algumas funções a partir desse script, mas como programador só sabe fazer testes viciados, nunca fiz um script tão grande que pudesse quebrar o pipe entre a aplicação pai e seu processo filho.

Mas até ai, tudo bem, encheu o buffer, não consegue liberar a memoria o processo fica parado, mas o Node vai me retornar algo pra avisar!

#SQN

A dor de cabeça foi maior pelo fato do Node.js não me retornar nenhum tipo de log quando esse tipo de situação acontece.

Dando uma olhada no código fonte do Node.js e baseado em nesta issue#6764 dá pra ter uma ideia de que mais ou menos quando seu buffer fica com +/- 24kb ele vai simplesmente parar de responder o processo Pai e não gerar nenhuma exception, erro, exit ou qualquer coisa do tipo!

E isso galera, é #foda! mas é #MTOFODA! por que eu realmente não sei o que está acontecendo com a minha aplicação, não tenho nenhum mecanismo pra saber o que aconteceu.

Mas é claro que isso fica muito bem documentado na API de Child Process né não? #SQN!

The answer

Baseado em um post no StackOverflow(eu perdi o link, mas sei a solução abordada lá, quando eu encontrar posto aqui =D ) lá é sugerido que redirecionemos o nosso output vindo do processo filho pro processo pai.

Por que isso? Minha teoria é simples, conforme você está soltando os logs do seu processo filho e jogando para o pai, esse processo não vai encher o seu buffer de execução com seus logs, pois eles estaram sendo redirecionados para outro lugar. Na resposta essa foi a solução:

Eu particularmente, penso que seja mais pratico, mandar o output ou o erro caso, percebam que eu disse CASO, não vá usar essas informações como é o meu caso, você pode mandar todo o log desse pipe pro buraco negro do Linux. “/dev/null” #ftw

Assim você não vai estourar seu buffer!

Espero que isso seja útil para que algumas pessoas não sofram como eu para achar o problema :/

Valeu e até a próxima!