#!/usr/bin/env perl # This script populates the HTML-rendered man page cache in the database. # # Usage: cache-html.pl # # --verbose # Be more verbose. # # --delay=$SEC # Seconds (fraction supported) to wait between batches. # # --batch=$NUM # Number of pages to render per batch. # # --maxbatches=$NUM # Maximum number of batches to run before exiting. # # Multiple instances of this script can run in parallel in order to speed up cache generation. use v5.36; use FU::Pg; use Getopt::Long; use Time::HiRes 'time', 'sleep'; use Cwd 'abs_path'; our $ROOT; BEGIN { ($ROOT = abs_path $0) =~ s{/util/cache-html\.pl$}{}; } use lib "$ROOT/ManUtils/blib/lib", "$ROOT/ManUtils/blib/arch"; use ManUtils; my $verbose = 0; my $delay = 0; my $batch = 1; my $maxbatches = 0; GetOptions('verbose' => \$verbose, 'delay=f' => \$delay, 'batch=i' => \$batch, 'maxbatches=i' => \$maxbatches); my $conn = FU::Pg->connect($ENV{MANNED_PG}//''); while (1) { my $txn = $conn->txn; my $lst = $txn->q('SELECT id, content FROM contents WHERE html IS NULL FOR UPDATE SKIP LOCKED LIMIT $1', $batch)->flat; last if !@$lst; my @save; for my($id, $content) (@$lst) { my $start = time; my $html = eval { ManUtils::html ManUtils::fmt $content }; my $end = time; # Should be rare. Do save *something* in the database, so we won't get # stuck trying this again and we can easily query for broken pages. if (!defined $html) { $html = '(Error rendering man page)'; warn "$id: Error rendering page: $@\n"; } printf "%10d: %5.1f ms, %d raw, %d html\n", $id, ($end-$start)*1000, length($content), length($html) if $verbose; push @save, $id, $html; } $txn->q('UPDATE contents SET html = nhtml FROM (VALUES '. join(', ', map sprintf('($%d::int, $%d)', $_*2-1, $_*2), 1..@save/2). ') d(nid, nhtml) WHERE id = nid', @save )->exec; $txn->commit; last if !--$maxbatches; sleep $delay if $delay; }