DEV Community

Cover image for Concorrência limitada em gorrotinas
Igor Costa
Igor Costa

Posted on • Edited on

Concorrência limitada em gorrotinas

Uma das coisas que me fascinaram quando comecei a aprender Go foram as Gorrotinas. A "facilidade" de criar processos concorrentes me motivou a tentar identificar onde poderia utilizar nas minhas apps pra conseguir ganhar desempenho.

Eis que eu encontrei a oportunidade numa app que estava construindo, basicamente eram feitas várias queries em tabelas do MySQL e precisava indexar tudo no Swiftype (uma engine de busca textual semelhante ao ElasticSearch).

A primeira versão ficou mais ou menos assim:
versão simples

Concorrência sem limite

Na função main() todos os registros do tipo document são listados, depois iterados e um a um são indexados no Swiftype.
O processo todo demorava um tempo longo com 80k registros para serem indexados um a um, pois cada chamada à API do Swiftype precisava esperar um retorno antes de ir para a próxima. Decidi usar gorrotinas para indexar todos os registros de forma concorrente e diminuir o tempo de execução. Alterando a função indexAll() para utilizar gorrotinas, ficou desse jeito:

concorrencia não limitada

Essa abordagem funcionou bem durante um pequeno momento até que começaram a estourar erros. Uma coisa que não havia levado em consideração é que existe um limite de conexões socket que o sistema operacional pode manter. Dessa forma serão criadas gorrotinas para cada registro a ser indexado, além disso pode gerar problemas de falta de memória, entre outros problemas.

Decidi então criar uma solução limitando o número de gorrotinas ativas, só poderia ser criada outra quando uma das ativas terminassem, pra ficar sempre o mesmo número de gorrotinas até que todos os registros fossem indexados.

Concorrência limitada

concorrencia limitada

O channel bufferizado age como uma fila, onde são adicionados os tokens das gorrotinas, quando o channel fica cheio não são criadas novas gorrotinas, até que alguma das que estão em execução terminam e o token é removido do channel, abrindo espaço para uma nova gorrotina ser criada.

Conclusão

Dessa maneira uma execução que demoraria vários minutos levou no máximo 2 minutos. É claro que existem muitas outras abordagens para o mesmo problema, mas essa me deu uma oportunidade de usar gorrotinas de uma maneira simples e eficaz.

Agradeço o tempo que você investiu lendo esse post e espero que seja útil para você, deixe um ❤️ ou 🦄 caso tenha curtido!
Se tiver alguma maneira diferente de resolver o problema ou tiver alguma dúvida não deixe de comentar!

Top comments (0)