Skip to content

Commit

Permalink
feat: disable metadata cache completely
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyXiang committed Mar 10, 2022
1 parent 2fb175c commit 69f5367
Show file tree
Hide file tree
Showing 8 changed files with 12 additions and 190 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,13 @@ env CGO_ENABLED=0 go install -trimpath -ldflags="-s -w" github.com/RoyXiang/plex

1. Configure environment variables in your preferred way
- `PLEX_BASEURL` (Required, e.g. `http://127.0.0.1:32400`)
- `PLEX_TOKEN` (Optional, if you need it, see [here](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))
* It is used to receive notifications from Plex Media Server
* Notifications are used to flush the cache of metadata
- `REDIS_URL` (Optional, e.g. `redis://127.0.0.1:6379`)
* If you need a cache layer, set a value for it
* `PLEX_TOKEN` is required
- `PLAXT_URL` (Optional, e.g. `https://plaxt.astandke.com/api?id=generate-your-own-silly`)
* `PLEX_TOKEN` is required
* Set it if you run an instance of [Plaxt](https://github.com/XanderStrike/goplaxt)
* Or, you can set it to [the official one](https://plaxt.astandke.com/)
- `PLEX_TOKEN` (Optional, if you need it, see [here](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))
- `REDIRECT_WEB_APP` (Optional, default: `true`)
- `DISABLE_TRANSCODE` (Optional, default: `true`)
- `NO_REQUEST_LOGS` (Optional, default: `false`)
Expand Down
14 changes: 6 additions & 8 deletions handler/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ const (
headerRealIP = "X-Real-IP"
headerVary = "Vary"

cachePrefixDynamic = "dynamic"
cachePrefixMetadata = "metadata"
cachePrefixStatic = "static"
cachePrefixPlex = "plex"

cacheTtlDynamic = time.Second * 5
cacheTtlMetadata = time.Hour * 24
cacheTtlStatic = time.Hour
cachePrefixDynamic = "dynamic"
cachePrefixStatic = "static"
cachePrefixPlex = "plex"

cacheTtlDynamic = time.Second * 5
cacheTtlStatic = time.Hour

contentTypeAny = "*/*"
contentTypeXml = "xml"
Expand Down
11 changes: 1 addition & 10 deletions handler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"log"
"net/http"
"os"
"sync"

"github.com/go-chi/chi/v5/middleware"
"github.com/go-redis/redis/v8"
Expand All @@ -16,8 +15,6 @@ var (
redisClient *redis.Client

emptyStruct = struct{}{}

mu sync.RWMutex
)

func init() {
Expand All @@ -34,7 +31,7 @@ func init() {
}

redisUrl := os.Getenv("REDIS_URL")
if redisUrl != "" && plexClient.IsTokenSet() {
if redisUrl != "" {
options, err := redis.ParseURL(redisUrl)
if err == nil {
redisClient = redis.NewClient(options)
Expand Down Expand Up @@ -62,12 +59,6 @@ func NewRouter() http.Handler {
staticRouter.Path("/library/metadata/{key}/thumb/{id}").Handler(plexClient)
staticRouter.Path("/photo/:/transcode").Handler(plexClient)

metadataRouter := r.Methods(http.MethodGet).PathPrefix("/library").Subrouter()
metadataRouter.Use(metadataMiddleware)
metadataRouter.PathPrefix("/collections/").Handler(plexClient)
metadataRouter.PathPrefix("/metadata/").Handler(plexClient)
metadataRouter.PathPrefix("/sections/").Handler(plexClient)

dynamicRouter := r.Methods(http.MethodGet).Subrouter()
dynamicRouter.Use(dynamicMiddleware)
dynamicRouter.PathPrefix("/").Handler(plexClient)
Expand Down
17 changes: 1 addition & 16 deletions handler/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,6 @@ func staticMiddleware(next http.Handler) http.Handler {
})
}

func metadataMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), cacheInfoCtxKey, &cacheInfo{
Prefix: cachePrefixMetadata,
Ttl: cacheTtlMetadata,
})
r = r.WithContext(ctx)
cacheMiddleware(next).ServeHTTP(w, r)
})
}

func dynamicMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), cacheInfoCtxKey, &cacheInfo{
Expand All @@ -141,10 +130,6 @@ func cacheMiddleware(next http.Handler) http.Handler {
var cacheKey string
ctx := context.Background()
info := r.Context().Value(cacheInfoCtxKey).(*cacheInfo)
if info.Prefix == cachePrefixMetadata {
mu.RLock()
defer mu.RUnlock()
}

defer func() {
if cacheKey == "" {
Expand Down Expand Up @@ -190,7 +175,7 @@ func cacheMiddleware(next http.Handler) http.Handler {
switch info.Prefix {
case cachePrefixStatic:
break
case cachePrefixDynamic, cachePrefixMetadata:
case cachePrefixDynamic:
user := r.Context().Value(userCtxKey)
if user != nil {
params.Set(headerUserId, strconv.Itoa(user.(*plexUser).Id))
Expand Down
54 changes: 2 additions & 52 deletions handler/plex.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package handler

import (
"bufio"
"bytes"
"context"
"encoding/json"
Expand Down Expand Up @@ -140,11 +139,6 @@ func (c *PlexClient) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// If it is an authorized request
if user := r.Context().Value(userCtxKey); user != nil {
switch path {
case "/:/scrobble", "/:/unscrobble":
ratingKey := r.URL.Query().Get("key")
if ratingKey != "" {
go clearCachedMetadata(ratingKey, user.(*plexUser).Id)
}
case "/:/timeline":
go c.syncTimelineWithPlaxt(r, user.(*plexUser))
case "/video/:/transcode/universal/decision":
Expand Down Expand Up @@ -360,7 +354,6 @@ func (c *PlexClient) syncTimelineWithPlaxt(r *http.Request, user *plexUser) {
session.status = sessionPaused
case webhookEventStop, webhookEventScrobble:
session.status = sessionStopped
go clearCachedMetadata(ratingKey, user.Id)
}
session.lastEvent = event
session.progress = progress
Expand Down Expand Up @@ -519,55 +512,12 @@ func (c *PlexClient) getMetadata(ratingKey string) *plex.MediaMetadata {
c.mu.RLock()
defer c.mu.RUnlock()

user := c.GetUser(c.client.Token)
if user == nil {
return nil
}

path := fmt.Sprintf("/library/metadata/%s", ratingKey)
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s%s", c.client.URL, path), nil)
if err != nil {
return nil
}
req.Header.Set(headerToken, c.client.Token)
req.Header.Set(headerAccept, "application/json")

var resp *http.Response
cacheKey := fmt.Sprintf("%s:%s?%s=%s&%s=%d", cachePrefixMetadata, path, headerAccept, "json", headerUserId, user.Id)
isFromCache := false
if redisClient != nil {
b, err := redisClient.Get(context.Background(), cacheKey).Bytes()
if err == nil {
reader := bufio.NewReader(bytes.NewReader(b))
resp, _ = http.ReadResponse(reader, req)
isFromCache = true
}
}
if resp == nil {
resp, err = c.client.HTTPClient.Do(req)
if err != nil {
common.GetLogger().Printf("Failed to parse metadata of item %s: %s", ratingKey, err.Error())
return nil
}
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)

if resp.StatusCode != http.StatusOK {
common.GetLogger().Printf("Failed to get metadata of item %s (status: %d)", ratingKey, resp.StatusCode)
return nil
} else if !isFromCache {
writeToCache(cacheKey, resp, cacheTtlMetadata)
}

var result plex.MediaMetadata
err = json.NewDecoder(resp.Body).Decode(&result)
metadata, err := c.client.GetMetadata(ratingKey)
if err != nil {
common.GetLogger().Printf("Failed to parse metadata of item %s: %s", ratingKey, err.Error())
return nil
}
return &result
return &metadata
}

func (c *PlexClient) disableTranscoding(r *http.Request) *http.Request {
Expand Down
25 changes: 0 additions & 25 deletions handler/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package handler

import (
"context"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
Expand Down Expand Up @@ -124,27 +123,3 @@ func writeToCache(key string, resp *http.Response, ttl time.Duration) {
}
redisClient.Set(context.Background(), key, b, ttl)
}

func clearCachedMetadata(ratingKey string, userId int) {
if redisClient == nil {
return
}

mu.Lock()
defer mu.Unlock()

pattern := cachePrefixMetadata + ":"
if ratingKey != "" {
pattern += fmt.Sprintf("/library/metadata/%s", ratingKey)
}
if userId > 0 {
pattern += fmt.Sprintf("*%s=%d", headerUserId, userId)
}
pattern += "*"

ctx := context.Background()
keys := redisClient.Keys(ctx, pattern).Val()
if len(keys) > 0 {
redisClient.Del(ctx, keys...).Val()
}
}
74 changes: 0 additions & 74 deletions handler/websocket.go

This file was deleted.

2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {

c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
handler.ListenToWebsocket(c)
<-c

ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()
Expand Down

0 comments on commit 69f5367

Please sign in to comment.