49 lines
1.4 KiB
Go
49 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"net/url"
|
|
)
|
|
|
|
// startProxy starts an HTTP reverse proxy that forwards requests to workers.
|
|
// It acquires a worker from the pool for each request and releases it when done.
|
|
func startProxy(listenAddr string, pool *WorkerPool) {
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Acquire a worker (blocks if none available)
|
|
workerAddr, ok := pool.Acquire()
|
|
if !ok {
|
|
http.Error(w, "Service unavailable", http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
|
|
// Ensure we release the worker when done
|
|
defer pool.Release(workerAddr)
|
|
|
|
// Create reverse proxy to the worker
|
|
targetURL, err := url.Parse("http://" + workerAddr)
|
|
if err != nil {
|
|
log.Printf("[proxy] Failed to parse worker URL %s: %v", workerAddr, err)
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
proxy := httputil.NewSingleHostReverseProxy(targetURL)
|
|
|
|
// Custom error handler
|
|
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
|
|
log.Printf("[proxy] Error proxying to %s: %v", workerAddr, err)
|
|
http.Error(w, "Bad gateway", http.StatusBadGateway)
|
|
}
|
|
|
|
log.Printf("[proxy] %s %s -> %s", r.Method, r.URL.Path, workerAddr)
|
|
proxy.ServeHTTP(w, r)
|
|
})
|
|
|
|
log.Printf("[proxy] Listening on %s", listenAddr)
|
|
if err := http.ListenAndServe(listenAddr, handler); err != nil {
|
|
log.Fatalf("[proxy] Failed to start: %v", err)
|
|
}
|
|
}
|