Skip to content

Commit

Permalink
Revert "lock cache during update"
Browse files Browse the repository at this point in the history
This reverts commit 1a6f9b8.
  • Loading branch information
dimkr committed Oct 17, 2024
1 parent 3f7969c commit 85232aa
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 29 deletions.
29 changes: 8 additions & 21 deletions front/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
"context"
"github.com/dimkr/tootik/cfg"
"github.com/dimkr/tootik/front/text"
"golang.org/x/sync/semaphore"
"slices"
"sync"
"time"
)

Expand All @@ -40,7 +40,7 @@ func (w chanWriter) Write(p []byte) (int, error) {
return len(p), nil
}

func callAndCache(r *Request, w text.Writer, args []string, f func(text.Writer, *Request, ...string), key string, now time.Time, cache *cacheEntry) {
func callAndCache(r *Request, w text.Writer, args []string, f func(text.Writer, *Request, ...string), key string, now time.Time, cache *sync.Map) {
c := make(chan []byte)

ctx, cancel := context.WithCancel(context.Background())
Expand Down Expand Up @@ -91,41 +91,28 @@ func callAndCache(r *Request, w text.Writer, args []string, f func(text.Writer,
w2.Textf("(Cached response generated on %s)", now.Format(time.UnixDate))
w2.Flush()

cache.Value = buf.Bytes()
cache.Created = now
cache.Store(key, cacheEntry{buf.Bytes(), now})
}

func withCache(f func(text.Writer, *Request, ...string), d time.Duration, cfg *cfg.Config) func(text.Writer, *Request, ...string) {
cache := &cacheEntry{}
lock := semaphore.NewWeighted(1)

func withCache(f func(text.Writer, *Request, ...string), d time.Duration, cache *sync.Map, cfg *cfg.Config) func(text.Writer, *Request, ...string) {
return func(w text.Writer, r *Request, args ...string) {
key := r.URL.String()
now := time.Now()

if err := lock.Acquire(r.Context, 1); err != nil {
r.Log.Warn("Failed to acquire cache lock", "key", key)
w.Error()
return
}

if cache.Value == nil {
entry, cached := cache.Load(key)
if !cached {
r.Log.Info("Generating first response", "key", key)
callAndCache(r, w, args, f, key, now, cache)
lock.Release(1)
return
}

if cache.Created.After(now.Add(-d)) {
value := cache.Value
lock.Release(1)
if entry.(cacheEntry).Created.After(now.Add(-d)) {
r.Log.Info("Sending cached response", "key", key)
w.Write(value)
w.Write(entry.(cacheEntry).Value)
return
}

r.Log.Info("Generating new response", "key", key)
callAndCache(r, w, args, f, key, now, cache)
lock.Release(1)
}
}
18 changes: 10 additions & 8 deletions front/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/dimkr/tootik/front/static"
"github.com/dimkr/tootik/front/text"
"regexp"
"sync"
"time"
)

Expand Down Expand Up @@ -56,6 +57,7 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config, resolver ap.Resolve
Resolver: resolver,
DB: db,
}
var cache sync.Map

h.handlers[regexp.MustCompile(`^/$`)] = withUserMenu(h.home)

Expand All @@ -70,8 +72,8 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config, resolver ap.Resolve

h.handlers[regexp.MustCompile(`^/users/mentions$`)] = withUserMenu(h.mentions)

h.handlers[regexp.MustCompile(`^/local$`)] = withCache(withUserMenu(h.local), time.Minute*15, cfg)
h.handlers[regexp.MustCompile(`^/users/local$`)] = withCache(withUserMenu(h.local), time.Minute*15, cfg)
h.handlers[regexp.MustCompile(`^/local$`)] = withCache(withUserMenu(h.local), time.Minute*15, &cache, cfg)
h.handlers[regexp.MustCompile(`^/users/local$`)] = withCache(withUserMenu(h.local), time.Minute*15, &cache, cfg)

h.handlers[regexp.MustCompile(`^/outbox/(\S+)$`)] = withUserMenu(h.userOutbox)
h.handlers[regexp.MustCompile(`^/users/outbox/(\S+)$`)] = withUserMenu(h.userOutbox)
Expand Down Expand Up @@ -122,20 +124,20 @@ func NewHandler(domain string, closed bool, cfg *cfg.Config, resolver ap.Resolve
h.handlers[regexp.MustCompile(`^/communities$`)] = withUserMenu(h.communities)
h.handlers[regexp.MustCompile(`^/users/communities$`)] = withUserMenu(h.communities)

h.handlers[regexp.MustCompile(`^/hashtag/([a-zA-Z0-9]+)$`)] = withCache(withUserMenu(h.hashtag), time.Minute*5, cfg)
h.handlers[regexp.MustCompile(`^/users/hashtag/([a-zA-Z0-9]+)$`)] = withCache(withUserMenu(h.hashtag), time.Minute*5, cfg)
h.handlers[regexp.MustCompile(`^/hashtag/([a-zA-Z0-9]+)$`)] = withCache(withUserMenu(h.hashtag), time.Minute*5, &cache, cfg)
h.handlers[regexp.MustCompile(`^/users/hashtag/([a-zA-Z0-9]+)$`)] = withCache(withUserMenu(h.hashtag), time.Minute*5, &cache, cfg)

h.handlers[regexp.MustCompile(`^/hashtags$`)] = withCache(withUserMenu(h.hashtags), time.Minute*30, cfg)
h.handlers[regexp.MustCompile(`^/users/hashtags$`)] = withCache(withUserMenu(h.hashtags), time.Minute*30, cfg)
h.handlers[regexp.MustCompile(`^/hashtags$`)] = withCache(withUserMenu(h.hashtags), time.Minute*30, &cache, cfg)
h.handlers[regexp.MustCompile(`^/users/hashtags$`)] = withCache(withUserMenu(h.hashtags), time.Minute*30, &cache, cfg)

h.handlers[regexp.MustCompile(`^/search$`)] = withUserMenu(search)
h.handlers[regexp.MustCompile(`^/users/search$`)] = withUserMenu(search)

h.handlers[regexp.MustCompile(`^/fts$`)] = withUserMenu(h.fts)
h.handlers[regexp.MustCompile(`^/users/fts$`)] = withUserMenu(h.fts)

h.handlers[regexp.MustCompile(`^/status$`)] = withCache(withUserMenu(h.status), time.Minute*5, cfg)
h.handlers[regexp.MustCompile(`^/users/status$`)] = withCache(withUserMenu(h.status), time.Minute*5, cfg)
h.handlers[regexp.MustCompile(`^/status$`)] = withCache(withUserMenu(h.status), time.Minute*5, &cache, cfg)
h.handlers[regexp.MustCompile(`^/users/status$`)] = withCache(withUserMenu(h.status), time.Minute*5, &cache, cfg)

h.handlers[regexp.MustCompile(`^/oops`)] = withUserMenu(oops)
h.handlers[regexp.MustCompile(`^/users/oops`)] = withUserMenu(oops)
Expand Down

0 comments on commit 85232aa

Please sign in to comment.