Node funciona com event loop - que atende com uma unica thread as requisioções e dpois compartilha a demanda
modelo tradicional (antes):
requisições ==> [threads esperando]
- aguardando que alguma coisa aconteça
- ao chegar faz alguma coisa (Query em banco, entregar arquivo requisitado)
- ficam a maior parte do tempo esperando(dormindo,wait)
- como alocar menos recurso?
Desafio do Node inicialmente, como melhorar este I/O
- como alocar menos memória, menos thread e ter mais cocorrencia
Solução proposta no node
- um event-loop (EL) que roda em uma só thread (uma coisa sendo processado por vez)
- ao receber requisição delega a tarrefa a um pool de threads (inicialmente 4 threads alocadas)
- esse pool de threds tem a ver com I/O Assincrono (I/O não bloqueante)
- quando o I/O é finalizadopelo no pool de threadas, isso é agendado no E.L. para ser processado
- assim nunca se tem threads wait, mas se tiver muito requisição concorrnte este processo pode esperar para entrar no pool de threads
- node usa LibUV para dar suporte a EL Pool de Threads
|--> responsável pela realizaçãodo I/O assíncrono
para I/O ñ bloquante ver:
I/O assíncrono
Polling
- programador, explicitamente, pede para saber da disponibilidade de eventos num file descriptor (fd) [3]
- quando se pergunta: tem algum evento acontecendo?) (perguntar o status de um file-descriptor)
=>a resposta é: eventos disposníveis nestas coisas
=>não é comum usar polling para um fd e sim varios
- file descriptor [3]: Every time you accept a connection with the accept system call, you get
a new file descriptor representing that connection.
- polling esta associado ao conceito de "readiness" Model ??
=>vc é informado quando aquele fd está pronto para um evento
=> mas as vezes: chega uma mensagem, o Polling avisa, pode ler desta fd mas
por algum motivo programador não consiga ler (ou seja esta pronto mas talvez não..?)
- servidores modernos como nGinx e Tornado usam conceito de Poling (em cima do poling o loop de eventos)_
=> ob.|: Flask is blocking and Tornado is non-blocking.
- no Python 3.3 poling esta no módulo select
- no Linux se usa epoll para polling, familia BSD (e OSX) kqueue, windows usa Select
Etapas do Polling (python)
- criar objeto poller
- (opcional) registrar um file descriptor (fd)
- execução do poll() => retorna os evento (o fd e o tipo de evento - leitura, escrita ou erro)
Polling é um conceito de baixo nível
- é responsabildiade do programador ficar invocando ele (gerealmnente dentro de um while(true) )
- responsabilidade também add e retirar eventos
=>se um cliente desconectou devo retirar do polling (cli não envia mais nada)
- reponsa tb iterar os eventos e ver se é leitura ou escrita e tratar cada item
Loop de Eventos [1]
- abstração acimam do Polling
- polling + loops + callbacks
=>quando acontecer o evento no fd tal => quero que executa o callback tal
Pool
I/O multiplexing(event multiplexing).
The blocking behavior of BSD Socket API means that if you invoke recv() on one connection,
you will not be able to respond to a request on the other connection. This is where you
need I/O multiplexing. (Scalable Event Multiplexing: epoll vs. kqueue)
Muita coisa peguei daqui Link
TULIP - PYTHON 3, IO ASSÍNCRONO E LOOP DE EVENTOS
https://pycursos.com/tulip-python-3-io-assincrono-e-loop-de-eventos/
Agenda do palestrante
- Poolig & Loop de eventos
- I/O Assíncrono e Não bloqueante
- Coroutinesa, Future/Tasks
- I/O Assíncrono sem calbacks - yeld from
o palestrante inicia falando sobre File Descriptor, ver o texto para complementar
https://jvns.ca/blog/2017/06/03/async-io-on-linux--select--poll--and-epoll/
Como se constrói um event-loop?
Dicas Rob Pike
[1] artigo Communicating Sequential Processes (tony hoare) um dos artigos mais imprtantes da coputação
[2] concorrencia é melhor que paralelismo (Concorrência não é paralelismo, é melhor! )
Long Pollig
==============
O Long Polling é uma técnica que simula uma indisponibilidade do servidor para manter uma conexão HTTP aberta. Essa técnica foi criada a partir da necessidade de comunicação em tempo real com um servidor web.
Contexto
Com a necessidade de se obter dados em tempo real do servidor, antigamente, os desenvolvedores criavam rotinas que enviavam uma requisição de tempos em tempos (como você mesmo descreveu) para "perguntar" se havia mudanças no modelo de dados da aplicação. Caso houvesse, a resposta da requisição conteria esses dados e então os mesmos poderiam ser atualizados na aplicação.
Esse tipo de rotina consumia uma quantidade grande de recursos quando a aplicação tendia a ser escalável (crescer de forma acelerada). Vamos simular:
Imagine uma página que envia a cada 5 segundos uma requisição AJAX para um endpoint específico a fim de descobrir se houve mudanças de notificações, por exemplo. Isso não se torna um problema com poucos usuários simultaneamente conectados. Mas digamos que a aplicação cresça de 10 usuários para 100 usuários conectados simultaneamente.
Vamos pensar maior. Imagine 1.000 usuários conectados. Em 5 segundos, 1.000 requisições serão enviadas para o mesmo endpoint. Após mais 5 segundos, mais 1.000 e assim por diante. Dependendo da arquitetura da aplicação, isso começa a sobrecarregar o servidor. Especificamente aquele endpoint.
"A solução" - Long Polling
Quando um cliente faz uma requisição o servidor simula uma indisponibilidade de dados e faz com que a requisição HTTP não tenha resposta enquanto não houver mudanças no modelo dos dados da aplicação.
Isso resolve o problema? Sim e não. Sim, por que não é necessário ficar enviando requisições de tempos e tempos para checar essas mudanças. Não, por que isso causou outro problema de desempenho. As requisições HTTP não foram especificadas para isso. Estender uma requisição HTTP pode "parecer" resolver o problema da quantidade de requisição enviadas ao mesmo endpoint, mas na verdade ela também consome muito recurso justamente por que está sendo usada inadequada.
A verdadeira solução - WebSockets
Escrevi um post sobre WebSockets e sua implementação em Java (mas tem implementações pra quase todas as linguagens atuais). Sugiro que dê uma olhada por que lá eu explico com detalhes sobre a especificação e também dou exemplos práticos que da pra reproduzir ai na sua casa.
Comunicação em tempo real com WebSockets
Enfim.. Foque seu estudo em implementações WebSockets e seja feliz com a verdadeira comunicação em tempo real.