DEV Community

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

Posted on • Edited on

3 1

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!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay