Polling — a criança impaciente

Luana Negreiros
Ship It!
Published in
3 min readMar 6, 2023

--

Imagine você num carro com sua família e duas crianças no banco do passageiro. Você estão viajando e a viagem demorará cerca de 4 horas. Uma das crianças se entretem com seu celular e se dá por satisfeita quando a mãe se vira e diz “Pronto, já chegamos filho”.

Já a outra criança pergunta, a cada 5 minutos, “nós já chegamos? já chegamos? já chegamos?”. Ela precisa de uma resposta constante para seu questionamento, e só para de perguntar quando a resposta a satisfazer, ou seja, ela só vai parar quando a mãe virar e dizer “já chegamos!”.

A criança impaciente é uma analogia para uma polling.

Às vezes, quando escrevemos um código, não podemos ficar presos a uma execução específica (como no caso das funções assíncronas). Precisamos seguir em frente independente do resultado daquele retorno. Mas, em alguns casos, precisamos ficar perguntando o resultado daquela função até que ela retorne algo diferente e, então, execute algo diferente.

Isso são pollings.

Vamos então transformar esse exemplo num caso que trabalhei aqui na RD:
Em uma de nossas ferramentas utilizamos a API do github, e utilizamos algumas informações encontradas no body do retorno da requisição. Nesse body temos o atributo mergeable, que denuncia se o PR em questão é mergeável ou não. Ele retorna os valores true ou false, mas ele também retorna null .

Nós tínhamos apenas tratado os casos em que o retorno do atributo fosse true ou false , ignorando o null , até que né, começou a dar ruim.

Quando o atributo retornava null todo o processo parava e dava erro. Fomos pesquisar e entendemos através da documentação que o atributo fica nulo devido à falta de interatividade no PR.

Decidimos então criar uma polling, que, dentro dessa checagem (se o PR é mergeável), fica perguntando: “o atributo body.mergeable é null?” Caso a resposta seja positiva, chama a função da polling novamente, que faz a requisição e volta a perguntar: “o atributo body.mergeable é null?”, e assim continua até o resultado ser true ou false .

No nosso caso, se o atributo for true, nossa promise se resolve, e, se for false , uma mensagem de erro é retornada:

“Seu pull request tem conflitos com a master. Você deve resolvê-los.”

checkIfPRIsMergeable(repositoryName, prNumber){
const path = `repos/${repositoryName}/pulls/${prNumber}`;

return new Promise((resolve, reject) => {
const _performPollingCheck = () => {
octonode.get(path, (err, status, body) => { // aqui fazemos a requisição

if (err || status !== 200) { // aqui ele rejeita a promise e retorna um erro pois o status é diferente de 200
return reject(new Error(`Não foi possível verificar o status de mergeabilidade do seu pull request.`));
}
if (body.mergeable !== null) { // aqui ele resolve ou rejeita a promise caso o atributo seja diferente de null
return body.mergeable ? resolve() : reject(new Error(`Seu pull request tem conflitos com a master. Você deve resolvê-los.`));
}

delay(() => _performPollingCheck()); // aqui ele performa a polling de novo caso não haja quaisquer dos retornos acima
});
};
_performPollingCheck(); // aqui ele executa a função
});
}

Podemos comparar a criança maior — que se mantém quieta durante o percurso e se contenta com um “já chegamos” ao final, com um interrupt . Mas isso já assunto pra um próximo artigo!

Gostou? Não gostou? Deixe sua opinião para que eu possa melhorar :)

--

--

Luana Negreiros
Ship It!
Writer for

Sou do time de Dev Tools na @ RD Station. Compartilho aqui as coisas que vou aprendendo, além de assuntos como maternidade e produtividade.