Certificações Ágeis para Scrum Master e Product Owner

Atualizado em 18/06/19 com vídeos!

Obtive minhas primeiras certificações em métodos ágeis, mais especificamente Scrum, em 2010, logo após fazer meu primeiro curso sobre o assunto e definitivamente mudar a minha carreira pra sempre. Estas certificações me foram muito úteis em diversas ocasiões e arrisco dizer que não seria hoje um Agile Coach no Agibank se não possuísse as mesmas.

A ideia do artigo de hoje é explicar um pouco sobre certificações em métodos ágeis, principalmente as disponibilizadas pela Scrum.org, a fundação sem fins lucrativos criada por Ken Schwaber em 2009, um dos fundadores do Scrum.

O que abordarei nesse artigo:

Vamos lá!

Por que tirar uma certificação?

Para quem nunca tirou uma certificação antes, ela funciona como um diploma, um certificado de proficiência mas em um assunto bem específico, como programação Java, administração de servidores Linux ou neste caso, atesta que você sabe toda a teoria sobre o framework Scrum e um papel em específico (Scrum Master ou Product Owner).

Ser certificado não é garantia de que você tenha experiência com algo, mas de que ao menos domina a teoria daquele assunto. Mais do que isso, um profissional certificado mostra o seu interesse genuíno sobre determinado assunto, uma vez que certificações levam certo tempo para estudo e aplicação da prova, além do valor que pode ser bem salgado às vezes.

É bem comum no mercado de desenvolvimento as pessoas acharem que qualquer um pode ser um Scrum master ou um Product Owner e saber se a pessoa possui ou não certificação no papel demonstra que ela realmente busca uma carreira naquele papel em específico e não está apenas atrás de alguma vaga de emprego qualquer. Existem exceções? Com certeza. Mas entrevisto regularmente candidatos a vagas com essas nomenclaturas e é triste ver pessoas que não fazem ideia onde estão se metendo.

Quem emite certificações?

Falarei aqui apenas das duas principais certificadoras do mercado em métodos ágeis: Scrum.org e Scrum Alliance.

A Scrum Alliance foi fundada pelos criadores do Scrum: Jeff Sutherland e Ken Schwaber em 2003. Ela promove a disseminação do Scrum ao redor do mundo desde seus dias iniciais e muito da popularidade do seu método vem da atuação desta empresa. Aproximadamente em 2007 Ken e Jeff entraram em desacordo sobre os rumos da empresa, que estava com um apelo cada vez mais comercial (por exemplo, não era exigida prova para certificar um aluno à época, apenas um curso caríssimo e obrigatório) e que também não estava preocupado com o papel do Dev Team, apenas PO e SM.

Desse desacordo surgiu a Scrum.org aproximadamente em 2009, com o intuito de educar e certificar não apenas SMs e POs, mas também desenvolvedores em práticas ágeis de engenharia. Com um cunho mais educativo e menos comercial, a Scrum.org não exige cursos, embora eles existam para quem deseje fazer, para certificar alguém, apenas uma prova online em Inglês que explicarei mais sobre na sequência. Embora a Scrum Alliance possua provas também há alguns anos, as provas da Scrum.org são notoriamente mais difíceis.

Independente deste histórico, tanto as certificações da Scrum.org quanto da Scrum Alliance são bem avaliadas no mercado, embora existam rumores no forum da Scrum.org de que na Europa as certificações assinadas pelo Ken Schwaber (Scrum.org) possuam maior prestígio.

Sinceramente não recomendo qualquer outra certificadora. Como o Scrum Guide é mantido por estes dois senhores até os dias de hoje, somente ELES podem dizer o que o Scrum é ou não, ou como devem ser a atuação dos papéis ágeis. Já vi muita prova de outras certificadores falando besteira que contradiz o Scrum Guide, que é a fonte oficial de informação sobre o Scrum. Não vou citar nomes aqui por uma questão de ética, mas já vi gente ensinando e cobrando em prova conceitos errados. Tenha cuidado!

Certificação Professional Scrum Master I (PSM-I)

Eu vou me focar aqui nas certificações da Scrum.org pois foi onde tirei as minhas e sei como funciona tudo em detalhes. A certificação PSM-I é a equivalente CSM (Certified Scrum Master) da Scrum Alliance e mostra que o certificado possui conhecimento teórico completo do framework Scrum e do papel do Scrum Master.

Se preferir ver um vídeo ao invés de ler o texto, segue um trecho do meu curso de Scrum e Métodos Ágeis:

As suas principais características são:

  • custo de U$150 por tentativa;
  • somente em Inglês;
  • somente aborda conceitos vistos no Scrum Guide;
  • totalmente objetiva, com questões de múltipla escolha e V/F;
  • média de 85% para aprovação ou 80% para cidadãos cuja primeira língua não é Inglês;
  • 80 questões;
  • 60 minutos para conclusão;

Ao contrário da CSM, a PSM-I não expira e não requer renovação anual. Tirei a minha em 2010 e continua lá no site deles o meu nome até hoje.

Certificação Professional Scrum Product Owner I (PSPO-I)

A certificação PSPO-I é equivalente à CSPO da Scrum Alliance (Certified Scrum Product Owner) e mostra que o certificado possui conhecimento teórico completo do framework Scrum e do papel do Product Owner, bem como de outros princípios mais além relacionados ao desenvolvimento ágil de produtos.

Se quiser ver um vídeo onde falo da certificação para PO, parte do meu curso de Scrum e Métodos Ágeis, segue abaixo:

As suas principais características são:

  • custo de U$200 por tentativa;
  • somente em Inglês;
  • aborda conceitos vistos no Scrum Guide e em outras leituras para POs;
  • totalmente objetiva, com questões de múltipla escolha e V/F;
  • média de 85% para aprovação ou 80% para cidadãos cuja primeira língua não é Inglês;
  • 80 questões;
  • 60 minutos para conclusão;

Também não expira.

Dicas de Estudo para as Provas

A dica mais quente que posso dar é decorar o Scrum Guide de ponta a ponta. Ele é a fonte oficial de informação sobre Scrum e é nele que você deve confiar para saber o que é cobrado nas provas sobre o framework Scrum.

A segunda dica de estudo é fazer os simulados presentes no site da Scrum.org, o Scrum Open e o Product Owner Open. Se for fazer a PSM-I, fazer o Scrum Open vai te permitir conhecer algo entre 30-40% da prova (semelhante ao que acontece com as provas do Detran, sabe?) e se estiver fazendo 100% nos simulados, tem grande chance de conseguir passar na prova. Já se for fazer o PSPO-I, recomendo fazer tanto o Scrum Open quanto o Product Owner Open. Os simulados são bem didáticos e possuem questões no mesmo nível da prova, além de serem gratuitos.

A terceira dica é anotar e fazer resumos. Você tem de ter em mãos tabelas e anotações que te permitam rapidamente saber as principais atribuições de cada papel, as características de cada cerimônia (objetivos, timeboxes, etc) e o uso de cada artefato. Você também vai precisar ter a mão a definição do que é o Scrum e quais são seus valores.

Não recomendo qualquer outro simulado ou livro, pois eles podem mais confundir do que ajudar. A única exceção são os excelentes cursos da TI Exames que são preparatórios para as respectivas provas. Já fiz um deles, de Product Owner especificamente, e considerei muito bom, além de outros colegas de trabalho que também tiveram experiência semelhante.

Dicas para Realização da Prova

Como a prova é online, ter os rascunhos e anotações à mão facilita bastante, bem mais do que ter o Scrum Guide, embora este último também seja importante. Somente se inscreva para a prova (você paga e recebe uma senha para poder iniciar a prova) depois de estar tirando 100% em todos simulados que esteja fazendo, consecutivamente.

Quando eu fiz as provas, eu me tranquei em um local fechado, desliguei o celular e avisei minha esposa que eu não poderia ser incomodado sob hipóteses alguma. Você precisa de muita concentração e silêncio, só deixe o celular por perto como backup de Internet, caso sua banda larga dê problema no meio da prova. Usar um notebook também é importante caso falte luz, pois assim você terá a bateria do note para garantir que consiga fazer a prova até o final (ela dura no máximo 60 minutos).

Feche todas as abas do navegador e demais softwares do seu computador. Deixe no máximo um tradutor de Inglês aberto, caso tenha problema com alguma palavra.

Uma última dica é quanto à interpretação das questões: seja o mais literal possível. Não leve para o seu entendimento pessoal ou para qualquer prática que já tenha tido. Se no Scrum Guide diz que a cerimônia x deve ser feita sempre em pé, sim, a resposta é sempre em pé, mesmo que você eventualmente não siga esta regra, só pra citar um exemplo.

Eu também tenho a certificação de Professional Scrum Developer I (PSD-I), pois na época que comecei a trabalhar com Scrum eu ainda era um analista/programador. As regras são praticamente as mesmas, com a diferença que a PSD-I exige conhecimento de práticas de engenharia ágil, principalmente algumas abordadas no framework Extreme Programming (XP). Como tirar esta certificação não é algo muito comum no mercado, resolvi focar o artigo apenas nas duas supracitadas.

Então é isso. Essas são as orientações que eu poderia deixar sobre o assunto e qualquer dúvida que tiver, pode deixar nos comentários que terei o maior prazer em responder.

Na séria de vídeos abaixo, eu falo de Carreira em Agilidade, um tópico que tem tudo a ver com o assunto certificações:

* OBS: curtiu o post? Então dá uma olhada no meu livro de Scrum e Métodos Ágeis e/ou no meu curso sobre o mesmo assunto!

Curso de Scrum e Métodos Ágeis
Curso de Scrum e Métodos Ágeis

Agile Testing: Cultura de Qualidade em times ágeis

Há algum tempo atrás eu estava fazendo um trabalho com os profissionais de QA lá do Agibank e escrevi o artigo Agile Testing com dicas para mudança de mindset e ressignificação do papel dos QAs nos times Scrum.

De lá para cá muita coisa mudou em nossos times e faz-se ainda mais necessário a ressignificação não apenas do papel do profissional de qualidade dentro dos times como o próprio assunto qualidade. Afinal, não existe entrega de valor em times ágeis se não existir qualidade nas mesmas. Pior do que uma não entrega é a frustração de uma entrega desastrosa.

No artigo de hoje pretendo explorar os tópicos que compreendem o assunto Cultura de Qualidade, tendo como foco o Testing Manifesto da Growing Agile, que eu conheci no Agile Trends 2018.

Qualidade fica no final, certo?…

Todos conhecemos o modelo waterfall de desenvolvimento de software, até porque ele é bem intuitivo: analisamos uma demanda, desenvolvemos ela e antes de entregar, fazemos uma ostensiva etapa de testes, certo?

Além de definir esta etapa de testes mais ao final do projeto, o modelo tradicional defende a existência de um papel de testador ou QA (Quality Assurance) no time, como a pessoa responsável por garantir a qualidade do software antes dele ser entregue. Se deu problema em produção, o problema é do QA que deixou passar os bugs, certo?

No entanto, quando partimos para abordagens de fluxo contínuo como Kanban ou de entregas iterativo-incrementais como Scrum (ou ainda o misto dos dois com Scrumban), se deixarmos a fase de qualidade para o final de um ciclo, claramente teremos problemas, além de obviamente gerar muito estoque de software não testado o que por si só já é um problema, o que chamamos no Lean Thinking de um dos 7 desperdícios do Lean. Então, aqui já temos um ponto: simplesmente não rola fazer testes só no final ou sempre atrasaremos o fim da sprint!

Mas vamos avançar com outro questionamento: no Scrum, o principal framework ágil do mundo, simplesmente não existe o papel do QA. Temos o Product Owner, o Scrum Master e o Development Team, que em tese engloba todos os demais papéis que não sejam de liderança de produto e de processo, respectivamente. Seriam os QAs desenvolvedores dentro do contexto do Scrum?

O raciocínio vai além disso. O QA (quando existente) não é apenas um desenvolvedor dentro do contexto do Scrum, mas em times ágeis (usando Scrum ou não) você deveria considerar que TODOS possuem a responsabilidade sobre a qualidade do software a ser entregue. O ponto que quero colocar aqui é que, para que exista realmente qualidade no trabalho realizado, TODOS devem ser responsabilizados por ela. E a Definition of Done e os Critérios de Aceitação estão aí para ajudar o time nesse aspecto.

Com isso em mente, vamos explorar quais são os possíveis valores por trás de uma cultura de qualidade em times ágeis. Valores estes que devem ser seguidos por TODOS os profissionais do time e antes de eu dar spoilers, voltarei no final do artigo a falar sobre o papel do QA nisso tudo.

Manifesto Ágil para Teste de Software

Todos conhecemos a história do Manifesto Ágil para Desenvolvimento de Software, correto? Esse manifesto acabou inspirando diversos outros e dentro da área da TI inspirou as Agile Coaches sul-africanas da consultoria Growing Agile a criarem o Testing Manifesto em 2013, algo como um manifesto ágil para teste de software.

A ideia deste manifesto, assim como o original é inspirar times de desenvolvimento a aderirem a valores saudáveis e promissores, que lhes ajudem a entregar mais valor para todos.

Acredito que, assim como quando incorporamos os valores do Agile Manifesto no dia a dia dos times provocamos mudanças positivas, incorporar estes valores ao seu rol de práticas e lições possa ajudá-lo a criar uma cultura de qualidade junto aos seus colegas.

O manifesto original é composto por 5 valores, ilustrados na imagem abaixo e que na sequência irei fazer uma possível tradução e dissertarei brevemente sobre os mesmos.

Testing Manifesto

Testing throughout over testing at the end

Cada valor segue a mesma lógica do Agile Manifesto: valoriza-se mais o item à esquerda do que o item à direita. Não é uma substituição, mas uma priorização na cadeia de valores, uma importância maior.

Assim, como primeiro valor temos “Testar através ao invés de testar no final”.

Eu falei sobre isso em meu artigo original e mencionei brevemente este tópico no início DESTE artigo. Se você deixar para testar somente no final da sprint, você estará em maus lençóis e na minha humilde opinião, este comportamento explica por que cerca de 90% dos projetos waterfall falham desde 1994 quando surgiu o Chaos Report.

Vivemos na era da entrega contínua (Continuous Delivery) e de tal forma temos de instruir nossos times a trabalhar com Teste Contínuo (Continuous Testing) também. A cada User Story desenvolvida, a mesma deve ser testada imediatamente e corrigida se necessário, o que nos leva ao próximo valor.

Preventing bugs over finding bugs

Nosso segundo valor é “Prevenir bugs ao invés de achá-los”.

Uma cultura de qualidade prega que ninguém deve ser parabenizado por encontrar bugs, bem como ninguém deve ser depreciado por causá-los, mas sim TODOS devem focar em evitá-los.

Mas como evitamos bugs que ainda não conhecemos?

O primeiro passo é o QA começar a trabalhar ANTES do desenvolvimento. Seja ajudando o Product Owner a especificar os Critérios de Aceite corretamente, seja escrevendo seus testes automatizados usando ATDD/TDD/BDD/etc, seja fazendo Pair Programming com os próprio programadores, para ajudá-los a deixar as funcionalidades com a maior qualidade possível.

Um bom QA não é aquele que acha muitos bugs no software dos devs, mas aquele que ajuda o seu time a não deixar bugs atrapalharem a vida do usuário em produção.

Linkado com as dicas que dei aqui, temos nosso terceiro princípio.

Testing understanding over checking functionality

Este valor pode ser traduzido como “testar entendimento ao invés de checar funcionalidade”.

Software é meio, não é fim. Logo, garantir a qualidade de um software não e limita a checar se ele está funcionando, mas sim se ele resolve o problema do usuário, se ele o ajuda a resolver a sua necessidade.

Assim, uma cultura de qualidade deve promover que os testes sejam feitos sempre sob perspectiva de solucionar o problema ou necessidade do usuário e jamais testar o software pelo software. Novamente, técnicas como ATDD e BDD ajudam aqui, bem como uma boa especificação ágil de requisitos e muita interação com o cliente.

O que nos leva ao próximo valor.

Building the best system over breaking the system

Como mencionei anteriormente, o papel do QA NÃO DEVE ser quebrar o sistema, mas sim ajudar enquanto Developer (segundo Scrum) a desenvolver o melhor sistema possível, e isso é exatamente do que se trata este valor: construir o melhor sistema ao invés de quebrar o sistema.

O racional de que a função do testador de software é “procurar bugs” (por mais que ele tenha uma intenção positiva de evitar que eles cheguem no usuário) é a origem de todo o mal da cultura de testes x a cultura de qualidade.

Quando se testa um software com o mindset de qualidade, procuramos entender se o que foi desenvolvido é o melhor que podemos entregar com as condições que temos visando satisfazer o cliente. Não é apenas ver se o botão salva ao ser clicado, mas se aquele é o melhor botão para resolver o problema do cliente.

E novamente, isso não deve ser feito somente no final do desenvolvimento. O papel de um profissional de qualidade deve ser de ponta a ponta, vide o primeiro valor. Não só dele, mas como de todos membros do time, certo?

Team responsibility for quality over tester responsibility

A responsabilidade pela qualidade deve ser de TODO o time ao invés de somente o testador.

Um Product Owner deve pensar constantemente na qualidade de seu entendimento e da sua comunicação dele para o time (escrita, falada, etc) para que tenhamos qualidade no requisito do projeto/produto.

Um Scrum Master/Agile Coach deve pensar na forma como o processo do time enfatiza a qualidade desejada pelo cliente e empresa, seja minimamente através de um fluxo de valor adequado, bem como boas práticas de engenharia ágil como TDD/ATDD/BDD, Pair Programming, Code Review, Mob Programming e muitas outras.

E os desenvolvedores são parte importantíssima em garantir a qualidade como um todo, fazendo desde um código de qualidade, com padrões concretos e adequados e seguindo as boas práticas sugeridas pelo agilista e mesmo criando práticas emergentes do time que apoiem a qualidade.

Mas se você, assim como eu acredita que “cachorro com dois donos morre de fome”…

O papel do QA Coach

Minha sugestão é que, em times que ainda exista a figura de um profissional especializado em qualidade (QA), ele atue como um coach (treinador) do time em práticas de qualidade. Que ele seja mais um facilitador, um educador e um aliado ao invés da última linha de defesa contra os bugs.

Um QA Ágil ou QA Coach deve ser alguém que não apenas domine técnicas de teste (funcional, automatizado, etc) mas que seja capaz de educar times sob a perspectiva da qualidade. Que assim como o Scrum Master ou Agile Coach que está todo o tempo todo “batendo na tecla” da melhoria contínua, da adaptabilidade, da entrega de valor, etc, que o QA Coach seja o cara que não deixa o time entregar nada menos do que um bom software para o cliente, dentro dos padrões de qualidade estabelecidos previamente.

Não defendo necessariamente a criação deste papel (o Scrum já tem papéis suficientes na minha opinião), em um cenário ideal acredito até que não deveria existir um profissional tão “especializado” assim em times ágeis, que todos developers deveriam ter estas skills, mas esta é uma discussão pra outro momento. Defendo que, nestes casos, que este “chapéu de QA coach” fique mais claro aos desenvolvedores que tenham como especialidade os testes, digo, a qualidade no âmbito de software. 😉

Concorda? Discorda? Deixe nos comentários e vamos bater um papo sobre isso!

* OBS: curtiu o post? Então dá uma olhada no meu livro de Scrum e Métodos Ágeis e/ou no meu curso sobre o mesmo assunto!

Curso de Scrum e Métodos Ágeis
Curso de Scrum e Métodos Ágeis

Entendendo o Node.js Event Loop

Continuando os estudos de Node.js me deparei com um elemento chave que não temos como ignorar quando o assunto é essa tecnologia. Estou falando do Event Loop.

Grande parte das características e principalmente das vantagens do Node.js se devem ao funcionamento do seu loop single-thread principal e como ele se relaciona com as demais partes do Node, como a biblioteca C++ libuv.

Assim, a ideia deste artigo é ajudar você a entender como o Event Loop do Node.js funciona, o que deve lhe ajudar a entender como tirar o máximo de proveito dele.

Vamos ver neste artigo:

Você pode acompanhar este conteúdo através do vídeo abaixo, que é parte do meu curso de Node.js e MongoDB:

O problema

Antes de entrar no Event Loop em si, vamos primeiro entender porque o Node.js possui um e qual o problema que ele propõe resolver.

A maioria dos backends por trás dos websites mais famosos não fazem computações complicadas. Nossos programas passam a maior parte do tempo lendo ou escrevendo no disco, ou melhor, esperando a sua vez de ler e escrever, uma vez que é um recurso lento e concorrido. Quando não estamos nesse processo de ir ao disco, estamos enviando ou recebendo bytes da rede, que é outro processo igualmente demorado. Ambos processos podemos resumir como operações de I/O (Input & Output) ou E/S (Entrada & Saída).

Processar dados, ou seja executar algoritmos, é estupidamente mais rápido do que qualquer operação de IO que você possa querer fazer. Mesmo se tivermos um SSD em nossa máquina com velocidades de leitura de 200-730 MB/s fará com que a leitura de 1KB de dados leve 1.4 micro-segundos. Parece rápido? Saiba que nesse tempo uma CPU de 2GHz consegue executar 28.000 instruções.

Isso mesmo. Ler um arquivo de 1KB demora tanto tempo quanto executar 28.000 instruções no processador. É muito lento.

Quando falamos de IO de rede é ainda pior. Faça um teste, abra o CMD e execute um ping no site do google.com, um dos mais rápidos do planeta:

A latência média nesse teste é de 44 milisegundos. Ou seja, enviar um ping para o Google demora o mesmo tempo que uma CPU necessita para executar 88 milhões de operações.

Ou seja, quando estamos fazendo uma chamada a um recurso na Internet, poderíamos estar fazendo cerca de 88 milhões de coisas diferentes na CPU.

É muita diferença!

A solução

A maioria dos sistemas operacionais lhe fornece mecanismos de programação assíncrona, o que permite que você mande executar tarefas concorrentes que não ficam esperando uma pela outra, desde que uma não precise do resultado da outra, é claro.

Esse tipo de comportamento pode ser alcançado de diversas maneiras. Atualmente a forma mais comum de fazer isso é através do uso de threads o que geralmente torna nosso código muito mais complexo. Por exemplo, ler um arquivo em Java é uma operação bloqueante, ou seja, seu programa não pode fazer mais exceto esperar a comunicação com a rede ou disco terminar. O que você pode fazer é iniciar uma thread diferente para fazer essa leitura e mandar ela avisar sua thread principal quando a leitura terminar.

Novas formas e programação assíncrona tem surgido com o uso de interfaces async como em Java e C#, mas isso ainda está evoluindo. Por ora isso é entediante, complicado, mas funciona. Mas e o Node? A característica de single-thread dele obviamente deveria representar um problema uma vez que ele só consegue executar uma tarefa de um usuário por vez, certo? Quase.

O Node usa um princípio semelhante ao da função setTimeout(func, x) do Javascript, onde a função passada como primeiro parâmetro é delegada para outra thread executar após x milisegundos, liberando a thread principal para continuar seu fluxo de execução. Mesmo que você defina x como 0, o que pode parecer algo inútil, isso é extremamente útil pois força a função a ser realizada em outra thread imediatamente.

Vamos falar melhor dessa solução na sequência.

Node.js Event Loop

Sempre que você chama uma função síncrona (i.e. “normal”) ela vai para uma “call stack” ou pilha de chamadas de funções com o seu endereço em memória, parâmetros e variáveis locais. Se a partir dessa função você chamar outra, esta nova função é empilhada em cima da anterior (não literalmente, mas a ideia é essa). Quando essa nova função termina, ela é removida da call stack e voltamos o fluxo da função anterior. Caso a nova função tenha retornado um valor, o mesmo é adicionado à função anterior na call stack.

Mas o que acontece quando chamamos algo como setTimeout, http.get, process.nextTick, ou fs.readFile? Estes não são recursos nativos do V8, mas estão disponíveis no Chrome WebApi e na C++ API no caso do Node.js.

Vamos dar uma olhada em uma aplicação Node.js comum – um servidor escutando em localhost:3000. Após receber a requisição, o servidor vai chamar wttr.in/ para obter informações do tempo e imprimir algumas mensagens no console e depois retorna a resposta HTTP.

O que será impresso quando uma requisição é enviada para localhost:3000?

Se você já mexeu um pouco com Node antes, não ficará surpreso com o resultado, pois mesmo que console.log(‘Obtendo a previsão do tempo, aguarde.’) tenha sido chamado depois de console.log(‘Previsão confirmada!’) no código, o resultado da requisição será como abaixo:

O que aconteceu? Mesmo o V8 sendo single-thread, a API C++ do Node não é. Isso significa que toda vez que o Node for solicitado para fazer uma operação bloqueante, Node irá chamar a libuv que executará concorrentemente com o Javascript em background. Uma vez que esta thread concorrente terminar ou jogar um erro, o callback fornecido será chamado com os parâmetros necessários.

A libuv é um biblioteca C++ open-source usada pelo Node em conjunto com o V8 para gerenciar o pool de threads que executa as operações concorrentes ao Event Loop single-thread do Node. Ela cuida da criação e destruição de threads, semáforos e outras “magias” que são necessárias para que as tarefas assíncronas funcionem corretamente. Essa biblioteca foi originalmente escrita para o Node, mas atualmente outros projetos a usam também.

Curso Node.js e MongoDB
Curso Node.js e MongoDB

Task/Event/Message Queue

Javascript é uma linguagem single-thread orientada a eventos. Isto significa que você pode anexar gatilhos ou listeners aos eventos e quando o respectivo evento acontece, o listener executa o callback que foi fornecido.

Toda vez que você chama setTimeout, http.get ou fs.readFile, Node.js envia estas operações para a libuv executá-las em uma thread separada do pool, permitindo que o V8 continue executando o código na thread principal. Quando a tarefa termina e a libuv avisa o Node disso, o Node dispara o callback da referida operação.

No entanto, considerando que só temos uma thread principal e uma call stack principal, onde que os callbacks ficam guardados para serem executados? Na Event/Task/Message Queue, ou o nome que você preferir. O nome ‘event loop’ se dá à esse ciclo de eventos que acontece infinitamente enquanto há callbacks e eventos a serem processados na aplicação.

Em nosso exemplo anterior, de previsão do tempo, nosso event loop ficou assim:

  1. Express registrou um handler para o evento ‘request’ que será chamado quando uma requisição chegar em ‘/’
  2. ele começar a escutar na porta 3000
  3. a stack está vazia, esperando pelo evento ‘request’ disparar
  4. quando a requisição chega, o evento dispara e o Express chama o handler configurado: sendWeatherOfRandomCity
  5. sendWeatherOfRandomCity é empilhado na call stack
  6. getWeatherOfRandomCity é chamado dentro da função anterior e é também empilhado na call stack
  7. Math.floor e Math.random são chamadas, empilhadas e logo desempilhadas, retornando uma cidade à variável city
  8. superagent.get é chamado com o parâmetro ‘wttr.in/${city}’ e definimos o handler/callback para o evento de término da requisição.
  9. a requisição HTTP para http://wttr.in/${city} é enviada para uma thread em background e a execução continua
  10. ‘Obtendo a previsão do tempo, aguarde.’é impresso no console e getWeatherOfRandomCity retorna
  11. sayHi é chamada, ‘Hi’ é impresso no console
  12. sendWeatherOfRandomCity retorna, é retirado da call stack, deixando-a vazia
  13. ficamos esperando pela chamada de http://wttr.in/${city} nos responder
  14. uma vez que a resposta chegue, o evento de ‘end’ é disparado
  15. o handler anônimo que passamos para .end() é chamado, é colocado na call stack com todos as variáveis locais, o que significa que ele pode ver e modificar os valores de express, superagent, app, CITIES, request, response, city e todas funções que definimos
  16. response.send() é chamado com um status code de 200 ou 500, mas isso também é executado em uma thread do pool para a stream de respostas não fique bloqueada e o handler anônimo é retirado da pilha.

E é assim que tudo funciona!

Vale salientar que por padrão o pool de threads da libuv inicia com 4 threads concorrentes e que isso pode ser configurado conforme a sua necessidade.

Microtasks e Macrotasks

Além disso, como se não fosse o bastante, nós temos duas task queues, não apenas uma. Uma task queue para microtasks e outra para macrotasks.

Exemplos de microtasks

  • process.nextTick
  • promises
  • Object.observe

Exemplos de macrotasks

  • setTimeout
  • setInterval
  • setImmediate
  • I/O

Para mostrar isso na prática, vamos dar uma olhada no seguinte código:

a saída no console é:

De acordo com a especificação da WHATWG, uma macrotask deve ser processada da macrotask queue em um ciclo do event loop. Depois que essa macrotask terminar, todas as microtasks existentes são processadas dentro do mesmo ciclo. Se durante este processamento de microtasks novas microtasks surgirem, elas são processadas também, até a microtask queue ficar vazia.

Este diagrama do site Rising Stack ilustra bem o event loop completo:

Em nosso caso:

Ciclo 1:

  1. setInterval é agendado como (macro)task
  2. setTimeout 1 é agendado como task
  3. em Promise.resolve 1 ambos thens são agendados como microtasks
  4. a call stack está vazia e as microtasks executam

Task queue: setInterval, setTimeout 1

Ciclo 2:

  1. a microtask queue está vazia, logo o handler setInterval pode executar;
  2. outro setInterval é agendado como task, logo atrás de setTimeout 1

Task queue: setTimeout 1, setInterval

Ciclo 3:

  1. a microtask queue está vazia, logo o handler setTimeout 1 pode executar;
  2. promise 3promise 4 são agendadas como microtasks;
  3. handlers de promise 3promise 4 são executados
  4. setTimeout 2 é agendado como task

Task queue: setInterval, setTimeout 2

Ciclo 4:

  1. a microtask queue está vazia; logo o handler de setInteval pode executar;
  2. outro setInterval é agendado como task, logo atrás de setTimeout

Task queue: setTimeout 2, setInterval

Ciclo 5:

  1. o handler setTimeout 2 executa;
  2. promise 5promise 6 são agendadas como microtasks;
  3. os handlers de promise 5 e promise 6 executam encerrando o programa.

Nota: isso funciona perfeitamente bem no Google Chrome, mas por questões que fogem da minha compreensão, não é regra em todos ambientes de execução. Existem modificações que podemos fazer no código para que o comportamento seja o mesmo em todos ambientes, mas deixam o código terrivelmente feio (i.e. callback hell).

Conclusões

Como você pôde ver, se quisermos ter total controle de nossas aplicações Node.js devemos prestar atenção nestes detalhes de como as tarefas são executadas dentro do event loop, principalmente para não bloquearmos sua execução sem querer.

O conceito do event loop pode ser um tanto complicado no início mas uma vez que você entender sue funcionamento na prática você não conseguirá mais imaginar sua vida sem ele. Obviamente o uso inicial intenso de callbacks é muito chato de gerenciar mas já é possível usar Promises em nossos códigos Javascript que permitem deixar as tarefas assíncronas mais inteligíveis e em breve devemos ter acesso ao recurso async-await com o ES7.

Uma última dica é que você também pode enviar seus processamentos longos (mas que não são operações de IO), que normalmente seriam executados na thread principal para as threads em background usando bibliotecas como async.js.

Recomendo agora colocar a mão na massa com esse tutorial de Node.js com MongoDB que preparei pra você!

Curtiu o post? Então clica no banner abaixo e dá uma conferida no meu livro sobre programação web com Node.js!