Projetando software com "Pipes & Filters"

Este capítulo possui uma versão mais recente:

Esta é a filosofia Unix: Escreva programas que façam apenas uma coisa, mas que a façam bem feita. Escreva programas que trabalhem juntos. Escreva programas que manipulem streams de texto, pois esta é uma interface universal.
Doug McIlroy

O estilo arquitetural Pipes and Filters emerge, naturalmente, quando arquitetos e desenvolvedores decidem decompor operações complexas em unidades de processamento independentes, mais fáceis de desenvolver e manter. Entretanto, por desconhecimento, com frequência é implementado de maneira descuidada e, em virtude disso, deficiente.

Neste estilo arquitetural, componentes podem ser particionados tanto tecnicamente quanto com base no domínio. Ele favorece atributos de qualidade importantes como performance, escalabilidade e reusabilidade, permitindo que seus componentes sejam implantados e escalados de maneira independente, favorecendo o evolvability. 

Este estilo arquitetural raramente será aplicável a sistemas inteiros, mas sempre é uma boa opção para partes importantes.
1
Você concorda?x

Bons exemplos de aplicação desse estilo são compiladores, soluções para renderização gráfica e o padrão MapReduce.

 

Conceito fundamental

Sistemas projetados utilizando o estilo arquitetural pipes and filters fazem o tratamento de dados, obtidos através de algum mecanismo de ingestão ou produzidos internamente, movimentando-os através de unidades computacionais independentes (os filters), conectadas de maneira planejada (as pipes) para serem processados e enriquecidos, de maneira incremental e contínua.

Uma analogia útil

Imagine um sistema hidráulico responsável por fazer o tratamento de água imprópria para consumo. Internamente, a água é tratada sendo deslocada por meio de dutos e processada em “filtros” específicos, cada um com uma função singular determinada, como, por exemplo, remover impurezas, regular acidez, adicionar cloro e ajustar a temperatura.


Em sistemas implementados utilizando o estilo pipes and filters, a “água” é substituída por dados, os dutos são substituídos por algum mecanismo de comunicação e, finalmente, os filtros, são substituídos por unidades computacionais.

Este estilo arquitetural tem quatro elementos básicos:

  1. filters, que lêem dados a partir de uma ou mais read ports, executam algum tipo de processamento específico, e escrevem os resultados em uma ou mais write ports.
  2. pipes, que conectam dois filters, recebendo input de uma write port e escrevendo dados em uma read port.
  3. read ports, que são pontos de entrada para filters, sendo responsáveis por converter dados em formatos diversos para uma representação interna compatível;
  4. write ports, que são pontos de saída dos filters, convertendo resultados do processamento para representações em formatos específicos.

De maneira genérica, o tipo de processamento executado por um filter inclui gerar, filtrar, transformar (inclusive enriquecendo),agregar e dar finalidade a dados.

Aparência funcional

Desenvolvedores habituados com o paradigma funcional têm mais facilidade para entender o estilo pipes and filters.

Todas as linguagens de programação com suporte ao paradigma funcional oferecem algum mecanismo/operador para criar cadeias de funções, combinadas. Além disso, há sempre funções especialistas em executar as operações de filtermap reduce.

As write ports, por sua vez, conectam o filter com algum tipo de pipe que transportam os dados, sem fazer modificações de qualquer natureza incluído ordenações.

Uma pipe “transporta” dados de uma write port até uma nova read port que serve como entrada para outro filter.

Pipes filters são organizadas de maneira sistemática e organizada, em uma topologia apropriada, com dados sendo coletados de uma origem (Source), submetidos a diversas etapas de processamento, até serem, finalmente, “descartados” em um sink.

Por poderem ter mais de uma porta de leitura e de gravação, filters podem ser envolvidos em “redes” complexas, geralmente sem loops.

Pipes and Filters no Shell dos sistemas Unix-like

As aplicações de linha de comando no Shell dos sistemas Unix-like são projetadas para operar como filters conectando-se com outras naturalmente.

Um exemplo fascinante do poder dessa abstração é narrado no artigo “More Shell, Less Egg“, que conta como Doug McIlroy recriou, combinando poucos aplicativos Linux, um programa de Donald Knuth com centenas de linhas.

tr -cs A-Za-z '\n' |
tr A-Z a-z |
sort |
uniq -c |
sort -rn |
sed ${1}q

Finalmente, filters devem ser independentes um dos outros, sem que qualquer comunicação aconteça, exceto através de pipesFilters tampouco devem assumir que natureza de processamento ocorrerá upstream downstream.

Relação natural com mensageria

O estilo Pipes and Filters conecta unidades de processamento independentes (filters) com diferentes demandas e capacidades computacionais. Os filters limitam o throughput dos dados no sistema e, por isso, é comum que dados se acumulem nas pipes anteriores aos filters mais “lentos”. Por essa razão, é essencial que essas pipes sejam projetadas para “gerenciar estado”. A saída comum é utilizar alguma solução de mensageria.

Facilidade para escalar na horizontal

A performance de um sistema com arquitetura no estilo pipes and filters é determinada pelo filter mais lento. 

A força de uma corrente é sempre determinada pelo elo mais fraco. – Eliyahu Goldratt

Eventualmente, na medida em que a escala aumenta, um ou mais filters mais lentos podem se converter em gargalo. Nesses casos, é comum “levantar” instâncias paralelas de filtros lentos, permitindo que o sistema espalhe a carga e melhore a taxa de transferência.

Os filters podem ser executados em diferentes computadores, permitindo que sejam escalados de forma independente e aproveitem a elasticidade que muitos ambientes de nuvem fornecem.

Um filter que é computacionalmente intensivo pode ser executado em máquinas melhores, enquanto outros filtros menos exigentes podem ser hospedados em máquinas mais simples, permitindo melhor gestão de custos.

Intimidade com “Actors Model

A natureza dos filters , desacoplados e coesos, combinados em ambientes necessariamente resilientes, dá ao estilo arquitetural Pipes and Filters ajuste natural ao Actors Model.
0
Você concorda?x

O modelo de atores é uma abstração matemática para computação distribuída, paralela e concorrente, onde “ator” é a primitiva essencial. Atores atuam sempre a partir de mensagens recebidas, executam algum tipo de processamento, modificam seu estado privado e se comunicam com outros atores, novamente, a partir de mensagens.

O modelo de atores é a abstração fundamental para tecnologias como ERLANG, Elixir, Akka, Akka.net, Orleans e mais.
0
Conhece essas tecnologias?x

A implementação do estilo Pipes and Filters ocorre através da construção de um ator para cada filter.

Intimidade com “FaaS

Recentemente, tem ganho destaque um modelo computacional orientado a eventos, com unidades mínimas de processamento (funções) executadas em contêineres stateless, que são executadas em ambientes gerenciados. Essas “funções” são acionadas sempre que há a ocorrência de um “evento”, com escalabilidade automática.

FaaS é o modelo computacional que fundamenta tecnologias como AWS Lambdas e Azure Functions.

A implementação do estilo arquitetural Pipes and Filters tem ajuste natural com FaaS. A solução é adaptada com filters sendo implementados como funções e as pipes como mecanismo para coleta e gestão de eventos.
0
Você concordax

Intimidade com plataformas de stream 

Nos últimos anos, plataformas para tratamento distribuído de streams, como Apache Kafka e NiFi têm permitido a construção de sistemas robustos capazes de tratar fluxos gigantes de informações.

Apache NiFi, uma ferramenta visual (com API REST),  permite a configuração e conexão entre processadores (filters) de maneira dinâmica. Além disso, permite monitoramento e controle dos fluxos de execução, autorizando ajustes de escala e pausas controladas.
0
Concorda?x

Apache Kafka,  uma implementação distribuída do padrão publish-subscribe, permite aos desenvolvedores conectar programas (filters) entre si, em diferentes linguagens e em um grande número de máquinas. Trata-se de uma alternativa poderosa para implementação de pipes.
0
Concorda?x

Soluções como Kafka e NiFi autorizam escalar de maneira segura soluções projetadas seguindo o estilo Pipes and Filters.

Conway, outra vez!

O desenvolvimento de soluções utilizando o estilo arquitetural Pipes and Filters conduz ao estabelecimento de pelo menos três tipos de times diferentes:

  • Desenvolvedores de filters – preocupados com determinada demanda de negócio pontual e implementação direta em código.
  • Supervisores de pipes – que desenvolvem e especializam plataformas ou soluções para gestão de streams de dados.
  • Gestores de Pipelines – que combinam diversos filters e tecnologias de pipes para o desenvolvimento de uma solução completa para o negócio.

Eventualmente reativo!

O estilo arquitetural Pipes and Filters habilita o desenvolvimento de sistemas reativos, que é algo desejável. Tais sistemas, são responsivos, resilientes, elásticos e orientados a mensagens.
0
Você concorda?x

A responsividade é obtida pelo desacoplamento lógico e operacional das diversas filters. Eventualmente, operações mais pesadas são postergadas para processamento posterior enquanto feedback rápido é dado aos usuários ou agentes externos.

A resiliência, por sua vez, é garantida pela estabilidade dos pipes que “seguram” os dados caso exista alguma instabilidade de processamento nos filters.

A elasticidade, em sistemas baseados em Pipes and Filters é possível desde que cada filter opere realmente de forma desacoplada com o fluxo quanto com outros filters. Em princípio, quando a demanda sobe, filters mais pesados podem ter novas instâncias criadas e descartadas conforme a escala oscila.

Por fim, o “fluxo dos dados” indica clara orientação a mensagens.

Indicações e contraindicações

O estilo Pipes and Filters é uma abstração poderosa que autoriza o desenvolvimento de sistemas robustos e potencialmente reativos. Entretanto, como é sempre o caso, não é uma solução “bala de prata”.

A aplicação de Pipes and Filters deve ser considerada sempre (e apenas quando) que o processamento de uma aplicação puder ser dividido em conjunto de etapas independentes, não dependentes de uma única unidade transacional. Eventualmente, isso não acontece para o software como um todo, mas, será o caso para partes. O ganho será mais percebido quando etapas diferentes tiverem demandas de escalabilidade diferentes.

Outro aspecto interessante do estilo, quando ele for aplicável, é a separação dos processos de desenvolvimento dos filters e o projeto das pipelines indica maior flexibilidade para permitir reordenação das etapas de processamento executadas, além, obviamente, de sofisticação dos processos, adicionando ou removendo etapas.

Em grandes jornadas, dividir para conquistar

Boa parte das implementações “chamadas” microsserviços são, na verdade, realizações de Pipes and Filters. O problema disso é que, muitas vezes, abstrações importantes do estilo acabam ignoradas, causando dificuldades desnecessárias.
1
Você concorda?x

Pensar sistemas em termos de Pipes and Filters é um começo importante para quem deseja criar arquiteturas desacopladas e com bom evolvability. Afinal, o estilo conta com familiaridade com mecanismos poderosos, admirados por muitos desenvolvedores. Além disso, acomoda muitas das “tendências tecnológicas”.
0
Você concorda?x

// TODO

Antes de avançar para o próximo capítulo, recomendo as seguintes reflexões:

  • Você conseguiria decompor seu sistema em um conjunto de “atividades” desacopladas, implementáveis como Pipes and Filters?
  • Você já utiliza Kafka, NiFi ou FaaS em seus sistemas? Há semelhanças, na sua solução, com o padrão Pipes and Filters?

Referências bibliográficas

BONÉR, Jonas; FARLEY, Dave; KUHN, Roland; THOMPSON, Martin. O manifesto reativo. 2014. Disponível em: https://www.reactivemanifesto.org/pt-BR. Acesso em: 16 maio 2021.

DRANG, Dr (org.). More shell, less egg. 2011. Disponível em: https://leancrew.com/all-this/2011/12/more-shell-less-egg/. Acesso em: 14 maio 2021.

GOLDRATT, Eliyahu; COX, Jeff. A meta: teoria das restrições (toc) aplicada a indústria. 4. ed. São Paulo: Nobel, 2015. 400 p. Edição comemorativa de 30 anos.

Compartilhe este capítulo:

Compartilhe:

Comentários

Participe da construção deste capítulo deixando seu comentário:

Inscrever-se
Notify of
guest
2 Comentários
Oldest
Newest Most Voted
Feedbacks interativos
Ver todos os comentários
Carlos Andrew Costa Bezerra
Carlos Andrew Costa Bezerra
3 anos atrás
Feedback no conteúdo deste capítulo Este estilo arquitetural raramente será aplicável a sistemas inteiros, mas sempre é uma boa opção para partes importantes." Ler mais »

Concordo, pois para cada alvo existe uma bala. Problemas diferentes, soluções diferentes.

Anderson Lima
Anderson Lima
3 anos atrás
Feedback no conteúdo deste capítulo Boa parte das implementações "chamadas" microsserviços são, na verdade, realizações de Pipes and Filters. O problema disso é que, muitas…" Ler mais »

Cabe aqui uma comparação mais extensa no texto? Ou essa discussão será tratada no capítulo sobre microsserviços?

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mentoria

para arquitetos de software

Imersão, em grupo, supervisionada por Elemar Júnior, onde serão discutidos tópicos avançados de arquitetura de software, extraídos de cenários reais, com ênfase em systems design.

Consultoria e Assessoria em

Arquitetura de Software

EximiaCo oferece a alocação de um Arquiteto de Software em sua empresa para orientar seu time no uso das melhores práticas de arquitetura para projetar a evolução consistente de suas aplicações.

ElemarJúnior

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

+55 51 99942-0609 |  contato@eximia.co

+55 51 99942-0609  contato@eximia.co

2
0
Quero saber a sua opinião, deixe seu comentáriox
()
x