Pular para o conteúdo

O livro · 09

Channels de rede

book.md · 59 linhas · 2 min de leitura

Objetivo: ver que comunicação pela rede é o mesmo Channel[T] dos processos locais (o RPC tipado nativo da linguagem), e entender a constraint Serializable.

Dois processos no mesmo runtime são mundos isolados que falam por channel. Dois runtimes em máquinas diferentes são só mais dois mundos isolados, e a comunicação é o mesmo conceito. Não há tipo de channel de rede: é o Channel[T] de sempre, obtido por uma operação de net que impõe o que a física exige.

A física exige duas coisas, e ambas já existem na linguagem:

  1. O payload tem que virar bytes, então a operação pede T + Serializable (capítulo 11). Mandar algo não-serializável pela rede não compila.
  2. Estabelecer pode falhar, então a operação devolve Result, e o channel herda o timeout obrigatório do sync.
use net
// servidor: escuta, cada conexão vira um Channel[T]
listener := net.listen("0.0.0.0:8080") catch |e| { return e }
loop {
chan := net.accept[Message](listener) catch |e| { continue } // Message: Serializable
spawn handle(chan) // cada cliente = processo
}
// cliente: conecta, obtém o Channel[T]
chan := net.connect[Message]("api.exemplo:8080") catch |e| { return e }
chan <- request // MESMA API de channel
reply := -> chan timeout(5s) catch |e| { return e } // timeout já obrigatório

O que você recebe é um Channel[Message] comum: send, -> recv, <->, match/select, catch, tudo idêntico ao capítulo 06. A rede não adicionou um modelo de comunicação; reusou o channel inteiro e deixou a física (serialização, falha) se expressar pela constraint e pelo Result.

Como os dois lados compartilham T em compilação, o channel de rede é um RPC tipado, sem IDL e sem stub gerado: você manda um valor da linguagem e o outro lado recebe o mesmo tipo. (Para falar com o mundo que não é seu, cujo contrato é o formato de fio e não um T compartilhado, o caminho é HTTP, pela lib oficial http, capítulo 12.)

Para protocolos que não falam a sua serialização, net também tem a camada 2, com TcpStream/ UdpSocket (bytes) que satisfazem Readable/Writeable, e TLS fino por cima. É sobre essa camada que o http é construído.

stream := net.dial_tcp("exemplo:80") catch |e| { return e }
io.write_all(stream, pedido_http_cru)

Próximo: 10 · Comptime e reflexão