• Nenhum resultado encontrado

Darch uma arquitetura distribuída para o teste de programas concorrentes

A Darch (Distributed ARCHtechture) é uma arquitetura de software distribuída e multiproces- sada que atua como um middleware entre aplicações que interagem por passagem de mensagens na linguagem Java. A Darch representa um subproduto da paralelização da geração automática de pares de sincronização proposta neste trabalho.

A Darch encapsula as primitivas de sincronização por meio da abstração da API (Application Programming Interface) de Datagram Sockets. A Darch também fornece gerenciamento de lo- calização possibilitando a comunicação entre duas aplicações sem a necessidade de conhecer o endereço ou a porta do host à qual a aplicação de destino está conectada. Um terceiro objetivo é a instanciação remota de aplicações com escalonamento por prioridades. O escalonamento por prioridades visa balancear a alocação das aplicações entre os hosts disponíveis onde a arquitetura é executada. O termo host está sendo usado neste trabalho como sinônimo de processador, nó ou elemento de processamento. Existem três níveis de prioridade: baixo (LOW), médio (MEDIUM) e alto (HIGH). Quanto maior for o nível de prioridade maior será a probabilidade da aplicação ser alocada exclusivamente em um host.

A Darch é dividida em dois módulos: aplicação e distribuição. O módulo de aplicação é uma biblioteca que facilita a comunicação com outras aplicações, tais como os módulos da ferramenta ValiPar: a ValiExec, ValiEval e ValiSync. O módulo de distribuição atua como um daemon, i.e., um processo em background responsável por gerenciar a comunicação entre as aplicações locais e aplicações remotas. Para executar uma aplicação que utiliza a arquitetura é necessário um processo do módulo de distribuição executando no host desejado e que as aplicações utilizem o módulo de aplicação para interagirem.

Ao iniciar a arquitetura, o módulo de distribuição é automaticamente criado em todos os hosts onde a aplicação será executada. A instanciação dos módulos de distribuição ocorre baseada em um arquivo de configuração.

Cada módulo é dividido em camadas que encapsulam responsabilidades e tornam a arquitetura facilmente extensível. O módulo de aplicação é dividido em duas camadas: interface de dados e comunicação.

A interface de dados permite que as mensagens enviadas sejam implicitamente transforma- das para um formato que possa ser facilmente transportado de uma aplicação para outra. A este processo dá-se o nome de serialização de dados (Serialization).

A camada de comunicação é responsável pelo envio e o recebimento de mensagens. A camada possui duas filas: uma para entrada (incoming) e outra para saída (outgoing) de mensagens. Esta

70

6.3. DARCH - UMA ARQUITETURA DISTRIBUÍDA PARA O TESTE DE PROGRAMAS CONCORRENTES camada possui dois pools de threads, o primeiro deles é responsável pelo recebimento das mensa- gens e por adicioná-las à fila de entrada e o segundo é responsável por retirar as mensagens da fila de saída e enviá-las ao destinatário.

O módulo de distribuição é responsável por gerenciar a comunicação entre as aplicações locais e as aplicações remotas e também pela criação de novas aplicações locais. Este módulo é dividido em quatro camadas: comunicação, interface de dados, serviço de localização de nomes (SLN) e broker. As camadas de comunicação e de interface de dados no módulo distribuidor possuem as mesmas responsabilidades que as respectivas camadas no módulo de aplicação.

O SLN é responsável por identificar quais aplicações estão disponíveis on-line e armazenar as informações sobre suas localizações. Isto ocorre durante a inicialização do módulo de aplicação, onde uma mensagem de registro é enviada ao módulo de distribuição e os dados de identificação e localização são armazenados no SLN. Uma tabela hash distribuída (DHT - Distributed Hash Table) foi utilizada para implementar o SLN; assim, todos os endereços inseridos nesta tabela estarão disponíveis para outros módulos de distribuição. A DHT utilizada foi a OpenChord (Stoica et al., 2003), que utiliza um protocolo de busca peer-to-peer escalável, no qual a resolução de nomes é armazenada localmente em memória para agilizar as consultas.

Todas as mensagens enviadas pelas aplicações são enviadas para o módulo de distribuição lo- cal contendo o identificador da aplicação de destino. O broker é responsável pelo escalonamento destas mensagens, sendo que o mesmo possui uma fila onde são inseridas as mensagens recebidas. Conforme esta fila é consumida, o endereço de destino é resolvido por meio da consulta do iden- tificador no SLN. As mensagens já resolvidas são enfileiradas na camada de comunicação com o endereço do destinatário.

A Figura 6.1 apresenta o fluxo do envio de uma mensagem entre duas aplicações localizadas em nós distintos, ilustrando o caminho percorrido entre os módulos da arquitetura e cada uma de suas camadas. As setas claras indicam chamadas internas do programa (métodos) e as setas escuras significam passagem de mensagens.

O processo é iniciado quando a Aplicação α realiza a chamada à uma primitiva de transmissão informando os dados a serem enviados e a identificação de destino (Aplicação β). Tais infor- mações são encapsuladas na interface de dados e a identificação do transmissor é adicionada à mensagem, que por sua vez é enfileirada na camada de comunicação. A camada de comunicação retira a mensagem da fila e a envia para o módulo de distribuição local por meio de passagem de mensagens.

A mensagem é recebida pela camada de comunicação do módulo de distribuição, desempa- cotada na interface de dados e inserida na fila do broker. O broker recupera o identificador da Aplicação β e busca seu endereço no SLN, este conhecido desde que ele recebeu informações de registro durante a inicialização da Aplicação β. O broker adiciona o endereço real da Aplicação β na mensagem que é encapsulada novamente (interface de dados), enfileirada na camada de comu- nicação e posteriormente enviada para a aplicação de destino em uma passagem de mensagem.

SINCRONIZAÇÃO 71

Figura 6.1: Fluxo da arquitetura durante a transmissão de uma mensagem considerando dois hosts. Cada host é delimitado nesta figura por um módulo de distribuição.

A mensagem é recebida na camada de comunicação localizada na Aplicação β, desencapsulada na interface de dados e finalmente entregue à aplicação.

Esta arquitetura encapsula os detalhes de comunicação para as aplicações, de modo que o de- senvolvimento das aplicações paralelas/distribuídas (neste contexto ambas necessitam comunicar e sincronizar) possa ser facilitado. De fato, as aplicações α e β podem enviar e receber infor- mações pela arquitetura sem ter um forte acoplamento com detalhes menores dos protocolos de comunicação.

6.4

Paralelização da geração de pares de sincronização