Corredor
que recebe duas URLs que "competirão" entre si através de uma chamada HTTP GET onde a primeira URL a responder será retornada. Se nenhuma delas responder dentro de 10 segundos a função deve retornar um erro
.net/http
para chamadas HTTP.net/http/httptest
para nos ajudar a testar.select
para sincronizar processos../corredor_test.go:14:9: undefined: Corredor
corredor_test.go:25: resultado '', esperado 'http://www.quii.co.uk'
time.Now()
para marcar o tempo antes de tentarmos pegar a URL
.http.Get
para tentar capturar os conteúdos da URL
. Essa função retorna http.Response
e um erro
, mas não temos interesse nesses valores.time.Since
pega o tempo inicial e retorna a diferença na forma de time.Duration
.net/http/httptest
onde é possível simular um servidor HTTP facilmente.httptest.NewServer
recebe um http.HandlerFunc
que vamos enviar para uma função anônima.http.HandlerFunc
é um tipo que se parece com isso: type HandlerFunc func(ResponseWriter, *Requisicao)
.ResponseWriter
e uma Requisição
, o que não é novidade para um servidor HTTP.httptest.NewServer
,o que facilita seu uso em testes por ele encontrar uma porta aberta para escutar e você poder fechá-la quando estiverem concluídos dentro dos próprios testes.time.Sleep
quando receber a requisição para torná-lo propositalmente mais lento que o outro. Ambos os servidores, então, devolvem uma resposta OK
com w.WriteHeader(http.StatusOK)
a quem realizou a chamada.Corredor
bem mais legível.criarServidorComAtraso
para remover alguns códigos desnecessários do nosso teste e reduzir repetições.defer
defer
, ela será chamada após o término da função que a contém.defer
quando queremos que a função seja executada no final de uma função, mas mantendo essa instrução próxima de onde o servidor foi criado para facilitar a vida das pessoas que forem ler o código futuramente.select
que nos ajudará a sincronizar os processos de forma mais fácil e clara.ping
ping
que cria um chan bool
e a retorna.http.Get(URL)
tenha sido finalizada.select
variavel := <-ch
. Isso é uma chamada bloqueante, pois está aguardando por um valor.select
te permite fazer é aguardar múltiplos canais. O primeiro a enviar um valor "vence" e o código abaixo do case
é executado.ping
em nosso select
para configurar um canal para cada uma de nossas URL
s. Qualquer um que enviar para esse canal primeiro vai ter seu código executado no select
, que resultará nessa URL
sendo retornada (que consequentemente será a vencedora).Corredor
demorar mais que 10 segundos.Corredor
retorne dois valores: a URL vencedora (que ignoramos nesse teste com _
) e um erro
../corredor_test.go:37:10: assignment mismatch: 2 variables but 1 values
Corredor
para retornar o vencedor e um erro
. Retornamos nil
para nossos casos de sucesso.obteve, _ := Corredor(urlLenta, urlRapida)
. Sabendo disso devemos verificar se não obteremos um erro em nosso caso de sucesso.time.After
é uma função muito útil quando usamos select
. Embora não ocorra em nosso caso, você pode escrever um código que bloqueia para sempre se os canais que o select
estiver ouvindo nunca retornarem um valor. time.After
retorna um chan
(como ping
) e te enviará um sinal após a quantidade de tempo definida.a
ou b
conseguir retornar teremos um vencedor, mas se chegar a 10 segundos nosso time.After
nos enviará um sinal e retornaremos um erro
.Corredor
(que usa Configuravel
por baixo dos panos) e nosso caminho triste pode usar Configuravel
.erro
.select
time.After
em um de seus cases
para prevenir que seu sistema fique bloqueado para sempre.httptest
net/http
reais, o que torna seu sistema consistente e gera menos coisas para você aprender.