Sou novo no Serverless (JAWS), então posso ignorar algo óbvio aqui. Eu tenho uma função de teste muito simples que usa o módulo de nó mysql
, instancia um pool de conexões, obtém uma conexão e a libera novamente:
var mysql = require ("mysql");
var config = {
// settings go here
};
module.exports.respond = function(event, cb) {
var pool = mysql.createPool({
connectionLimit: config.connectionLimit,
host: config.host,
user: config.user,
password: config.password,
multipleStatements: true
});
pool.getConnection(function(err, connection) {
err && console.log("Error establishing a database connection: ", err);
connection.release();
return cb(err, "Done.");
});
};
Essa função funciona perfeitamente bem quando implantada na AWS, sai em alguns milissegundos e o mundo é brilhante e bonito. No entanto, executando esta função localmente com serverless function run
, ela imprimirá " Done.
" no final, mas nunca sairá.
Eu descobri que o motivo provavelmente é que eu não estou liberando o pool de conexão mysql. Se eu alterar o último comando na função acima para o seguinte, tudo funcionará:
pool.end(function() {
return cb(err, "Done.");
});
Parece que o Serverless está esperando o loop de eventos do mysql terminar e não sairá a menos que isso aconteça. No entanto, no meu entendimento, devo _não_ fechar o pool de conexões para que chamadas futuras da mesma função do Lambda possam reutilizar o pool e, portanto, não exigirão uma nova conexão de banco de dados, mas reutilizarão uma existente.
Então, o comportamento do Serverless é esperado aqui para bloquear ou isso é um bug? Eu tinha a impressão de que chamar context.done()
terminaria e retornaria. Portanto, eu esperaria que o Serverless saia ao testar isso localmente.
Acabei de testar isso com 0.1.0 e ainda se comporta da mesma maneira: executar a função localmente (por meio de sls function run component/module/func
) travará e não retornará à linha de comando, enquanto a função do Lambda implantada funciona conforme o esperado.
mesmo problema aqui
Para todos que ainda estão tendo esse problema... Acho que é discutível se isso é um bug ou não. O motivo pelo qual sls
não está sendo encerrado é que ainda há um loop em execução e o aplicativo é, pelo menos em teoria, ainda capaz de processar solicitações adicionais (invocações adicionais de handler.handle()
). Este é exatamente o mesmo comportamento que você veria nos servidores da Amazon: a instância do Lambda é mantida em execução para processar solicitações adicionais e será interrompida (eliminada) em algum momento no futuro, quando a Amazon quiser liberar recursos. Qualquer variável global será mantida nessas invocações. Se você tiver um pool de conexão MySQL, esse pool ainda estará disponível para a próxima invocação do Lambda, acelerando as coisas notavelmente.
Portanto, o Serverless deve sair do processo quando a chamada da função for concluída ou não? Não sei. Mas, a julgar pela resposta de @eahefnawy para fechar este relatório, presumo que o comportamento esperado seja continuar rodando.
Comentários muito úteis
Para todos que ainda estão tendo esse problema... Acho que é discutível se isso é um bug ou não. O motivo pelo qual
sls
não está sendo encerrado é que ainda há um loop em execução e o aplicativo é, pelo menos em teoria, ainda capaz de processar solicitações adicionais (invocações adicionais dehandler.handle()
). Este é exatamente o mesmo comportamento que você veria nos servidores da Amazon: a instância do Lambda é mantida em execução para processar solicitações adicionais e será interrompida (eliminada) em algum momento no futuro, quando a Amazon quiser liberar recursos. Qualquer variável global será mantida nessas invocações. Se você tiver um pool de conexão MySQL, esse pool ainda estará disponível para a próxima invocação do Lambda, acelerando as coisas notavelmente.Portanto, o Serverless deve sair do processo quando a chamada da função for concluída ou não? Não sei. Mas, a julgar pela resposta de @eahefnawy para fechar este relatório, presumo que o comportamento esperado seja continuar rodando.