[Slim-Checkins] r10976 - in /branches/6.5/server/Slim: Music/Info.pm Web/Pages/Playlist.pm

adrian at svn.slimdevices.com adrian at svn.slimdevices.com
Fri Dec 15 14:23:43 PST 2006


Author: adrian
Date: Fri Dec 15 14:23:42 2006
New Revision: 10976

URL: http://svn.slimdevices.com?rev=10976&view=rev
Log:
Bug: 4600
Description: additional caching to reduce Default skin playlist cpu
hit, merge from trunk -r 10955:10956 & 10969:10970

Modified:
    branches/6.5/server/Slim/Music/Info.pm
    branches/6.5/server/Slim/Web/Pages/Playlist.pm

Modified: branches/6.5/server/Slim/Music/Info.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Music/Info.pm?rev=10976&r1=10975&r2=10976&view=diff
==============================================================================
--- branches/6.5/server/Slim/Music/Info.pm (original)
+++ branches/6.5/server/Slim/Music/Info.pm Fri Dec 15 14:23:42 2006
@@ -468,13 +468,26 @@
 
 		$format = 'TITLE';
 
-	} elsif (defined($client)) {
+	} else {
+
+		$format = standardTitleFormat($client);
+
+	}
+
+	return displayText($client, $track, $format);
+}
+
+# format string for standard title, potentially client specific
+sub standardTitleFormat {
+	my $client = shift;
+
+	if (defined($client)) {
 
 		# in array syntax this would be
 		# $titleFormat[$clientTitleFormat[$clientTitleFormatCurr]] get
 		# the title format
 
-		$format = Slim::Utils::Prefs::getInd("titleFormat",
+		return Slim::Utils::Prefs::getInd("titleFormat",
 			# at the array index of the client titleformat array
 			$client->prefGet("titleFormat",
 				# which is currently selected
@@ -485,10 +498,8 @@
 	} else {
 
 		# in array syntax this would be $titleFormat[$titleFormatWeb]
-		$format = Slim::Utils::Prefs::getInd("titleFormat", Slim::Utils::Prefs::get("titleFormatWeb"));
-	}
-
-	return displayText($client, $track, $format);
+		return Slim::Utils::Prefs::getInd("titleFormat", Slim::Utils::Prefs::get("titleFormatWeb"));
+	}
 }
 
 # get display text for object by format, caches all formats for this url for this client

Modified: branches/6.5/server/Slim/Web/Pages/Playlist.pm
URL: http://svn.slimdevices.com/branches/6.5/server/Slim/Web/Pages/Playlist.pm?rev=10976&r1=10975&r2=10976&view=diff
==============================================================================
--- branches/6.5/server/Slim/Web/Pages/Playlist.pm (original)
+++ branches/6.5/server/Slim/Web/Pages/Playlist.pm Fri Dec 15 14:23:42 2006
@@ -17,6 +17,8 @@
 use Slim::Utils::Strings qw(string);
 use Slim::Web::Pages;
 
+use constant CACHE_TIME => 300;
+
 sub init {
 	
 	Slim::Web::HTTP::addPageFunction( qr/^playlist\.(?:htm|xml)/, \&playlist, 'fork' );
@@ -71,28 +73,41 @@
 		msg("start: $params->{'start'}\n");
 	}
 
-	# Only build if we need to.
-	# Check to see if we're newer, and the same skin.
+	# Only build if we need to - try to return cached html or build page from cached info
+	my $cachedRender = $client->currentPlaylistRender();
+
 	if ($songcount > 0 && 
 		defined $params->{'skinOverride'} &&
 		defined $params->{'start'} &&
-		$client->currentPlaylistRender() && 
-		ref($client->currentPlaylistRender()) eq 'ARRAY' && 
-		$client->currentPlaylistChangeTime() && 
-		$client->currentPlaylistRender()->[1] eq $params->{'skinOverride'} &&
-		$client->currentPlaylistRender()->[2] eq $params->{'start'} &&
-		$client->currentPlaylistChangeTime() < $client->currentPlaylistRender()->[0]) {
-
-		if (Slim::Utils::Prefs::get("playlistdir")) {
-			$params->{'cansave'} = 1;
-		}
-
-		$::d_playlist && msg("Skipping playlist build - not modified.\n");
-
-		$params->{'playlist_items'}   = $client->currentPlaylistRender()->[3];
-		$params->{'pageinfo'}         = $client->currentPlaylistRender()->[4];
-
-		return Slim::Web::HTTP::filltemplatefile("playlist.html", $params);
+		$cachedRender && ref($cachedRender) eq 'ARRAY' &&
+		$client->currentPlaylistChangeTime() &&
+		$client->currentPlaylistChangeTime() < $client->currentPlaylistRender()->[0] &&
+		$cachedRender->[1] eq $params->{'skinOverride'} &&
+		$cachedRender->[2] eq $params->{'start'} ) {
+
+		if ($cachedRender->[5]) {
+
+			$::d_playlist && msg("Returning cached playlist html - not modified.\n");
+
+			# reset cache timer to forget cached html
+			Slim::Utils::Timers::killTimers($client, \&flushCachedHTML);
+			Slim::Utils::Timers::setTimer($client, time() + CACHE_TIME, \&flushCachedHTML);
+
+			return $client->currentPlaylistRender()->[5];
+
+		} else {
+
+			$::d_playlist && msg("Rebuilding playlist from cached params.\n");
+
+			if (Slim::Utils::Prefs::get("playlistdir")) {
+				$params->{'cansave'} = 1;
+			}
+
+			$params->{'playlist_items'}   = $client->currentPlaylistRender()->[3];
+			$params->{'pageinfo'}         = $client->currentPlaylistRender()->[4];
+
+			return Slim::Web::HTTP::filltemplatefile("playlist.html", $params);
+		}
 	}
 
 	if (!$songcount) {
@@ -121,16 +136,17 @@
 
 	my $currsongind   = Slim::Player::Source::playingSongIndex($client);
 
-	my $itemCount    = 0;
-	my $itemsPerPass = Slim::Utils::Prefs::get('itemsPerPass');
 	my $itemsPerPage = Slim::Utils::Prefs::get('itemsPerPage');
 	my $composerIn   = Slim::Utils::Prefs::get('composerInArtists');
 
+	my $titleFormat  = Slim::Music::Info::standardTitleFormat();
+
 	$params->{'playlist_items'} = [];
 	$params->{'myClientState'}  = $client;
 
 	# This is a hot loop.
 	# But it's better done all at once than through the scheduler.
+
 	for my $itemnum ($start..$end) {
 
 		# These should all be objects - but be safe.
@@ -140,8 +156,8 @@
 		if (!blessed($objOrUrl) || !$objOrUrl->can('id')) {
 
 			$track = Slim::Schema->rs('Track')->objectForUrl($objOrUrl) || do {
+
 				msg("Couldn't retrieve objectForUrl: [$objOrUrl] - skipping!\n");
-				$itemCount++;
 				next;
 			};
 		}
@@ -166,41 +182,57 @@
 		} else {
 
 			$form{'currentsong'} = undef;
-			$form{'title'}    = Slim::Music::Info::standardTitle(undef, $track);
+			$form{'title'}    = Slim::Music::TitleFormatter::infoFormat($track, $titleFormat);
 		}
 
 		$form{'nextsongind'} = $currsongind + (($itemnum > $currsongind) ? 1 : 0);
 
 		push @{$params->{'playlist_items'}}, \%form;
 
-		$itemCount++;
-
-		# don't neglect the streams too long, every itemsPerPass idle them
-		if (!($itemCount % $itemsPerPass)) {
-
-			main::idleStreams();
-		}
-	}
-
-	$::d_playlist && msg("End playlist build. $itemCount items\n");
-
-	# Give some player time after the loop, but before rendering.
-	main::idleStreams();
+		# don't neglect the streams too long
+		main::idleStreams();
+	}
+
+	$::d_playlist && msg("End playlist build.\n");
+
+	my $page = Slim::Web::HTTP::filltemplatefile("playlist.html", $params);
 
 	if ($client) {
 
-		# Stick the rendered data into the client object as a stopgap
-		# solution to the cpu spike issue.
+		# Cache to reduce cpu spike seen when playlist refreshes
+		# For the moment cache html for Default, other skins only cache params
+		# Later consider caching as html unless an ajaxRequest
+		# my $cacheHtml = !$params->{'ajaxRequest'};
+		my $cacheHtml = (($params->{'skinOverride'} || Slim::Utils::Prefs::get('skin')) eq 'Default');
+
+		my $time = time();
+
 		$client->currentPlaylistRender([
-			time(),
+			$time,
 			($params->{'skinOverride'} || ''),
 			($params->{'start'}),
 			$params->{'playlist_items'},
 			$params->{'pageinfo'},
+			$cacheHtml ? $page : undef,
 		]);
-	}
-
-	return Slim::Web::HTTP::filltemplatefile("playlist.html", $params),
+
+		$::d_playlist && msg(sprintf("Caching playlist as %s.\n", $cacheHtml ? 'html' : 'params'));
+
+		Slim::Utils::Timers::killTimers($client, \&flushCachedHTML);
+
+		if ($cacheHtml) {
+			Slim::Utils::Timers::setTimer($client, $time + CACHE_TIME, \&flushCachedHTML);
+		}
+	}
+
+	return $page;
+}
+
+sub flushCachedHTML {
+	my $client = shift;
+
+	$::d_playlist && msg("Flushing playlist html cache for client.\n");
+	$client->currentPlaylistRender(undef);
 }
 
 1;



More information about the checkins mailing list