Repository navigation
fix(baileys): impede sockets duplicadas da mesma instância na reconexão - #7
Open
adriano-rodrigues99 wants to merge 1 commit into
Open
adriano-rodrigues99 wants to merge 1 commit into
adriano-rodrigues99 wants to merge 1 commit into
Conversation
O createClient criava uma socket nova sem encerrar a anterior, e o connectionUpdate reconectava em qualquer 'close' (inclusive o 440, conflict/replaced) sem conferir de qual socket o evento vinha. Bastava surgir uma segunda socket com a mesma sessão (ex.: o fallback do /instance/restart reconectando junto com a reconexão automática) para as duas se derrubarem pelo WhatsApp até o restart da task. Em prod isso gerava de 4 a 12 mil erros conflict/replaced por hora. - createClient desliga os eventos e encerra a socket anterior antes de criar a nova (unsubscribe antes do end, para o 'close' dela não reconectar de novo). - Eventos de uma socket que já não é a atual são descartados. - connectToWhatsapp reaproveita uma conexão em andamento em vez de abrir outra socket em paralelo. - No 440, loga em nível de erro com o nome da instância e reconecta depois de 10s, só se ninguém tiver reaberto a conexão nesse intervalo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resumo
Em prod, a Evolution registra de 4 a 12 mil erros
stream:error conflict type=replacedpor hora (log group/ecs/maxlav-evolution-api-td). Esse erro (código 440) é o WhatsApp derrubando uma conexão porque a mesma sessão foi aberta em outro lugar: duas sockets brigando pela mesma instância.O padrão nos logs mostra que a duplicação nasce dentro do próprio processo:
Causa
createClientcria uma socket nova commakeWASocketsem encerrar a anterior.connectionUpdatereconecta em qualquercloseque não seja 401/403/402/406, inclusive no 440, e não confere de qual socket o evento veio.closee reconecta, derrubando a nova, que também reconecta, e assim por diante, até o restart da task./instance/restart(instance.controller.ts): ele fazws.close()+end()e chamaconnectToWhatsapp()ao mesmo tempo em que oclosetambém reconecta. Esse endpoint é chamado pelo backend no botão de reiniciar do chat e da IA B2C, e antes de excluir uma instância. Não deu pra confirmar o horário dos restarts porque os logs do backend não estão no/ecs/maxlav-be-td.Mudanças (só
whatsapp.baileys.service.ts)endPreviousClient): primeiro desliga os eventos dela (oev.processdevolve um unsubscribe) e depois chamaend(). A ordem importa: ocloseque oend()emite não pode disparar mais uma reconexão.connectToWhatsappjá está em andamento, uma segunda chamada (reconexão automática + chamada da API) reaproveita a mesma promessa em vez de abrir outra socket.LOG_LEVEL=ERROR) e reconecta depois de 10s, só se ninguém tiver reaberto a conexão nesse intervalo. Se ainda existir uma duplicata que este PR não cobre (ex.: dois objetos de serviço para a mesma instância), a briga cai de dezenas por minuto para uma a cada 10s, e o log mostra qual instância é.O fallback do restart no controller não foi alterado: com as guardas acima, as duas reconexões dele convergem para uma socket só.
Riscos
endPreviousClient, a instância fica sem socket até a próxima reconexão ou restart. Antes, nesse mesmo ponto, a socket anterior já estava fechada, então o comportamento é equivalente.Plano de teste
tsc --noEmit,eslinte build (tsup) passamPOST /instance/restart/{instance}algumas vezes seguidas numa instância conectada e confirmar que ela volta aopene que não aparece"type":"replaced"em/ecs/maxlav-evolution-api-td-stg"type":"replaced"por hora (Logs Insights) e a inclinação deMemoryUtilizationdo serviçomaxlav-ms-evolutionno dia seguinte ao deployRefs
Refs maxpantech/infra-iac-aws#163
Relacionados: #5 (consultas da
IsOnWhatsapp; também mexe neste arquivo, mas em trechos diferentes) e #6 (_countdofetchInstances). Os três juntam sem conflito (conferido comgit merge-tree).