Programação Reativa

No Quarkus, a programação reativa é um jeito alternativo de desenvolver aplicações: em vez de trabalhar com chamadas que bloqueiam até terminar, ela se baseia em processamento assíncrono, não bloqueante e orientado a eventos.

Em um modelo tradicional (baseado em servlets), cada requisição ocupa uma thread até que tudo seja concluído. Isso limita a escalabilidade, porque o servidor precisa de muitas threads e memória para lidar com várias conexões ao mesmo tempo.

Blocking Threads

O Quarkus adota um modelo reativo usando o Vert.x como motor. Esse motor funciona com loops de eventos (event loops), que processam as requisições sem criar uma thread para cada conexão.

Blocking Threads

Em vez de devolver imediatamente o resultado, os métodos retornam tipos reativos, como:

  • Uni → representa um único resultado futuro.
  • Multi → representa um fluxo (stream) de vários elementos ao longo do tempo.

Como não há bloqueio de threads, é possível atender milhares de conexões simultâneas consumindo menos memória e CPU. Isso torna as aplicações mais leves rápidas e escaláveis.

Vert.x

O Quarkus é construído sobre o Eclipse Vert.x, que fornece um event loop (Event Pool) baseado em epoll (no Linux) ou kqueue (em BSD/macOS). Cada event loop thread é capaz de gerenciar milhares de conexões concorrentes sem a necessidade de criar uma thread para cada cliente.

Uma boa analogia é imaginar uma telefonista: ela não conversa com todos os clientes ao mesmo tempo, mas atende a ligação, anota a solicitação e encaminha para o destino correto. Assim, pode lidar com um grande volume de chamadas de forma organizada e contínua.

No Linux, o event loop utiliza a primitiva epoll para monitorar milhares de sockets simultaneamente:

  • Quando algo acontece (por exemplo, a chegada de dados pela rede), o epoll notifica a thread do event loop.
  • Essa thread, então, aciona o callback correspondente para tratar o evento.

Nota: epoll é uma chamada de sistema do kernel Linux que implementa um mecanismo de notificação de eventos de E/S altamente escalável.

Principais Métodos

  • onItem: usado para reagir a eventos bem-sucedidos emitidos por um Uni ou Multi.

  • call: chama um método assíncrono e espera terminar, um exemplo:

repository.findById(user.id)
    .onItem().ifNotNull()
    .call(item -> {
        item.setName(user.getName());
        item.setEmail(user.getEmail());
        return repository.persistAndFlush(item);
  });
  • invoke: chama um método assíncrono e retorna imediatamente, atua como um interceptador de um item.

  • transform: transforma o item emitido por um Uni ou Multi em outro valor.

Referências

Rodrigo Prestes Machado
CC BY 4.0 DEED

Copyright © 2024 RPM Hub. Distributed by CC-BY-4.0 license.