add caching for parsed page info
Matt S Trout [Mon, 4 Jul 2011 20:17:16 +0000 (20:17 +0000)]
lib/SCSite/PageSet.pm

index f55a868..82c1e30 100644 (file)
@@ -1,13 +1,19 @@
 package SCSite::PageSet;
 
-use IO::All;
 use Text::MultiMarkdown 'markdown';
 use HTML::Zoom;
 use Sub::Quote;
 use Syntax::Keyword::Gather;
 use SCSite::Page;
-use Moo;
+use IO::All;
 use Try::Tiny;
+use JSON;
+use Moo;
+
+{
+  my $j = JSON->new;
+  sub _json { $j }
+}
 
 has top_dir => (is => 'ro', lazy => 1, builder => 'base_dir');
 has base_dir => (is => 'ro', required => 1);
@@ -38,15 +44,26 @@ sub get {
     if @poss > 1;
   return undef unless @poss;
   $self->_inflate(
-    $type, $self->rel_path->catdir($spec->{path}), $poss[0]->all
+    $type, $self->rel_path->catdir($spec->{path}), $poss[0]
   );
 }
 
 sub _inflate {
-  my ($self, $type, $path, $data) = @_;
-  try { $self->${\"_inflate_${type}"}($path, $data) }
-  catch {
-    die "Error inflating ${path} as ${type}: $_\n\nData was: ${data}";
+  my ($self, $type, $path, $io) = @_;
+  (my $cache_name = $io->name) =~ s/\/([^\/]+)$/\/.htcache.$1.json/;
+  my $cache = io($cache_name);
+  if (-f $cache_name) {
+    if ($cache->mtime >= $io->mtime) {
+      return $self->_new_page($path, $self->_json->decode($cache->all));
+    }
+  }
+  my $raw = $io->all;
+  try {
+    my $extracted = $self->${\"_extract_from_${type}"}($raw);
+    $cache->print($self->_json->encode($extracted));
+    $self->_new_page($path, $extracted);
+  } catch {
+    die "Error inflating ${path} as ${type}: $_\n\nData was: ${raw}";
   }
 }
 
@@ -71,7 +88,7 @@ sub flatten {
     $self->_inflate(
       $type,
       $slash->catdir(File::Spec->abs2rel($path, $self->top_dir->name)),
-      $_->all
+      $_
     );
   } map {
     $_->filter(sub { $_->filename =~ /${\$self->_types_re}$/ })
@@ -101,11 +118,6 @@ sub _new_page {
 
 sub _types_re { qw/\.(html|md)/ }
 
-sub _inflate_html {
-  my ($self, $path, $html) = @_;
-  $self->_new_page($path, $self->_extract_from_html($html));
-}
-
 sub _extract_from_html {
   my ($self, $html) = @_;
   HTML::Zoom->from_html($html)
@@ -126,11 +138,6 @@ sub _extract_from_html {
   }
 }
 
-sub _inflate_md {
-  my ($self, $path, $md) = @_;
-  $self->_new_page($path, $self->_extract_from_md($md));
-}
-
 sub _extract_from_md {
   my ($self, $md) = @_;
   $self->_extract_from_html(markdown($md, { document_format => 'complete' }));