Skip to content

Commit

Permalink
Merge pull request #668 from mw9/feature/pcast_precaching
Browse files Browse the repository at this point in the history
Podcasts: Pre-caching image and more-info data can bring the server to a crawl
  • Loading branch information
mherger committed Sep 28, 2021
2 parents 8b026f1 + f96ff71 commit ab2f9d3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 17 deletions.
6 changes: 6 additions & 0 deletions Slim/Plugin/Podcast/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use Slim::Utils::Cache;
use Slim::Utils::DateTime;
use Slim::Utils::Strings qw(cstring);

use Slim::Plugin::Podcast::Plugin;

my $cache = Slim::Utils::Cache->new;

my $fetching;
Expand All @@ -24,6 +26,10 @@ sub parse {
# don't use eval() - caller is Slim::Formats::XML is doing so already
my $feed = Slim::Formats::XML::parseXMLIntoFeed( $http->contentRef, $http->headers()->content_type );

# refresh precached image & more info data - keeps them up to date
my $feedUrl = $http->params->{params}->{url};
Slim::Plugin::Podcast::Plugin::precacheFeedData($feedUrl, $feed);

foreach my $item ( @{$feed->{items}} ) {
if ($item->{type} && $item->{type} eq 'link') {
$item->{parser} = $class;
Expand Down
63 changes: 46 additions & 17 deletions Slim/Plugin/Podcast/Plugin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ sub handleFeed {

# then existing feeds
my @feeds = @{$prefs->get('feeds')};
my @need;
my $fetch;

foreach ( @feeds ) {
my $url = $_->{value};
Expand All @@ -183,23 +185,39 @@ sub handleFeed {
playlist => $url,
};

# if pre-cached feed data is missing, initiate retrieval
unless ($image && $cache->get('podcast_moreInfo_' . $url)) {
Slim::Formats::XML->getFeedAsync(
sub {
_precacheShowDetails($url, $_[0]);
},
sub {
$log->warn("can't get $url RSS feed information: ", $_[0]);
},
{
parser => 'Slim::Plugin::Podcast::Parser',
url => $_->{value},
expires => 86400
}
);
# cache a placeholder image & moreInfo to guard against retrieving
# the feed multiple times while browsing within the podcast menu
# they will be replaced with real data after feed is successfully retrieved
$cache->set('podcast-rss-' . $url, __PACKAGE__->_pluginDataFor('icon'), '1days');
$cache->set('podcast_moreInfo_' . $url, {}, '1days');
push (@need, $url);
}
}

# get missing cache images & moreinfo if any
# each feed is retrieved and parsed sequentially, to limit loading on modestly powered servers
$fetch = sub {
my $url = pop @need;
Slim::Formats::XML->getFeedAsync(
sub {
# called by feed parser, so not needed here
# precacheFeedData($url, $_[0]);
$fetch->();
},
sub {
$log->warn("can't get $url RSS feed information: ", $_[0]);
$fetch->();
},
{
parser => 'Slim::Plugin::Podcast::Parser',
url => $url,
}
) if $url;
};
$fetch->();

$cb->({
items => $items,
actions => {
Expand Down Expand Up @@ -283,7 +301,7 @@ sub searchHandler {
$feed->{parser} ||= 'Slim::Plugin::Podcast::Parser';
push @$items, $feed;

_precacheShowDetails($feed->{url}, $feed);
precacheFeedData($feed->{url}, $feed);
}

push @$items, { name => cstring($client, 'EMPTY') } if !scalar @$items;
Expand Down Expand Up @@ -312,11 +330,20 @@ sub searchHandler {
)->get($url, @$headers);
}

sub _precacheShowDetails {
sub precacheFeedData {
my ($url, $feed) = @_;
# sanity check
unless (defined($url) && (ref($feed) eq 'HASH')) {
$log->error("Unexpected feed data for URL '$url'");
return;
}

# keep image for around 90 days, randomizing cache period to
# avoid flood of simultaneous requests in future
my $cacheTime = sprintf("%.3f days", 80 + rand(20));

if (my $image = $feed->{image}) {
$cache->set('podcast-rss-' . $url, $image, '90days');
$cache->set('podcast-rss-' . $url, $image, $cacheTime);
}
else {
# always cache image to avoid sending a flood of requests
Expand All @@ -332,7 +359,9 @@ sub _precacheShowDetails {
}
}

$cache->set('podcast_moreInfo_' . $url, \%moreInfo);
# keep moreInfo for around 90 days, same as image
# it will not change often
$cache->set('podcast_moreInfo_' . $url, \%moreInfo, $cacheTime);
}

sub registerProvider {
Expand Down

0 comments on commit ab2f9d3

Please sign in to comment.