Cache smart playlist refreshes for 5 seconds
This commit is contained in:
@@ -173,9 +173,11 @@ func (r *playlistRepository) GetAll(options ...model.QueryOptions) (model.Playli
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *playlistRepository) refreshSmartPlaylist(pls *model.Playlist) bool {
|
func (r *playlistRepository) refreshSmartPlaylist(pls *model.Playlist) bool {
|
||||||
if !pls.IsSmartPlaylist() { //|| pls.EvaluatedAt.After(time.Now().Add(-5*time.Second)) {
|
// Only refresh if it is a smart playlist and was not refreshed in the last 5 seconds
|
||||||
|
if !pls.IsSmartPlaylist() || time.Since(pls.EvaluatedAt) < 5*time.Second {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug(r.ctx, "Refreshing smart playlist", "playlist", pls.Name, "id", pls.ID)
|
log.Debug(r.ctx, "Refreshing smart playlist", "playlist", pls.Name, "id", pls.ID)
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
@@ -186,7 +188,8 @@ func (r *playlistRepository) refreshSmartPlaylist(pls *model.Playlist) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
sp := SmartPlaylist(*pls.Rules)
|
// Re-populate playlist based on Smart Playlist criteria
|
||||||
|
sp := smartPlaylist(*pls.Rules)
|
||||||
sql := Select("row_number() over (order by "+sp.OrderBy()+") as id", "'"+pls.ID+"' as playlist_id", "media_file.id as media_file_id").
|
sql := Select("row_number() over (order by "+sp.OrderBy()+") as id", "'"+pls.ID+"' as playlist_id", "media_file.id as media_file_id").
|
||||||
From("media_file").LeftJoin("annotation on (" +
|
From("media_file").LeftJoin("annotation on (" +
|
||||||
"annotation.item_id = media_file.id" +
|
"annotation.item_id = media_file.id" +
|
||||||
@@ -200,14 +203,23 @@ func (r *playlistRepository) refreshSmartPlaylist(pls *model.Playlist) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update playlist stats
|
||||||
err = r.updateStats(pls.ID)
|
err = r.updateStats(pls.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(r.ctx, "Error updating smart playlist stats", "playlist", pls.Name, "id", pls.ID, err)
|
log.Error(r.ctx, "Error updating smart playlist stats", "playlist", pls.Name, "id", pls.ID, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update when the playlist was last refreshed (for cache purposes)
|
||||||
|
updSql := Update(r.tableName).Set("evaluated_at", time.Now()).Where(Eq{"id": pls.ID})
|
||||||
|
_, err = r.executeSQL(updSql)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(r.ctx, "Error updating smart playlist", "playlist", pls.Name, "id", pls.ID, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
log.Debug(r.ctx, "Refreshed playlist", "playlist", pls.Name, "id", pls.ID, "numTracks", c, "elapsed", time.Since(start))
|
log.Debug(r.ctx, "Refreshed playlist", "playlist", pls.Name, "id", pls.ID, "numTracks", c, "elapsed", time.Since(start))
|
||||||
pls.EvaluatedAt = time.Now()
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +263,8 @@ func (r *playlistRepository) updatePlaylist(playlistId string, mediaFileIds []st
|
|||||||
return r.updateStats(playlistId)
|
return r.updateStats(playlistId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateStats updates total playlist duration, size and count
|
||||||
func (r *playlistRepository) updateStats(playlistId string) error {
|
func (r *playlistRepository) updateStats(playlistId string) error {
|
||||||
// Get total playlist duration, size and count
|
|
||||||
statsSql := Select("sum(duration) as duration", "sum(size) as size", "count(*) as count").
|
statsSql := Select("sum(duration) as duration", "sum(size) as size", "count(*) as count").
|
||||||
From("media_file").
|
From("media_file").
|
||||||
Join("playlist_tracks f on f.media_file_id = media_file.id").
|
Join("playlist_tracks f on f.media_file_id = media_file.id").
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import (
|
|||||||
//"order": "lastPlayed desc",
|
//"order": "lastPlayed desc",
|
||||||
//"limit": 10
|
//"limit": 10
|
||||||
//}
|
//}
|
||||||
type SmartPlaylist model.SmartPlaylist
|
type smartPlaylist model.SmartPlaylist
|
||||||
|
|
||||||
func (sp SmartPlaylist) AddCriteria(sql SelectBuilder) SelectBuilder {
|
func (sp smartPlaylist) AddCriteria(sql SelectBuilder) SelectBuilder {
|
||||||
sql = sql.Where(RuleGroup(sp.RuleGroup)).Limit(uint64(sp.Limit))
|
sql = sql.Where(RuleGroup(sp.RuleGroup)).Limit(uint64(sp.Limit))
|
||||||
if order := sp.OrderBy(); order != "" {
|
if order := sp.OrderBy(); order != "" {
|
||||||
sql = sql.OrderBy(order)
|
sql = sql.OrderBy(order)
|
||||||
@@ -30,7 +30,7 @@ func (sp SmartPlaylist) AddCriteria(sql SelectBuilder) SelectBuilder {
|
|||||||
return sql
|
return sql
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp SmartPlaylist) OrderBy() string {
|
func (sp smartPlaylist) OrderBy() string {
|
||||||
order := strings.ToLower(sp.Order)
|
order := strings.ToLower(sp.Order)
|
||||||
for f, fieldDef := range fieldMap {
|
for f, fieldDef := range fieldMap {
|
||||||
if strings.HasPrefix(order, f) {
|
if strings.HasPrefix(order, f) {
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("SmartPlaylist", func() {
|
var _ = Describe("smartPlaylist", func() {
|
||||||
var pls SmartPlaylist
|
var pls smartPlaylist
|
||||||
Describe("AddCriteria", func() {
|
Describe("AddCriteria", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
sp := model.SmartPlaylist{
|
sp := model.SmartPlaylist{
|
||||||
@@ -32,7 +32,7 @@ var _ = Describe("SmartPlaylist", func() {
|
|||||||
Order: "artist asc",
|
Order: "artist asc",
|
||||||
Limit: 100,
|
Limit: 100,
|
||||||
}
|
}
|
||||||
pls = SmartPlaylist(sp)
|
pls = smartPlaylist(sp)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns a proper SQL query", func() {
|
It("returns a proper SQL query", func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user