0.2.79 - Slow api fixes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"github.com/ponzischeme89/memby/server/internal/emby"
|
||||
"github.com/ponzischeme89/memby/server/internal/recommend"
|
||||
"github.com/ponzischeme89/memby/server/internal/store"
|
||||
"github.com/ponzischeme89/memby/server/internal/timing"
|
||||
)
|
||||
|
||||
// fieldsRelated is the detail set. It once added Studios on its own account — the
|
||||
@@ -50,7 +52,24 @@ func (s *Server) handleRelated(w http.ResponseWriter, r *http.Request, sess stor
|
||||
return
|
||||
}
|
||||
|
||||
reasons, related, err := s.recommender.RelatedTo(ctx, credentials(sess), item, relatedRowSize)
|
||||
// Coalesced, because this route is asked for twice for the same title as a matter of
|
||||
// course: the launcher warms it while a card is focused and the detail page asks for
|
||||
// it again the moment somebody presses. Those two requests used to build the answer
|
||||
// twice, and building it is the same Emby fan-out the home rows pay for.
|
||||
body, err := s.buildCached(ctx, key, relatedTTL(s.cfg.ItemTTL),
|
||||
func(ctx context.Context) (json.RawMessage, error) {
|
||||
reasons, related, err := s.recommender.RelatedTo(
|
||||
timing.WithLabel(ctx, "emby.related"), credentials(sess), item, relatedRowSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := nonNilRaws(recommend.Raws(related))
|
||||
s.decorateItemRatings(ctx, items)
|
||||
return json.Marshal(relatedResponse{
|
||||
Reasons: nonNilStrings(reasons),
|
||||
Items: items,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
// RelatedTo degrades rather than failing, so the only error it returns is the
|
||||
// viewer having navigated on. That is the television saving work, not a fault.
|
||||
@@ -61,29 +80,20 @@ func (s *Server) handleRelated(w http.ResponseWriter, r *http.Request, sess stor
|
||||
s.writeUpstreamError(ctx, w, err, "could not load related titles")
|
||||
return
|
||||
}
|
||||
writeCached(w, false, body)
|
||||
}
|
||||
|
||||
items := nonNilRaws(recommend.Raws(related))
|
||||
s.decorateItemRatings(ctx, items)
|
||||
body, err := json.Marshal(relatedResponse{
|
||||
Reasons: nonNilStrings(reasons),
|
||||
Items: items,
|
||||
})
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "could not encode related titles")
|
||||
return
|
||||
// relatedTTL keeps an empty carousel briefly rather than for the item lifetime: it
|
||||
// usually means something upstream was unwell, and the ten-minute answer would otherwise
|
||||
// outlive the minute of trouble that produced it.
|
||||
func relatedTTL(itemTTL time.Duration) func(json.RawMessage) time.Duration {
|
||||
return func(body json.RawMessage) time.Duration {
|
||||
var decoded relatedResponse
|
||||
if json.Unmarshal(body, &decoded) == nil && len(decoded.Items) == 0 {
|
||||
return relatedEmptyTTL
|
||||
}
|
||||
return itemTTL
|
||||
}
|
||||
// An empty carousel is cached briefly rather than for the item lifetime: it usually
|
||||
// means something upstream was unwell, and the ten-minute answer would otherwise
|
||||
// outlive the minute of trouble that produced it.
|
||||
ttl := s.cfg.ItemTTL
|
||||
if len(items) == 0 {
|
||||
ttl = relatedEmptyTTL
|
||||
}
|
||||
if err := s.cache.Set(ctx, key, body, ttl); err != nil {
|
||||
s.loggerFor(ctx).Warn("related cache write failed", "error", err)
|
||||
}
|
||||
w.Header().Set("X-Memby-Cache", "miss")
|
||||
writeRaw(w, http.StatusOK, body)
|
||||
}
|
||||
|
||||
// relatedRowSize is a carousel's worth. The strip scrolls, but a viewer who reaches the
|
||||
|
||||
Reference in New Issue
Block a user