WebSiteRacer
라는 함수를 만들라는 요청을 받았다. 10초 이내에 반환되는 항목이 없으면 오류를 반환해야 한다.net/http
을 사용해 HTTP 호출을 한다.net/http/httptest
를 사용해 테스트를 한다.select
한다../racer_test.go:14:9: undefined: Racer
racer_test.go:25: got '', want 'http://www.quii.co.uk'
URL
을 가져 오기 전에 time.Now()
를 사용하여 기록한다.time.Since
는 시작 시간을 받으며 차이인 time.Duration
을 반환한다.httptest.NewServer
는 익명 함수를 이용해 보내는 http.HandlerFunc
를 받는다.http.HandlerFunc
의 타입은 type HandlerFunc func(ResponseWriter, *Request)
와 같다.ResponseWriter
와 Request
를 받는 함수가 필요하다는 것이다. 이것은 HTTP 서버에는 그렇게 놀라운 일이 아니다.httptest.NewServer
로 감싸는 것이다. 이것은 요청을 대기할 열린 포트를 찾고 테스트가 끝나면 닫을 수 있기 때문에 테스트와 함께 사용하기가 더 쉽다.time.Sleep
을 만든다. 그런 다음 두 서버 모두 w.WriteHeader (http.StatusOK)
와 함께 OK
응답을 호출자에게 반환한다.Racer
코드를 훨씬 쉽게 읽을 수 있게 만든다.makeDelayedServer
라는 함수로 리팩터링 하여 테스트에서 흥미롭지 않은 코드를 옮기고 반복을 줄였다.defer
defer
를 붙이면 해당 함수를 포함하는 함수의 끝에서 호출합니다.ping
chan struct {}
를 생성하고 그것을 반환하는 ping
함수를 정의했다.bool
과 같은 다른 타입이 아닌 struct {}
일까? chan struct {}
는 메모리 관점에서 사용할 수 있는 가장 작은 데이터 타입이므로 bool
에 비해 할당이 없다. 닫은 후에 채널에 아무것도 보내지 않는데 왜 할당해야 할까요?http.Get(url)
을 완료하면 해당 채널로 신호를 보내는 고루틴을 시작한다.var ch chan struct {}
를 선언하는 것보다 채널을 만들 때 make
를 어떻게 사용해야 하는지 주의해야 한다. var
를 사용할 때 변수는 타입의 "비어있는" 값으로 초기화된다. 따라서 string
의 경우 ""
, int
는 0 등으로 초기화된다.nil
이고 <-
을 사용해 보내려고 하면 nil
채널로 보낼 수 없기 때문에 영원히 차단된다.select
myVar := <- ch
를 사용해 값이 채널로 전송 될 때까지 기다릴 수 있다. 값을 기다리고 있으므로 차단 호출이다.select
을 사용하면 여러 채널에서 대기 할 수 있습니다. 처음으로 값을 보내는 항목이 "승리"하고 case
아래의 코드가 실행된다.select
에서 ping
을 사용하여 각 URL
에 대해 두 개의 채널을 설정한다. 어느 쪽이 먼저 채널에 작성하든 select
에서 코드가 실행되어 URL
이 반환되고 승자가 된다.Racer
가 10 초 이상 걸리면 오류를 반환하는 것이다.Racer
가 두 개의 값, 즉 승리 URL (이 테스트에서는 _
로 무시함)과 error
를 반환할 것으로 예상한다../racer_test.go:37:10: assignment mismatch: 2 variables but 1 values
Racer
의 시그니처를 변경하여 승자와 error
를 반환한다. 행복한 케이스에 대해서는 nil
을 반환한다.got, _ := Racer(slowURL, fastURL)
로 변경하여 행복한 시나리오에서 오류가 발생하지 않는지 확인해야 한다.time.After
는 select
를 사용할 때 매우 편리한 기능이다. 우리의 경우에는 발생하지 않았지만 수신중인 채널이 값을 반환하지 않으면 영원히 차단되는 코드를 잠재적으로 작성할 수 있다. time.After
는 chan
(ping
과 같은)을 반환하고 정의한 시간 후에 신호를 보낸다.a
또는 b
가 반환하면 승리하지만 10 초가 되면 time.After
가 신호를 보내고 오류를 반환하게 된다.Racer
(내부에서 ConfigurableRacer
사용)를 사용할 수 있고 슬픈 경로 테스트에서는 ConfigurableRacer
를 사용할 수 있다.error
가 없는지 확인하기 위해 첫 번째 테스트에서 최종 확인을 추가했다.select
cases
중 하나에 time.After
를 포함하고 싶을 것이다.httptest
net/http
서버와 동일한 인터페이스를 사용한다.