From 0821af5f21fdb083020ae2e3e79e4227ef59cd4f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 30 Jul 2020 23:43:50 +0000 Subject: www: rework async_* to use method table Although the ->async_next method does not take $self as a receiver, but rather a PublicInbox::HTTP object, we may still retrieve it to be called with the HTTP object via UNIVERSAL->can. --- lib/PublicInbox/GzipFilter.pm | 16 +++++++--------- lib/PublicInbox/Mbox.pm | 6 +++--- lib/PublicInbox/MboxGz.pm | 5 +++-- lib/PublicInbox/WwwAtomStream.pm | 4 ++-- lib/PublicInbox/WwwAttach.pm | 4 +--- lib/PublicInbox/WwwStream.pm | 4 ++-- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/PublicInbox/GzipFilter.pm b/lib/PublicInbox/GzipFilter.pm index f1354d2b..20030433 100644 --- a/lib/PublicInbox/GzipFilter.pm +++ b/lib/PublicInbox/GzipFilter.pm @@ -7,8 +7,8 @@ # # In newer versions, public-inbox-httpd supports a backpressure-aware # pull/push model which also accounts for slow git blob storage. -# {async_next} callbacks only run when the DS {wbuf} is drained -# {async_eml} callbacks only run when a blob arrives from git. +# async_next callbacks only run when the DS {wbuf} is drained +# async_eml callbacks only run when a blob arrives from git. # # We continue to support getline+close for generic PSGI servers. package PublicInbox::GzipFilter; @@ -46,18 +46,16 @@ sub gz_or_noop { sub gzf_maybe ($$) { bless { gz => gz_or_noop(@_) }, __PACKAGE__ } sub psgi_response { - my ($self, $code, $res_hdr, $next_cb, $eml_cb) = @_; + my ($self, $code, $res_hdr) = @_; my $env = $self->{env}; $self->{gz} //= gz_or_noop($res_hdr, $env); if ($env->{'pi-httpd.async'}) { - $self->{async_next} = $next_cb; - $self->{async_eml} = $eml_cb; my $http = $env->{'psgix.io'}; # PublicInbox::HTTP $http->{forward} = $self; sub { my ($wcb) = @_; # -httpd provided write callback $self->{http_out} = $wcb->([$code, $res_hdr]); - $next_cb->($http); # start stepping + $self->can('async_next')->($http); # start stepping }; } else { # generic PSGI code path [ $code, $res_hdr, $self ]; @@ -172,12 +170,12 @@ sub async_blob_cb { # git->cat_async callback # it's possible to have TOCTOU if an admin runs # public-inbox-(edit|purge), just move onto the next message warn "E: $smsg->{blob} missing in $self->{-inbox}->{inboxdir}\n"; - return $http->next_step($self->{async_next}); + return $http->next_step($self->can('async_next')); } $smsg->{blob} eq $oid or bail($self, "BUG: $smsg->{blob} != $oid"); - eval { $self->{async_eml}->($self, PublicInbox::Eml->new($bref)) }; + eval { $self->async_eml(PublicInbox::Eml->new($bref)) }; bail($self, "E: async_eml: $@") if $@; - $http->next_step($self->{async_next}); + $http->next_step($self->can('async_next')); } sub smsg_blob { diff --git a/lib/PublicInbox/Mbox.pm b/lib/PublicInbox/Mbox.pm index 115321c6..fc83a893 100644 --- a/lib/PublicInbox/Mbox.pm +++ b/lib/PublicInbox/Mbox.pm @@ -29,7 +29,7 @@ sub getline { } } -# called by PublicInbox::DS::write +# called by PublicInbox::DS::write after http->next_step sub async_next { my ($http) = @_; # PublicInbox::HTTP my $ctx = $http->{forward} or return; # client aborted @@ -40,7 +40,7 @@ sub async_next { warn "E: $@" if $@; } -sub async_eml { # ->{async_eml} for async_blob_cb +sub async_eml { # for async_blob_cb my ($ctx, $eml) = @_; my $smsg = delete $ctx->{smsg}; # next message @@ -87,7 +87,7 @@ sub emit_raw { my $smsg = $ctx->{smsg} = $over->next_by_mid(@$mip) or return; my $res_hdr = res_hdr($ctx, $smsg->{subject}); bless $ctx, __PACKAGE__; - $ctx->psgi_response(200, $res_hdr, \&async_next, \&async_eml); + $ctx->psgi_response(200, $res_hdr); } sub msg_hdr ($$;$) { diff --git a/lib/PublicInbox/MboxGz.pm b/lib/PublicInbox/MboxGz.pm index 967af9c6..913be6e4 100644 --- a/lib/PublicInbox/MboxGz.pm +++ b/lib/PublicInbox/MboxGz.pm @@ -29,8 +29,7 @@ sub mbox_gz { bless $self, __PACKAGE__; my $res_hdr = [ 'Content-Type' => 'application/gzip', 'Content-Disposition' => "inline; filename=$fn.mbox.gz" ]; - $self->psgi_response(200, $res_hdr, \&async_next, - \&PublicInbox::Mbox::async_eml); + $self->psgi_response(200, $res_hdr); } # called by Plack::Util::foreach or similar (generic PSGI) @@ -47,4 +46,6 @@ sub getline { $self->zflush; } +no warnings 'once'; +*async_eml = \&PublicInbox::Mbox::async_eml; 1; diff --git a/lib/PublicInbox/WwwAtomStream.pm b/lib/PublicInbox/WwwAtomStream.pm index 2f9b953b..1ed806fd 100644 --- a/lib/PublicInbox/WwwAtomStream.pm +++ b/lib/PublicInbox/WwwAtomStream.pm @@ -35,7 +35,7 @@ sub async_next ($) { warn "E: $@" if $@; } -sub async_eml { # ->{async_eml} for async_blob_cb +sub async_eml { # for async_blob_cb my ($ctx, $eml) = @_; my $smsg = delete $ctx->{smsg}; $ctx->{http_out}->write($ctx->translate(feed_entry($ctx, $smsg, $eml))) @@ -45,7 +45,7 @@ sub response { my ($class, $ctx, $code, $cb) = @_; my $res_hdr = [ 'Content-Type' => 'application/atom+xml' ]; $class->new($ctx, $cb); - $ctx->psgi_response($code, $res_hdr, \&async_next, \&async_eml); + $ctx->psgi_response($code, $res_hdr); } # called once for each message by PSGI server diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index 20417295..0b2cda90 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -35,7 +35,7 @@ sub get_attach_i { # ->each_part callback $res->[2]->[0] = $part; } -sub async_eml { # ->{async_eml} for async_blob_cb +sub async_eml { # for async_blob_cb my ($ctx, $eml) = @_; eval { $eml->each_part(\&get_attach_i, $ctx, 1) }; if ($@) { @@ -55,8 +55,6 @@ sub async_next { sub scan_attach ($) { # public-inbox-httpd only my ($ctx) = @_; $ctx->{env}->{'psgix.io'}->{forward} = $ctx; - $ctx->{async_eml} = \&async_eml; - $ctx->{async_next} = \&async_next; $ctx->smsg_blob($ctx->{smsg}); } diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm index 23b03f0e..d79770ed 100644 --- a/lib/PublicInbox/WwwStream.pm +++ b/lib/PublicInbox/WwwStream.pm @@ -28,7 +28,7 @@ sub init { bless $ctx, __PACKAGE__; } -sub async_eml { # ->{async_eml} for async_blob_cb +sub async_eml { # for async_blob_cb my ($ctx, $eml) = @_; $ctx->{http_out}->write($ctx->translate($ctx->{cb}->($ctx, $eml))); } @@ -198,7 +198,7 @@ sub aresponse { my ($ctx, $code, $cb) = @_; my $res_hdr = [ 'Content-Type' => 'text/html; charset=UTF-8' ]; init($ctx, $cb); - $ctx->psgi_response($code, $res_hdr, \&async_next, \&async_eml); + $ctx->psgi_response($code, $res_hdr); } 1; -- cgit v1.2.3-24-ge0c7