Inter-process Communication


Gostaria de modularizar seus sistemas Object Pascal em pequenos executáveis mas não sabe como?

Unsplash image Photo by Climate KIC on Unsplash

Introdução

Muitos sistemas começam simples. Uma dúzia de tabelas, alguns cadastros, um formulário de login e poucas Regras de Negócio.

Com o tempo é necessário ter alguns relatórios, mais cadastros, mais tabelas e muito mais Regras de Negócio.

A complexidade vai aumentando cada vez mais. O que antes era simples, agora é um “monstro” monolítico.

Essa história parece familiar?

Isso já aconteceu comigo — mais de uma vez — e talvez esteja acontecendo com você agora mesmo.

Hoje vou lhe apresentar uma técnica (antiga) para modularizar seus sistemas, facilitando a manutenção e, possivelmente, diminuir a complexidade do código.

Esse artigo irá focar numa dessas técnicas chamada Inter-process Communication ou IPC.

IPC

Um sistema pode ser modularizado de várias maneiras. Podemos utilizar algumas técnicas como DLL’s, Packages, WebServices, Microservices e algumas outras.

O IPC permite que dois processos (executáveis) distintos se comuniquem entre si através de mensagens que são gerenciadas pelo sistema operacional.

Essa técnica é muito utilizada por sistemas operacionais de microkernel como, por exemplo, o sistema operacional MINIX3.

O objetivo principal é diminuir o número de funcionalidades de um executável monolítico, utilizando um design mas modular, onde haverá uma comunicação entre processos colaborativos ao invés de haver um único processo que faz tudo.

A comunicação por IPC é do tipo cliente/servidor, sendo que cada processo pode ser tanto um como outro ao mesmo tempo.

Então, imagine projetar um sistema onde seus módulos seriam divididos em vários executáveis. Um módulo com as Regras de Negócio, outro de Relatórios para disponibilizá-los tanto na Web quanto no Desktop, outro para login, etc.

Alguns destes módulos seriam executados na mesma máquina e, portanto, seria mais vantajoso se esses executáveis se comunicassem através de mensagens gerenciadas pelo Sistema Operacional ao invés de utilizar uma nova camada de protocolos (REST, SOAP, etc). Para esses casos, podemos utilizar o IPC.

Mas como implementá-lo?

SimpleIPC

No compilador Free Pascal existe um package chamado fcl-process que implementa o IPC.

Essa implementação foi codificada numa única Unidade chamada simpleipc.pp e é cross-platform, ou seja, um único código que funciona em sistemas Unix-like e Windows.

O próprio Lazarus utiliza o SimpleIPC para fazer a comunicação entre a IDE e o Help Viewer.

Basicamente são duas classes principais a saber:

  1. A classe TSimpleIPCClient implementa o envio das mensagens
  2. A classe TSimpleIPCServer implementa o recebimento das mensagens

Exemplos de uso de ambas as Classes podem ser visto nos demos disponibilizados no próprio package, aqui.

Alternativas

Para aqueles que não utilizam Free Pascal, existe a opção de utilizar a implementação do SimpleIPC no formato de DLL.

O projeto SimpleIPC Library encapsula a implementação do Free Pascal numa DLL que pode ser utilizada por praticamente qualquer linguagem.

O código é bastante procedural — padrão em DLL’s — porém pode ser uma alternativa rápida para começar a utilizar essa técnica ao invés de implentá-la do zero.

Considere que mesmo que sua linguagem já implemente tal padrão, talvez ele não seja compatível com outras linguagens. Nesses casos o uso de uma DLL padrão pode fazer sentido.

No Windows o IPC pode ser “traduzido” como uma Windows Message do tipo WM_COPYDATA. Sabemos que é relativamente fácil trabalhar com mensagens do Windows no Object Pascal então, se o desenvolvimento for apenas para a plataforma Windows, talvez seja mais simples utilizar mensagens do tipo WM_COPYDATA. Esses links aqui, aqui e aqui, podem ajudar.

Conclusão

Nos anos 60 já existiam tais técnicas de modularização. No entanto, ainda hoje, continuamos a desenvolver softwares monolíticos, pesados e de difícil manutenção.

Como visto nesse artigo, utilizar o IPC pode facilitar a manutenção do código, pois cada subprojeto (executável) iria lidar apenas com poucos contextos, possivelmente diminuindo a complexidade.

Cada subprojeto poderia evoluir e ser utilizado independentemente.

Até logo.

Posts Relacionados

  • Memória Segura Utilizando Instâncias de Interfaces

  • Classes Mutáveis vs Objetos Imutáveis

  • Implementando Interfaces Utilizando Diferente Assinaturas de Métodos

  • Usando Paths ao invés de Diretivas de Compilação

  • Trabalhando com Exceções em Requisições HTTP

  • Tipo object Continua Vivo

  • Array de Objetos

  • Variáveis Locais Deveriam ter Nomes Curtos

  • Como Dividir e Organizar o Código em Formulários com Muitos Widgets

  • Pascal Deveria ser Modernizado?