Add a cache for gallery thumbnails (#496)

This commit is contained in:
bnkai
2020-05-11 10:20:08 +03:00
committed by GitHub
parent 8ba76783b0
commit bd45daacf3
36 changed files with 319 additions and 1200 deletions

72
pkg/api/cache_thumbs.go Normal file
View File

@@ -0,0 +1,72 @@
package api
import (
"github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/manager/paths"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"io/ioutil"
)
type thumbBuffer struct {
path string
dir string
data []byte
}
func newCacheThumb(dir string, path string, data []byte) *thumbBuffer {
t := thumbBuffer{dir: dir, path: path, data: data}
return &t
}
var writeChan chan *thumbBuffer
var touchChan chan *string
func startThumbCache() { // TODO add extra wait, close chan code if/when stash gets a stop mode
writeChan = make(chan *thumbBuffer, 20)
go thumbnailCacheWriter()
}
//serialize file writes to avoid race conditions
func thumbnailCacheWriter() {
for thumb := range writeChan {
exists, _ := utils.FileExists(thumb.path)
if !exists {
err := utils.WriteFile(thumb.path, thumb.data)
if err != nil {
logger.Errorf("Write error for thumbnail %s: %s ", thumb.path, err)
}
}
}
}
// get thumbnail from cache, otherwise create it and store to cache
func cacheGthumb(gallery *models.Gallery, index int, width int) []byte {
thumbPath := paths.GetGthumbPath(gallery.Checksum, index, width)
exists, _ := utils.FileExists(thumbPath)
if exists { // if thumbnail exists in cache return that
content, err := ioutil.ReadFile(thumbPath)
if err == nil {
return content
} else {
logger.Errorf("Read Error for file %s : %s", thumbPath, err)
}
}
data := gallery.GetThumbnail(index, width)
thumbDir := paths.GetGthumbDir(gallery.Checksum)
t := newCacheThumb(thumbDir, thumbPath, data)
writeChan <- t // write the file to cache
return data
}
// create all thumbs for a given gallery
func CreateGthumbs(gallery *models.Gallery) {
count := gallery.ImageCount()
for i := 0; i < count; i++ {
cacheGthumb(gallery, i, models.DefaultGthumbWidth)
}
}

View File

@@ -38,6 +38,13 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.Co
config.Set(config.Generated, input.GeneratedPath)
}
if input.CachePath != nil {
if err := utils.EnsureDir(*input.CachePath); err != nil {
return makeConfigGeneralResult(), err
}
config.Set(config.Cache, input.CachePath)
}
if input.MaxTranscodeSize != nil {
config.Set(config.MaxTranscodeSize, input.MaxTranscodeSize.String())
}

View File

@@ -23,7 +23,7 @@ func (r *mutationResolver) MetadataExport(ctx context.Context) (string, error) {
}
func (r *mutationResolver) MetadataGenerate(ctx context.Context, input models.GenerateMetadataInput) (string, error) {
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes)
manager.GetInstance().Generate(input.Sprites, input.Previews, input.Markers, input.Transcodes, input.Thumbnails)
return "todo", nil
}

View File

@@ -45,6 +45,7 @@ func makeConfigGeneralResult() *models.ConfigGeneralResult {
Stashes: config.GetStashPaths(),
DatabasePath: config.GetDatabasePath(),
GeneratedPath: config.GetGeneratedPath(),
CachePath: config.GetCachePath(),
MaxTranscodeSize: &maxTranscodeSize,
MaxStreamingTranscodeSize: &maxStreamingTranscodeSize,
ForceMkv: config.GetForceMKV(),

View File

@@ -23,11 +23,15 @@ func (rs galleryRoutes) Routes() chi.Router {
func (rs galleryRoutes) File(w http.ResponseWriter, r *http.Request) {
gallery := r.Context().Value(galleryKey).(*models.Gallery)
if gallery == nil {
http.Error(w, http.StatusText(404), 404)
return
}
fileIndex, _ := strconv.Atoi(chi.URLParam(r, "fileIndex"))
thumb := r.URL.Query().Get("thumb")
w.Header().Add("Cache-Control", "max-age=604800000") // 1 Week
if thumb == "true" {
_, _ = w.Write(gallery.GetThumbnail(fileIndex, 200))
_, _ = w.Write(cacheGthumb(gallery, fileIndex, models.DefaultGthumbWidth))
} else if thumb == "" {
_, _ = w.Write(gallery.GetImage(fileIndex))
} else {
@@ -36,7 +40,7 @@ func (rs galleryRoutes) File(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(400), 400)
return
}
_, _ = w.Write(gallery.GetThumbnail(fileIndex, int(width)))
_, _ = w.Write(cacheGthumb(gallery, fileIndex, int(width)))
}
}

View File

@@ -245,6 +245,7 @@ func Start() {
http.Redirect(w, r, "/", 301)
})
startThumbCache()
// Serve the web app
r.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) {
ext := path.Ext(r.URL.Path)