Esse post serve para lhe ajudar a resolver o erro mais comum que acontece em uma aplicação NodeJS que crasha do nada, e só volta a funcionar reiniciando. Até crashar novamente.
Esse comportamento pode acontecer devido a inúmeros motivos diferentes. Não é exclusivo ao exemplo apresentado abaixo. Mas a ideia é a mesma. Verificar os logs quando a aplicação para de funcionar para saber o motivo.
O exemplo que vou usar nesse post é quando você usa o banco MySQL com o módulo mysql. E o erro que aparece nos logs é esse:
Error: Connection lost: The server closed the connection.
Porque isso acontece?
Suponhamos que o seu código tenha essa estrutura:
Ele cria uma conexão e conecta no banco de dados. (não necessariamente apenas uma)
Então, toda vez que é feita uma requisição para o /produtos, ele manda o resultado cru da query feita com aquela conexão aberta anteriormente.
Isso funcionará normalmente… até não funcionar mais.
As conexões com o banco de dados tem um tempo limite para ficarem abertas. Quando esse tempo limite for atingido, o servidor fechará a conexão, a sua aplicação Node jogará o erro acima e terminará. Voltando a funcionar apenas se reiniciar a aplicação. Então todo o ciclo iniciará novamente.
Como resolvo?
Com uma pool de conexões!
O módulo do MySQL para NodeJS já vem com a funcionalidade de gerenciar uma pool de conexões.
Basicamente, quando você cria uma pool de conexões, o módulo abre várias conexões simultâneas com o banco de dados e as deixa em uma espécie de standby.
Quando você precisa fazer uma query, você requisita uma conexão para o pool, e ele lhe retornará com uma para usar. Então, assim que terminar de usar aquela conexão, você deve liberá-la, devolvendo ao pool.
Com o código adaptado, deve ficar algo como:
Não altere o seu código ainda
Dessa maneira, a conexão fica aberta apenas durante o tempo que é usada. Logo, não haverá o problema do timeout derrubando a sua aplicação
Mas espere, há uma maneira mais fácil!
O próprio objeto retornado pela função createPool já vem com a função query. Essa função query já faz todo o processo mencionado acima de pegar uma conexão, executar a query e liberá-la.
Com poucas modificações, é possível adaptar o seu código existente para usar pools.
Ao adaptar o código inicial:
As modificações feitas foram:
- Alterar o nome da variável connection para pool (opcional)
- Trocar a função createConnection pela createPool
- Remover a linha que chama o connect do objeto retornado pela antiga função