Tatsumaki
view release on metacpan or search on metacpan
lib/Tatsumaki/Handler.pm view on Meta::CPAN
sub get_writer {
my $self = shift;
$self->flush unless $self->writer;
return $self->writer;
}
sub get_chunk {
my $self = shift;
if (ref $_[0]) {
if ($self->mxhr) {
my $json = $self->json->encode($_[0]);
return "Content-Type: application/json\n\n$json\n--" . $self->mxhr_boundary. "\n";
} else {
$self->response->content_type('application/json');
return $self->json->encode($_[0]);
}
} elsif ($self->binary) {
join '', @_;
} else {
join '', map Encode::encode_utf8($_), @_;
}
}
sub _write {
my $self = shift;
my @buf = @_;
try {
$self->get_writer->write(@buf);
} catch {
/Broken pipe/ and Tatsumaki::Error::ClientDisconnect->throw;
die $_;
}
}
sub stream_write {
my $self = shift;
$self->_write($self->get_chunk(@_));
}
sub write {
my $self = shift;
push @{$self->_write_buffer}, $self->get_chunk(@_);
}
sub flush {
my $self = shift;
my($is_final) = @_;
if ($self->writer) {
$self->_write(join '', @{$self->_write_buffer}) if @{$self->_write_buffer};
$self->_write_buffer([]);
} elsif (!$self->is_asynchronous || $is_final) {
my $body = $self->response->body || [];
push @$body, @{$self->_write_buffer};
$self->_write_buffer([]);
$self->response->body($body);
} else {
my $res = $self->response->finalize;
delete $res->[2]; # gimme a writer
$self->condvar->send($res);
$self->writer or Carp::croak("Can't get a writer object back: you need servers with psgi.streaming");
$self->flush();
}
}
sub finish {
my($self, $chunk) = @_;
$self->write($chunk) if defined $chunk;
$self->flush(1);
if ($self->writer) {
$self->writer->close;
$self->condvar->send;
} elsif ($self->condvar) {
$self->condvar->send($self->response->finalize);
}
}
sub render {
my($self, $file, $args) = @_;
$args ||= {};
$self->finish($self->application->render_file($file, { %$args, handler => $self })->as_string);
}
no Any::Moose;
__PACKAGE__->meta->make_immutable;
1;
__END__
( run in 0.801 second using v1.01-cache-2.11-cpan-2c0d6866c4f )