Adds support for streaming response body
This commit is contained in:
parent
217b486b03
commit
9e535846d5
2 changed files with 46 additions and 4 deletions
|
|
@ -27,6 +27,7 @@ use WebGUI::Session;
|
||||||
use WebGUI::User;
|
use WebGUI::User;
|
||||||
use WebGUI::Request;
|
use WebGUI::Request;
|
||||||
use Moose;
|
use Moose;
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
has root => ( is => 'ro', isa => 'Str', default => '/data/WebGUI' );
|
has root => ( is => 'ro', isa => 'Str', default => '/data/WebGUI' );
|
||||||
has site => ( is => 'ro', isa => 'Str', default => 'dev.localhost.localdomain.conf' );
|
has site => ( is => 'ro', isa => 'Str', default => 'dev.localhost.localdomain.conf' );
|
||||||
|
|
@ -91,7 +92,26 @@ sub compile_psgi_app {
|
||||||
my $callback = shift;
|
my $callback = shift;
|
||||||
my $request = WebGUI::Request->new($env);
|
my $request = WebGUI::Request->new($env);
|
||||||
my $response = $self->dispatch($request);
|
my $response = $self->dispatch($request);
|
||||||
$callback->($response);
|
|
||||||
|
if (ref $response eq 'ARRAY' && ref $response->[2] eq 'CODE') {
|
||||||
|
# Response wants to stream itself, so tell PSGI server to give us
|
||||||
|
# a streaming writer object
|
||||||
|
my $writer = $callback->( [ $response->[0], $response->[1] ] );
|
||||||
|
|
||||||
|
# ..and let the response stream itself
|
||||||
|
try {
|
||||||
|
$response->[2]->($writer);
|
||||||
|
} catch {
|
||||||
|
# Response has already been started, so log error and close writer
|
||||||
|
warn "error caught after streaming response started";
|
||||||
|
$writer->close;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# Not streaming, so immediately tell the callback to return
|
||||||
|
# the response. In the future we could use an Event framework here
|
||||||
|
# to make this a non-blocking delayed response.
|
||||||
|
$callback->($response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -129,9 +149,22 @@ sub dispatch {
|
||||||
my $session = $self->session( WebGUI::Session->open($self->root, $config, $request, $sessionId) );
|
my $session = $self->session( WebGUI::Session->open($self->root, $config, $request, $sessionId) );
|
||||||
|
|
||||||
# Short-circuit contentHandlers - for benchmarking PSGI scaffolding vs. modperl
|
# Short-circuit contentHandlers - for benchmarking PSGI scaffolding vs. modperl
|
||||||
$session->close;
|
# $session->close;
|
||||||
$session->output->print('WebGUI PSGI with contentHandlers short-circuited for benchmarking');
|
# $session->output->print("WebGUI PSGI with contentHandlers short-circuited for benchmarking\n");
|
||||||
return $session->response->finalize;
|
# return $session->response->finalize;
|
||||||
|
|
||||||
|
# Streaming content
|
||||||
|
$session->response->stream(sub {
|
||||||
|
my $writer = shift;
|
||||||
|
$writer->write("WebGUI PSGI with contentHandlers short-circuited for benchmarking (streaming)\n");
|
||||||
|
# sleep 1;
|
||||||
|
$writer->write("...see?\n");
|
||||||
|
$writer->close;
|
||||||
|
});
|
||||||
|
if ($session->response->streaming) {
|
||||||
|
$session->close;
|
||||||
|
return $session->response->finalize;
|
||||||
|
}
|
||||||
|
|
||||||
for my $handler (@{$config->get("contentHandlers")}) {
|
for my $handler (@{$config->get("contentHandlers")}) {
|
||||||
my $output = eval { WebGUI::Pluggable::run($handler, "handler", [ $session ] )};
|
my $output = eval { WebGUI::Pluggable::run($handler, "handler", [ $session ] )};
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
package WebGUI::Response;
|
package WebGUI::Response;
|
||||||
use parent qw(Plack::Response);
|
use parent qw(Plack::Response);
|
||||||
|
|
||||||
|
use Plack::Util::Accessor qw(streaming);
|
||||||
|
|
||||||
=head2 DESCRIPTION
|
=head2 DESCRIPTION
|
||||||
|
|
||||||
The WebGUI server response object. See of L<Plack::Response>
|
The WebGUI server response object. See of L<Plack::Response>
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
sub stream {
|
||||||
|
my $self = shift;
|
||||||
|
my $streamer = shift;
|
||||||
|
$self->streaming(1);
|
||||||
|
$self->body($streamer);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
Loading…
Add table
Add a link
Reference in a new issue