blob: a34ae5729de60689405dbb0d6bf9e659a5391fe3 [file] [log] [blame] [view]
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11001# Bounding resource use
2
nathanyad56cb22014-12-10 09:37:30 -08003To bound a program's use of a limited resource - like memory - have goroutines synchronize their use of that resource using a buffered channel (i.e., use the channel as a semaphore):
Dave Day0d6986a2014-12-10 15:02:18 +11004
nathanyad56cb22014-12-10 09:37:30 -08005```go
Andrew Gerrand5bc444d2014-12-10 11:35:11 +11006const (
Dave Day0d6986a2014-12-10 15:02:18 +11007 AvailableMemory = 10 << 20 // 10 MB
8 AverageMemoryPerRequest = 10 << 10 // 10 KB
9 MaxOutstanding = AvailableMemory / AverageMemoryPerRequest
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110010)
Dave Day0d6986a2014-12-10 15:02:18 +110011
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110012var sem = make(chan int, MaxOutstanding)
13
14func Serve(queue chan *Request) {
Dave Day0d6986a2014-12-10 15:02:18 +110015 for {
16 sem <- 1 // Block until there's capacity to process a request.
17 req := <-queue
18 go handle(req) // Don't wait for handle to finish.
19 }
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110020}
21
22func handle(r *Request) {
Dave Day0d6986a2014-12-10 15:02:18 +110023 process(r) // May take a long time & use a lot of memory or CPU
24 <-sem // Done; enable next request to run.
Andrew Gerrand5bc444d2014-12-10 11:35:11 +110025}
26```
27
28## References
29
30Effective Go's discussion of channels: http://golang.org/doc/effective_go.html#channels