-
Notifications
You must be signed in to change notification settings - Fork 0
http
Benjamin Bennett edited this page Dec 12, 2020
·
6 revisions
This example uses channels, waitgroup and timeouts to make concurrent, bounded http requests.
cd go-bits/http
go run -race main.go
The tests can be run to verify behaviour.
cd go-bit/http
go test ./... -race

- A context with a timeout is created for use in cancelling ongoing goroutines.
- An http client is created with a timeout specifying the time limit for requests.
- A new request client is created.
- Calling
client.GetResultChannel
returns a channel of result. - We range over the channel of
result
and output either the status code from a successful request or the error from an unsuccessful request.

- The
client
struct uses thedo func
to make http requests and theconcurrencyLimit
to limit the number of concurrent requests. - The
result
andstatus
structs are used to hold the responses from the http requests.

- Sending to the
semaphoreChan
will block when the channel buffer is full, thereby limiting the number of concurrent requests. - The
resultChan
is used to hold the results from the http requests and is returned immediately allowing main to range over. - A
sync.WaitGroup
is created and used to track the goroutines started to make the http requests. - The
WaitGroup
is counter is incremented by the number of urls that will be requested concurrently. - The urls are ranged over and a goroutine is started for each request.
- A select is used to determine whether the context has been cancelled or timed out, if so the
WaitGroup
is decremented. - If
context.Done()
cannot be received from, thesemaphoreChan
is sent to. - An http request is made by calling
c.GetResult
(see below) and the result is sent to theresultsChan
. - The
semaphoreChan
is received from thereby reducing the number ofstruct{}
in the channel by one. - The
WaitGroup
is decremented. - An additional goroutine is started and uses
Wait
to block until all of the goroutines started to make http requests have completed or have timed out or been cancelled. Both thesemaphoreChan
andresultsChan
are then closed, the latter is required as ranging over theresultsChan
in main.go will block otherwise.

- A
NewRequestWithContext
is used to allow cancellation/timeout of the request.