| --- |
| title: Bounding resource use |
| --- |
| |
| To 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): |
| |
| ```go |
| const ( |
| AvailableMemory = 10 << 20 // 10 MB |
| AverageMemoryPerRequest = 10 << 10 // 10 KB |
| MaxOutstanding = AvailableMemory / AverageMemoryPerRequest |
| ) |
| |
| var sem = make(chan int, MaxOutstanding) |
| |
| func Serve(queue chan *Request) { |
| for { |
| sem <- 1 // Block until there's capacity to process a request. |
| req := <-queue |
| go handle(req) // Don't wait for handle to finish. |
| } |
| } |
| |
| func handle(r *Request) { |
| process(r) // May take a long time & use a lot of memory or CPU |
| <-sem // Done; enable next request to run. |
| } |
| ``` |
| |
| ## References |
| |
| Effective Go's discussion of channels: https://go.dev/doc/effective_go#channels |
| |