From 1704bdb4aabdbc155eb962edf51498f59b65c839 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 22 Aug 2015 00:06:45 +0000 Subject: stream HTML views as much as possible This should allow progressive rendering on the client and reduce memory usage on the server. Unfortunately XML::Atom::SimpleFeed does not yet support streaming, so we may not use it in the future. --- lib/PublicInbox/Feed.pm | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'lib/PublicInbox/Feed.pm') diff --git a/lib/PublicInbox/Feed.pm b/lib/PublicInbox/Feed.pm index 40f08ac7..5d122ac6 100644 --- a/lib/PublicInbox/Feed.pm +++ b/lib/PublicInbox/Feed.pm @@ -52,7 +52,15 @@ sub generate { } sub generate_html_index { - my ($class, $ctx) = @_; + my ($ctx) = @_; + sub { emit_html_index($_[0], $ctx) }; +} + +# private subs + +sub emit_html_index { + my ($cb, $ctx) = @_; + my $fh = $cb->([200,['Content-Type'=>'text/html; charset=UTF-8']]); my $max = $ctx->{max} || MAX_PER_PAGE; my $feed_opts = get_feedopts($ctx); @@ -61,11 +69,11 @@ sub generate_html_index { $title = PublicInbox::Hval->new_oneline($title)->as_html; my $atom_url = $feed_opts->{atomurl}; - my $html = "$title" . - "" . - '' . PublicInbox::View::PRE_WRAP . - "$title (Atom feed)\n"; + $fh->write("$title" . + "" . + '' . PublicInbox::View::PRE_WRAP . + "$title (Atom feed)\n"); my $state; my $git = PublicInbox::GitCatFile->new($ctx->{git_dir}); @@ -80,8 +88,7 @@ sub generate_html_index { add_topic($git, $srch, $topics, $path, $ts, $u, $subj); } else { my $mime = do_cat_mail($git, $path) or return 0; - $html .= - PublicInbox::View->index_entry($mime, 0, $state); + PublicInbox::View::index_entry($fh, $mime, 0, $state); 1; } }); @@ -94,12 +101,11 @@ sub generate_html_index { $footer .= "\n" . $list_footer if $list_footer; $footer = "
$footer
"; } - dump_topics(\$html, $topics) if $topics; - $html .= "$footer"; + $fh->write(dump_topics($topics)) if $topics; + $fh->write("$footer"); + $fh->close; } -# private subs - sub nav_footer { my ($cgi, $last, $feed_opts, $state) = @_; $cgi or return ''; @@ -328,27 +334,28 @@ sub add_topic { } sub dump_topics { - my ($dst, $topics) = @_; + my ($topics) = @_; my ($order, $subjs) = @$topics; - $$dst .= "\n[No recent topics]" unless (scalar @$order); + my $dst = ''; + $dst .= "\n[No recent topics]" unless (scalar @$order); while (defined(my $info = shift @$order)) { my ($mid, $ts, $u, $subj) = @$info; my $n = delete $subjs->{$subj}; $mid = PublicInbox::Hval->new($mid)->as_href; $subj = PublicInbox::Hval->new($subj)->as_html; $u = PublicInbox::Hval->new($u)->as_html; - $$dst .= "\n$subj\n- "; + $dst .= "\n$subj\n- "; $ts = POSIX::strftime('%Y-%m-%d %H:%M', gmtime($ts)); if ($n == 1) { - $$dst .= "created by $u @ $ts UTC\n" + $dst .= "created by $u @ $ts UTC\n" } else { # $n isn't the total number of posts on the topic, # just the number of posts in the current "git log" # window, so leave it unlabeled - $$dst .= "updated by $u @ $ts UTC ($n)\n" + $dst .= "updated by $u @ $ts UTC ($n)\n" } } - $$dst .= '' + $dst .= '' } 1; -- cgit v1.2.3-24-ge0c7