Conhecendo o Node.js

Vamos entender como funciona o processo de compilação do Node.js

O JavaScript está a cada dia ganhando mais espaço no mercado, antigamente nós utilizávamos ele somente para validações dos nossos formulários, depois começamos a desenvolver games e animações com interações cada vez mais robustas com os nossos usuários. Hoje nós podemos trabalhar com ele no lado do banco de dados com o MongoDB e o melhor no lado Servidor com o Node.js. Pensando nisso eu resolvi criar esse artigo para que possamos aprender e entender como ele funciona por baixo dos panos.

Vamos começar com o seu conceito. Quando eu comecei a estudar node, logo foquei na questão dele ser Single Thread, no inicio eu fiquei pensando … porque usar ele sendo que em outras linguagens nós conseguimos abrir mais de uma Thread por requisição? Pensando nisso, eu fui estudar um pouco mais a sua estrutura até que cheguei no V8.

Em um breve resumo o V8 é uma engine criada pelo Google com a finalidade de interpretar códigos no Google Chrome. Como nós já sabemos, o JavaScript é uma linguagem interpretada, quando o nosso navegador inicia a leitura de um código JS ele irá passar linha a linha de uma forma linear do inicio para o final do nosso código. Nesse processo o V8 compila o nosso código para linguagem de máquina, tentando otimizar ele o máximo possível, permitindo que o código seja executado em cima do que ele compilou.

Se nós utilizássemos somente o node pensando nesse cenário com o V8 , nós teríamos o mesmo cenário das demais linguagem de programação. Mas pensando em um ambiente com muito processamento, como podemos fazer para que não tenhamos o chamado stackoverflow?

Vamos imaginar um cenário onde temos um servidor web que recebe milhões de requisições por segundo. Se a nossa aplicação gerar uma nova Thread para cada requisição, nós teremos um alto custo de processamento. Com o modelo assíncrono Single Thread, nós conseguimos processar mais requisições concorrentes com um número menor de recursos. Para que possamos entender melhor, iremos detalhar a baixo os pontos responsáveis por essa estrutura. A imagem a baixo demonstra uma estrutura simples dos próximos passos desse artigo:

Call Stack

É uma pilha de chamadas de funções com o seu endereço em memoria, ela cria uma pilha com as nossas requisições para que possam ser executadas. Vamos montar um exemplo simples para analisarmos esse passo.

O nosso código acima será executado na sequencia a baixo:

1º Executar o console.log;

2º Irá passar pela function Calc;

3º Em seguida, irá passar pela variável result, nesse momento ele irá perceber que ela tem uma referencia a uma function, para que ele possa voltar a function ele irá empilhar a nossa variável em seguida irá empilhar a nossa function para que ela possa ser executada e retornar o valor para nossa variável.

4º Após ele executar a função e retornar o valor para a variável , ele irá executar os dois consoles finalizando a leitura do nosso código.

O Exemplo acima trabalha em um único processo, onde o V8 está lendo e compilando o nosso código, mas dessa forma em uma aplicação que nem a referenciada a cima nós iremos ter problemas. Para que possamos ter um ambiente de alta disponibilidade, nós precisamos trabalhar com Multi threading.

Multi threading

O Node trabalha com diversas API’s, algumas delas são do próprio Sistema Operacional como: eventos de disco, sockets TCP… etc, mas para que ele possa trabalhar com tarefas assíncronas, ele utiliza uma biblioteca open-source com foco em I/O assíncrono chamada Libuv.

Podemos ver no exemplo a baixo a execução de uma função assíncrona, utilizando essa biblioteca.

Nesse exemplo, nós estamos executando a função readfile do modulo file system do node, essa requisição esta sendo enviada para uma nova Thread, toda requisição assíncrona que precisa de uma API externa é enviada para o Background-Thread, em quanto isso o Callback continua executando as outras requisições. Quando a nossa thread for executada, ela irá ser enviada para a Task Queue. Quando o CallStack tiver executado todas as instruções da sua pilha e do Background-threads, o Event Loop irá buscar na fila de processos da Task Queue o próximo processo para enviar para CallStack.

Task Queue

Como vimos no exemplo acima, algumas ações como I/O são enviadas para serem executadas em outra thread permitindo que o V8 siga trabalhando e a stack siga executando as próximas funções. Essas funções são enviadas para o Background-Thread para serem executadas em outra thread, para que elas retornem irão precisar de um callback. Um callback é basicamente uma função que será executada. Sempre que a thread principal finalizar uma tarefa, o que significa que a stack estará vazia, uma nova tarefa é movida da task queue para a stack onde será executada. Podemos ver esse passo no desenho a baixo:

Esse loop, conhecido como Event Loop, será responsável por chamar as próximas tarefas da task queue enquanto o Node.js estiver rodando. Avançando um pouco mais com o Task Queue, podemos dividir ele em duas partes: Macro e Micro Task.

Macro tasks

São processadas pelo Event Loop, alguns exemplos conhecidos são: setTimeout, I/O, setInterval. Segundo a especificação do WHATWG somente uma macro task deve ser processada em um ciclo do Event Loop.

Micro tasks

São programadas para executar após a execução principal do código, alguns exemplos conhecidos de micro tasks são: as promises e o process.nextTick. As micro tasks normalmente são tarefas que devem ser executadas rapidamente após alguma ação, ou realizar algo assíncrono sem a necessidade de inserir uma nova task na Task Queue. A especificação do WHATWG diz que após o Event Loop processar a macro task da task queue, todas as micro tasks disponíveis devem ser processadas e, caso elas chamem outras micro tasks, essas também devem ser resolvidas para que somente então ele chame a próxima macro task.

O exemplo abaixo demonstra como funciona esse fluxo:

Bom, com isso nós conseguimos ver quais bibliotecas e ferramentas são responsáveis por fazer com que o node seja uma das linguagens mais recomentadas para se trabalhar em um ambiente de alta disponibilidade.

Compartilhe:

Share on facebook
Facebook
Share on twitter
Twitter
Share on pinterest
Pinterest
Share on linkedin
LinkedIn

Table of Contents

Postagens Relacionadas

RockBottomRiser

Rock Bottom Riser

Rock Bottom Riser 01/03/2021(US) – Documentário – 1h 10min –   Nota: 0/10   Sinopse     Elenco Nainoa Thompson Como – master navigator Moses
SaferatHome

Safer at Home

Safer at Home 26/02/2021(US) – Filmes – 0h 0min –   Nota: 0/10   Sinopse     Elenco Mais informações Título Original Safer at Home
SouLunaOUltimoShow

Sou Luna: O Último Show

O elenco de “Sou Luna” se apresenta ao vivo pela última vez no mítico estádio Luna Park em Buenos Aires. Vamos acompanhá-los na intimidade dos bastidores e r…
Chansondouce

Chanson douce

Chanson douce () – Drama, Crime – 1h 40min –   Nota: 6/10   Sinopse     Elenco Leïla Bekhti Como – Myriam Karin Viard