Programação distribuída

» Slides sobre programação distribuída

Existem várias razões para escrever aplicações distribuídas. Entre elas:

O primeiro passo para criar um ambiente distribuído em Erlang é transformar a shell num nó com capacidades de comunicação remota. A partir desse momento é possível executar diversas operações, como por exemplo:


Criação de nós

Para criar um nó de um ambiente distribuído em Erlang podem ser usadas as seguintes flags na linha de comando do sistema operativo (em windows substituir o comando erl por werl):

erl -name nome_do_nó

Cria um nó Erlang. O nome do nó será nome_do_nó@máquina.domínio

Exemplo:

erl -name no1

Eshell V4.7 (abort with ^G)
(no1@alvega.dei.isep.ipp.pt)1>


erl -sname
  nome_do_nó

À semelhança de -name cria um nó distribuído. No entanto o formato será nome_do_nó@máquina

Exemplo:

erl -sname no1

Eshell V4.7 (abort with ^G)
(no1@alvega)1>

Esta é por vezes a única forma de criar nós num ambiente sem DNS (Domain Name Service).

Nota: Não existirá comunicação entre os nós criados com -name e aqueles criados com -sname, uma vez que os
nomes dos nós têm de ser únicos num sistema distribuído.


BIFs para programação distribuída

O mecanismo de distribuição é internamente implementado usando sockets TCP/IP.

No Erlang são usadas as seguintes BIFs para programação distribuída:

As funções spawn/4 e spawn_link/4 retornam à semelhança das suas versões com 3 argumentos um Pid que pode ser usado da forma habitual. No caso de spawn_link/4, se o nó não existir é gerado um sinal EXIT. Quase todas as operações que são normalmente usadas com Pids locais também são permitidas com Pids remotos. Por exemplo, podem ser enviadas mensagens para processos remotos e podem ser estabelecidas ligações entre os processos tal como se se tratassem de processos locais.

Para enviar mensagens a processos registados num dado nó usamos a seguinte notação:

{Nome do processo, Nome do nó} ! Mensagem

Nota: Nesta aula ainda só vai ser possível criar nós na mesma máquina (abrir portos diferentes no mesmo endereço IP). O mecanismo de autenticação entre nós de IPs diferentes será abordado na próxima aula.


Conexões entre nós

As conexões entre nós são estabelecidas na primeira vez que se usa o nome de um nó remoto, por exemplo se for usada a função spawn/4 ou net_adm:ping(Nó). Podem ainda ser explicitamente estabelecidas conexões entre nós, usando a função net_kernel:connect_node(Nó). No entanto, só será necessário estabelecer conexões explicitamente se tiver sido usada a flag -dist_auto_connect na linha de comandos.

As conexões são, por omissão, transitivas. Se um nó A se conectar a um nó B e este tiver uma conexão com um nó C, então A tentará estabelecer uma conexão com o nó C. Esta característica pode ser alterada se se usar a flag -connect_all false na linha de comando.


Exercícios

1) Crie 2 ou mais nós na mesma máquina. Num dos nós lance um processo que aguarda mensagens originadas por processos do(s) restante(s) nó(s). Sempre que recebe uma mensagem deve imprimi-la, indicando o pid e o nó do emissor e devolve uma confirmação de recepção.

2) Crie um sistema com um nó central e 6 nós periféricos, de acordo com a figura 1.

modelo estrela

Fig. 1 - Modelo de rede em estrela

Um processo master do nó central deverá criar um processo slave em cada um dos nós periféricos e aguardar pedidos de clientes (que podem estar em qualquer um destes 7 nós ou noutros nós que podem ser criados na máquina).

Os clientes recebem da linha de comando uma lista de inteiros e pedem ao processo master que some o seu conteúdo.

Sempre que o master recebe um pedido de um cliente, envia a um dos slaves a lista recebida, aguarda o valor final da soma do seu conteúdo e devolve-o ao cliente. A distribuição de pedidos pelos slaves deve obedecer a uma política round robin.

Se um processo slave terminar anormalmente deve ser recriado pelo master.

Se o master receber uma mensagem stop, deve avisar todos os slaves que devem terminar normalmente. Após ter a confirmação de que todos os slaves terminaram, ele próprio deve terminar.