Remove Library::RebuildCache

This commit is contained in:
Mike Colagrosso 2024-07-14 12:39:04 -06:00 committed by Alex Cabal
parent f4a19a2d12
commit ec26e7f9af
2 changed files with 2 additions and 144 deletions

View file

@ -1,7 +1,6 @@
<? <?
use Safe\DateTimeImmutable; use Safe\DateTimeImmutable;
use function Safe\apcu_fetch;
use function Safe\exec; use function Safe\exec;
use function Safe\filemtime; use function Safe\filemtime;
use function Safe\filesize; use function Safe\filesize;
@ -9,8 +8,6 @@ use function Safe\glob;
use function Safe\ksort; use function Safe\ksort;
use function Safe\preg_replace; use function Safe\preg_replace;
use function Safe\preg_split; use function Safe\preg_split;
use function Safe\shell_exec;
use function Safe\sleep;
use function Safe\usort; use function Safe\usort;
class Library{ class Library{
@ -598,141 +595,6 @@ class Library{
return $retval; return $retval;
} }
/**
* @throws Exceptions\AppException
*/
public static function RebuildCache(): void{
// We check a lockfile because this can be a long-running command.
// We don't want to queue up a bunch of these in case someone is refreshing the index constantly.
$lockVar = 'library-cache-rebuilding';
try{
$val = apcu_fetch($lockVar);
return;
}
catch(Safe\Exceptions\ApcuException){
apcu_store($lockVar, true);
}
$collator = Collator::create('en_US'); // Used for sorting letters with diacritics like in author names
if($collator === null){
throw new Exceptions\AppException('Couldn\'t create collator object when rebuilding cache.');
}
$ebooks = [];
$ebooksByCollection = [];
$ebooksByTag = [];
$collectionsByName = [];
$authors = [];
$tagsByName = [];
foreach(explode("\n", trim(shell_exec('find ' . EBOOKS_DIST_PATH . ' -name "content.opf"'))) as $filename){
try{
$ebookWwwFilesystemPath = preg_replace('|/content\.opf|ius', '', $filename);
$ebook = Ebook::FromFilesystem($ebookWwwFilesystemPath);
$ebooks[$ebookWwwFilesystemPath] = $ebook;
// Create the collections cache
foreach($ebook->CollectionMemberships as $collectionMembership){
$collection = $collectionMembership->Collection;
$sequenceNumber = $collectionMembership->SequenceNumber;
$urlSafeCollection = Formatter::MakeUrlSafe($collection->Name);
if(!array_key_exists($urlSafeCollection, $ebooksByCollection)){
$ebooksByCollection[$urlSafeCollection] = [];
$collectionsByName[$urlSafeCollection] = $collection;
}
// Some items may have the same position in a collection,
// like _Some Do Not..._ and _No More Parades_ are both #57 in the Modern Library's 100 best novels.
// To accomodate that, we create an anonymous object that holds the sequence number as a separate value,
// then later we sort by that instead of by array index.
$sortItem = new stdClass();
$sortItem->Ebook = $ebook;
if($sequenceNumber !== null){
$sortItem->Ordinal = $sequenceNumber;
}
else{
$sortItem->Ordinal = 1;
}
$ebooksByCollection[$urlSafeCollection][] = $sortItem;
}
// Create the tags cache
foreach($ebook->Tags as $tag){
$tagsByName[$tag->UrlName] = $tag;
if(!array_key_exists($tag->UrlName, $ebooksByTag)){
$ebooksByTag[$tag->UrlName] = [];
}
$ebooksByTag[$tag->UrlName][] = $ebook;
}
// Create the authors cache
$authorPath = EBOOKS_DIST_PATH . rtrim(preg_replace('|^/ebooks/|ius', '', $ebook->AuthorsUrl), '/');
if(!array_key_exists($authorPath, $authors)){
$authors[$authorPath] = [];
}
$authors[$authorPath][] = $ebook;
}
catch(\Exception){
// An error in a book isn't fatal; just carry on.
}
}
apcu_delete('ebooks');
apcu_store('ebooks', $ebooks);
// Before we sort the list of ebooks and lose the array keys, store them by individual ebook
apcu_delete(new APCUIterator('/^ebook-/'));
foreach($ebooks as $ebookWwwFilesystemPath => $ebook){
apcu_store('ebook-' . $ebookWwwFilesystemPath, $ebook);
}
// Now store various collections
apcu_delete(new APCUIterator('/^collection-/'));
foreach($ebooksByCollection as $collection => $sortItems){
// Sort the array by the ebook's ordinal in the collection. We use this custom sort function
// because an ebook may share the same place in a collection with another ebook; see above.
usort($sortItems, function($a, $b){
if($a->Ordinal == $b->Ordinal){
return 0;
}
return ($a->Ordinal < $b->Ordinal) ? -1 : 1;
});
// Now pull the actual ebooks out of the anonymous objects we just sorted
$ebooks = [];
foreach($sortItems as $sortItem){
$ebooks[] = $sortItem->Ebook;
}
apcu_store('collection-' . $collection, $ebooks);
}
apcu_delete('collections');
usort($collectionsByName, function($a, $b) use($collator){ return $collator->compare($a->GetSortedName(), $b->GetSortedName()); });
apcu_store('collections', $collectionsByName);
apcu_delete(new APCUIterator('/^tag-/'));
foreach($ebooksByTag as $tagName => $ebooks){
apcu_store('tag-' . $tagName, $ebooks);
}
ksort($tagsByName);
apcu_delete('tags');
apcu_store('tags', $tagsByName);
apcu_delete(new APCUIterator('/^author-/'));
foreach($authors as $author => $ebooks){
apcu_store('author-' . $author, $ebooks);
}
apcu_delete($lockVar);
apcu_store('is-cache-fresh', true);
}
/** /**
* @return array<Artist> * @return array<Artist>
*/ */

View file

@ -4,10 +4,10 @@ usage(){
echo -n echo -n
fmt <<EOF fmt <<EOF
DESCRIPTION DESCRIPTION
Rebuild one of three caches stored in APCu for the standardebooks.org FPM pool. Rebuild one of the caches stored in APCu for the standardebooks.org FPM pool.
USAGE USAGE
rebuild-cache {library,bulk-downloads,feeds} rebuild-cache {bulk-downloads,feeds}
EOF EOF
exit 1 exit 1
} }
@ -27,10 +27,6 @@ fi
type="$1" type="$1"
if [ "${type}" = "library" ]; then
echo "<?php require_once('Core.php'); Library::RebuildCache(); ?>" > /tmp/rebuild-cache.php
fi
if [ "${type}" = "bulk-downloads" ]; then if [ "${type}" = "bulk-downloads" ]; then
echo "<?php require_once('Core.php'); Library::RebuildBulkDownloadsCache(); ?>" > /tmp/rebuild-cache.php echo "<?php require_once('Core.php'); Library::RebuildBulkDownloadsCache(); ?>" > /tmp/rebuild-cache.php
fi fi