Created
November 4, 2019 09:45
-
-
Save Integralist/b39b53e7f33970223eca5fb814c6add6 to your computer and use it in GitHub Desktop.
[Golang HTTP Web Server Parallel Tee Goroutine per Request] #go #golang #tee #parallel #http #web #server #request #pool #concurrency
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"io/ioutil" | |
"net/http" | |
) | |
var largePool chan func() | |
var smallPool chan func() | |
func main() { | |
// Start two different sized worker pools (e.g., for different workloads). | |
// Cancelation and graceful shutdown omited for brevity. | |
largePool = make(chan func(), 100) | |
smallPool = make(chan func(), 10) | |
for i := 0; i < 100; i++ { | |
go func() { | |
for f := range largePool { | |
f() | |
} | |
}() | |
} | |
for i := 0; i < 10; i++ { | |
go func() { | |
for f := range smallPool { | |
f() | |
} | |
}() | |
} | |
http.HandleFunc("/endpoint-1", handler1) | |
http.HandleFunc("/endpoint-2", handler2) // naming things is hard, okay? | |
http.ListenAndServe(":8080", nil) | |
} | |
func handler1(w http.ResponseWriter, r *http.Request) { | |
// Imagine a JSON body containing a URL that we are expected to fetch. | |
// Light work that doesn't consume many of *our* resources and can be done | |
// in bulk, so we put in in the large pool. | |
var job struct{ URL string } | |
if err := json.NewDecoder(r.Body).Decode(&job); err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
go func() { | |
largePool <- func() { | |
http.Get(job.URL) | |
// Do something with the response | |
} | |
}() | |
w.WriteHeader(http.StatusAccepted) | |
} | |
func handler2(w http.ResponseWriter, r *http.Request) { | |
// The request body is an image that we want to do some fancy processing | |
// on. That's hard work; we don't want to do too many of them at once, so | |
// so we put those jobs in the small pool. | |
b, err := ioutil.ReadAll(r.Body) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
go func() { | |
smallPool <- func() { | |
processImage(b) | |
} | |
}() | |
w.WriteHeader(http.StatusAccepted) | |
} | |
func processImage(b []byte) {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment