From 5150f782307a26f35c358febe4358e92b526c798 Mon Sep 17 00:00:00 2001 From: Kelvin Ly Date: Sun, 2 Jul 2023 18:40:18 -0400 Subject: [PATCH] Work on the caching logic, for now turn it off to reduce memory usage --- README.md | 7 +++++++ cache.go | 42 +++++++++++++++++++++++++++++++++++++++--- main.go | 2 +- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ade7fd2..ba1ddc5 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,10 @@ TODOs - make a cronjob to automatically renew the certificate - add a header bar and make the footer look a little nicer - do cool stuff so I can post about it here I guess + +Migration notes for myself +- copy this server over (`git clone ...` plus copying auth keys) +- run install script to set iptable rules +- copy repositories over (`./gogs backup` to generate, copy over, etc) +- rerun certbot with google-dns plugin (and copy DNS secret over, or regenerate) +- fix DNS links diff --git a/cache.go b/cache.go index 3ef0c7f..b5c5f52 100644 --- a/cache.go +++ b/cache.go @@ -2,10 +2,43 @@ package main import ( "net/http" + "runtime" + "unsafe" ) +type realCacheEntry struct { + r Response + cache map[string]cacheEntry + key string +} + +// store a pointer to the real cache entry as an int here +// so that the garbage collector can collect it if needed type cacheEntry struct { - r Response + p uintptr + //r Response +} + +func (e cacheEntry) access() *Response { + ptr := unsafe.Pointer(e.p) + entry := (*realCacheEntry)(ptr) + return &entry.r +} + +func addEntry(cache map[string]cacheEntry, s string, r Response) cacheEntry { + entry := new(realCacheEntry) + entry.r = r + entry.cache = cache + entry.key = s + + cache[s] = cacheEntry{ + p: (uintptr)(unsafe.Pointer(entry)), + } + runtime.SetFinalizer(entry, func(e *realCacheEntry) { + delete(e.cache, e.key) + }) + + return cache[s] } func Cache(h http.Handler) http.Handler { @@ -18,9 +51,12 @@ func Cache(h http.Handler) http.Handler { return } + // NOTE: not threadsafe, TODO fix that entry, exists := c[r.URL.String()] if exists { - entry.r.WriteResponse(rw) + // NOTE: the finalizer can theoretically execute between the map read + // and here + entry.access().WriteResponse(rw) } else { rc := ResponseCollector{} // copy request in case they modify it @@ -28,7 +64,7 @@ func Cache(h http.Handler) http.Handler { h.ServeHTTP(&rc, &req) resp := rc.CollectResponse() if resp.Code == 200 { - c[r.URL.String()] = cacheEntry{resp} + addEntry(c, r.URL.String(), resp) } resp.WriteResponse(rw) } diff --git a/main.go b/main.go index aa1dc3d..ace7d4c 100644 --- a/main.go +++ b/main.go @@ -189,7 +189,7 @@ func startServer(srv *http.Server) { serveMux.HandleFunc("/", rootHandler) //serveMux.Handle("/certbot/", http.StripPrefix("/certbot/", http.FileServer(http.Dir("./certbot-tmp")))) serveMux.Handle("/gfm/", http.StripPrefix("/gfm", http.FileServer(gfmstyle.Assets))) - serveMux.Handle("/resize/", Cache(Resize(640, http.StripPrefix("/resize", http.FileServer(http.Dir("static/")))))) + serveMux.Handle("/resize/", Resize(640, http.StripPrefix("/resize", http.FileServer(http.Dir("static/"))))) if webhookKey != nil { log.Print("web hook found") serveMux.HandleFunc("/update", func(w http.ResponseWriter, r *http.Request) {