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!

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up