Use RWMutex instead of atomic value

This commit is contained in:
Jan-Lukas Else 2021-03-19 11:26:45 +01:00
parent ded4294c45
commit e5117779cc
2 changed files with 15 additions and 8 deletions

20
http.go
View File

@ -8,7 +8,7 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync/atomic" "sync"
"time" "time"
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
@ -93,15 +93,15 @@ func reloadRouter() error {
if err != nil { if err != nil {
return err return err
} }
purgeCache()
d.swapHandler(h) d.swapHandler(h)
purgeCache()
return nil return nil
} }
const paginationPath = "/page/{page:[0-9-]+}" const paginationPath = "/page/{page:[0-9-]+}"
const feedPath = ".{feed:rss|json|atom}" const feedPath = ".{feed:rss|json|atom}"
func buildHandler() (http.Handler, error) { func buildHandler() (*chi.Mux, error) {
startTime := time.Now() startTime := time.Now()
r := chi.NewRouter() r := chi.NewRouter()
@ -501,16 +501,22 @@ func noIndexHeader(next http.Handler) http.Handler {
} }
type dynamicHandler struct { type dynamicHandler struct {
realHandler atomic.Value router *chi.Mux
mutex sync.RWMutex
} }
func (d *dynamicHandler) swapHandler(h http.Handler) { func (d *dynamicHandler) swapHandler(h *chi.Mux) {
d.realHandler.Store(h) d.mutex.Lock()
d.router = h
d.mutex.Unlock()
} }
func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (d *dynamicHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Fix to use Path routing instead of RawPath routing in Chi // Fix to use Path routing instead of RawPath routing in Chi
r.URL.RawPath = "" r.URL.RawPath = ""
// Serve request // Serve request
d.realHandler.Load().(http.Handler).ServeHTTP(w, r) d.mutex.RLock()
router := d.router
d.mutex.RUnlock()
router.ServeHTTP(w, r)
} }

View File

@ -5,6 +5,7 @@ import (
"log" "log"
"os" "os"
"os/signal" "os/signal"
"runtime"
"runtime/pprof" "runtime/pprof"
"syscall" "syscall"
@ -138,7 +139,7 @@ func main() {
log.Fatal("could not create memory profile: ", err) log.Fatal("could not create memory profile: ", err)
} }
defer f.Close() defer f.Close()
// runtime.GC() // get up-to-date statistics runtime.GC()
if err := pprof.WriteHeapProfile(f); err != nil { if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err) log.Fatal("could not write memory profile: ", err)
} }