SmallFBP: a Smalltalk framework for Flow-Based Programming – Part 2

filter

Ciência, arte e filosofia se vão fundindo tanto em mim que algum dia certamente vou parir um centauro – Nietzsche.

  1.  Introdução
  2. Flow-Base Programming
    1. Component
    2. Port
    3. Information Packet (IP)
    4. Connection
    5. Network
    6. Initial Information Packet (IIP)
  3. Exemplo: Filter
    1. OddFilter
    2. MaxNumberIIP
    3. Numbers
    4. Printer
    5. Filter GUI
  4. Portas automáticas
    1. Introdução
    2. Exemplo: Writer e Reader
    3. Usando displays com portas automáticas
    4. Usando portas automáticas no exemplo Filter
  5. Componentes compostos
    1. Introdução
    2. Subnet
    3. Composição
  6. Flow-Based Programming IDE
    1. Introdução
    2. Arquitetura
    3. Protótipo
  7. Flow-Based Programming IDE II
    1. Introdução
    2. Odd filter
  8. Flow-Based Programming IDE – III
    1. Introdução
    2. Writer e Reader

Flow-Base Programming

Flow-Based Programming envolve basicamente usar uma miríade componentes ativos (processos ou threads) que ficam esperando dados em suas portas de entrada, transformando os dados recebidos e enviando através de suas portas de saída. Cada componente só interage com suas portas de entrada e saída e dorme até que “batam a sua porta”. Isto é, quando há algum pacote para processar nas portas de entrada. Internamente pode delegar a subcomponentes “ouvir” cada porta. Subcomponentes e subnetwork podem representar um esquema de “bonecas russas”. A implementação interna pode ser baseada em componentes em várias camadas até atingir componentes atômicos, que são implementados sem o uso de outros componentes. Externamente os componentes são conectados numa rede que interliga suas portas de entrada e saída. Os sistemas desenvolvidos assim poderiam ser chamados de o laço eterno. Na verdade muitos laços.

Conceitos

Component

component

Componente (component) é um dos principais ingredientes em flow-based programming. É um módulo que fornece uma transformação/triagem de pacotes  recebidos de portas de entrada e que são enviados para portas de saída. Os pacotes não enviados são descartados explicitamente. Estas portas são utilizadas para ligar os componentes uns aos outros.

Um componente, ao ser criado, pode iniciar imediatamente um laço perene onde “escuta”, em estado “dormente” (sem consumir ciclos de CPU) as portas (waiting). Quando há pacotes enfileirados  numa porta de entrada o componente “acorda” (passando a consumir CPU) e eles são removidos repetidamente e enviados para portas de saída ou então são descartados explicitamente. Pacotes também podem ser gerados no componente e enviados para portas de saída.

Um componente pode conter componentes internos criados no seu interior mas não devem compartilhar componentes (instâncias).

As classes dos componentes são subclasses de Component. Component fornece alguns métodos de apoio e obriga o override do laço de execução. Veja abaixo algumas partes código:

component-class

O código em Smalltalk acima cria uma classe FBPComponent que servirá de superclasse para toda classe de componente. Na linha 2 são declaradas duas variáveis de instância. outputPorts se refere às portas de saída que serão armazenadas num dicionário (Instância da classe Dictionary). inputPorts também é um dicionário e se refere às portas de entrada do componente. Os dicionários (hash tables) permitem recuperar uma porta pelo seu nome. Dois métodos do componente são bastante usados na implementação do laço infinito nas subclasses: FBPComponente>>#send:to: FBPComponente>>#receiveFrom:.

send-to

O método tem dois parâmetros: o packet a ser enviado e o símbolo da porta de saída. Um exemplo de uso poderia ser:

using-send-to

O outro método é usado para receber pacotes numa porta:

receive-from

Exemplo de uso:

using-receive-from

As mensagens #next e #nextPut: que aparecem nas implementações dos métodos acima correspondem a métodos para manipular a estrutura de dados que representa uma fila. #next retorna o primeiro pacote da fila e o remove. #nextPut: coloca o pacote no final da fila. A fila representa a conexão e é o único objeto que é compartilhado entre dois componentes (um para cada conexão). Este modelo é comumente chamado de producer-consumer problem.

Nota: Os tratamentos de erros serão omitidos para tornar o código mais legível exceto quando o foco for o próprio tratamento de erros.

Port

ports   As portas (ports) podem ser de entrada (input port) ou de saída (output port). representam as extremidades de uma conexão (connection). As portas de um mesmo componente devem ter nomes distintos. As portas são identificadas com símbolos do Smalltalk (symbol). Um symbol é uma forma econômica de usar strings que tem uma única instância e são reutilizadas sem necessidade de duplicar o uso da memória como pode acontecer com strings. #IN e #OUT são exemplos de símbolos.

Na implementação atual não existe algo como uma classe Port da qual as portas sejam instâncias. No tópico Connection abaixo a implementação do conceito fica clara. Em uma versão futura caso se necessite uma semântica em que a existência de uma classe Port facilite as coisas ela pode ser introduzida.

Information Packet (IP)

Os pacotes (packets) são as unidades de informação (IP – Information Packet) que são processadas no interior dos componentes, recebidas nas portas de entrada ou descartados explicitamente. Podem também carregar programas (pattern strategy) ou serem visitantes (pattern visitor). Quando carregando informação é recomendado que sejam imutáveis (immutable) e impossíveis de serem copiados (unclonable) em alguns casos. Pacotes podem ser criados internamente para serem enviados através das portas de saída.

A implementação de IP é feita através de uma classe FBPInformationPacket:

IP-class

A propriedade content de um InformationPacket referencia o conteúdo de dados carregado pelo packet.

O método de criação requer que o contéudo seja fornecido:

IP-creation

Um exemplo de uso pode ser visto abaixo:

using-IP-creation

O código acima cria um packet que irá transportar o número inteiro 10. Um pacote pode, em princípio, transportar qualquer objeto.

Connection

connection As conexões (connections) são a únicas ligações entre os componentes. São unidirecionais e formam uma rede com os componentes (network) que pode ser vista como um grafo direto (direct graph). Nada mais são do que filas (queue ou FIFO – First In First Out) com capacidade limitada (bounded buffer). Enviar um pacote para a porta de saída equivale a colocá-lo no final da fila. Receber um pacote de uma porta de entrada equivale a retirá-lo do início da fila. O processo/thread do componente fica bloqueado (com a execução suspensa – suspended) quando tenta receber um pacote de uma porta de entrada acoplada a uma fila vazia ou quando tenta enviar um pacote para uma porta de saída acoplada a uma fila no limite da capacidade. Os processos/threads são acordados (resume) quando as filas deixam de ser vazias ou se tornam ocupadas aquém da capacidade máxima. Isto acontece quando no outro extremo da conexão um pacote é enviado ou recebido a depender porta em questão ser de entrada ou de saída.

Network

filter-diagram

A rede (network) é composta de componentes (nós de um grafo) e conexões (arestas de um grafo). Pode ser representada por um grafo direto (direct graph), onde as arestas são unidirecionais, isto é, os pacotes fluem sempre numa mesma direção em cada aresta. A rede é configurada conectando-se uma porta de saída de um componente a uma porta de entrada de outro componente. Uma conexão não pode ter suas extremidades no mesmo componente. Várias conexões de saída de um componente podem ser conectadas a uma mesma porta de entrada de outro componente mas o inverso não pode ser feito (uma porta de saída conectada a várias portas de entrada de outro componente) pois implicaria numa repetição do envio de um pacote pela mesma porta. Um pacote enviado não deve ser mais usado num componente (afinal ele deu “tchau”e saiu pela porta). Várias regras limitadoras são impostas como disciplina de programação (em alguns casos travas podem ser programadas ) visando imitar o que ocorre com os objetos no mundo físico e permitir uma raciocínio mais intuitivo sobre a correção das implementações. A implementação no estágio corrente consta de uma classe Network com um método para instalar uma conexão.

O código abaixo conecta os componentes em um exemplo que será usado mais adiante e será melhor explicado depois. Por agora é bem provável que a sua intuição esteja certa sobre o que ele faz graças a excelente legibilidade do Smalltalk que permite escrever código na forma de uma DSL facilmente.

network-config

Initial Information Packet (IIP)

filter-diagram

IIP é um componente (preliminarmente pelo menos). Mas possui só portas de saída. É usado para iniciar valores geralmente de configuração. O diagrama no topo dos post omite os IIP. Acima mostramos o diagrama completo (o mesmo já mostrado no tópico Network).   O diagrama acima é base de um dos exemplos que será mostrado em posts futuros e então os detalhes serão explicitados.

As redes (networks) de componentes cujas figuras aparecem neste post já foram esboçadas no paper On the Architectural Requirements of an Engineered System, de Nate Edwards. O diagrama mostra as conexões como filas e lembra um pouco um sistema hidráulico com lugares (as filas) para acúmulo de fluido e os componentes como se fossem válvulas. Veja a sugestiva figura abaixo:

nate-edwards-paper-fig-6

Anúncios

3 Respostas para “SmallFBP: a Smalltalk framework for Flow-Based Programming – Part 2

  1. Pingback: SmallFBP: a Smalltalk framework for Flow-Based Programming | Crab Log

  2. Pingback: SmallFBP: a Smalltalk framework for Flow-Based Programming – Part 3 | Crab Log

  3. Pingback: SmallFBP: a Smalltalk framework for Flow-Based Programming – Part 4 | Crab Log

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s