Async-Microservice

 view release on metacpan or  search on metacpan

lib/Async/MicroserviceReq.pm  view on Meta::CPAN


    return $state;
}

sub _emit_response {
    my ( $self, $state ) = @_;

    push(
        @{ $state->{headers} },
        ( 'Content-Type' => ( $state->{content_type} || 'text/plain' ) )
    ) unless ( $state->{headers_as_hash}->{'content-type'} );

    return $self->plack_respond->(
        [   $state->{status},
            [ @no_cache_headers, @{ $state->{headers} } ],
            [ $state->{payload} ]
        ]
    );
}

sub respond {
    my ( $self, $status, $headers, $payload ) = @_;

    my %headers_as_hash = map { defined($_) ? lc($_) : $_ } @$headers;
    my $state           = {
        status          => $status,
        headers         => $headers,
        headers_as_hash => \%headers_as_hash,
        payload         => $payload,
    };

    $state->{payload} = $self->_wrap_payload($state);
    $state = $self->_serialize_payload($state);

    return $self->_emit_response($state);
}

sub redirect {
    my ( $self, $location_path ) = @_;
    my $location = $self->base_url->clone;
    $location->path($location_path);
    return $self->respond(
        302,
        [ "Location" => $location ],
        "redirect to " . $location
    );
}

async sub static_ft {
    my ( $self, $file_name, $content_cb ) = @_;
    my $static_file  = $self->static_dir->file($file_name)->stringify;
    my $content_type = Plack::MIME->mime_type($static_file) || 'text/plain';
    return await _fetch_file_ft($static_file)->then(
        sub {
            my ($content) = @_;
            $content = $content_cb->($content) if $content_cb;
            return [ 200, [ 'Content-Type' => $content_type ], $content ];
        }
    )->catch(
        sub {
            return [ 404, [@no_cache_headers], 'no such static file' ];
        }
    );
}

sub _fetch_file_ft {
    my ($file) = @_;

    my $aio_load_f = Future->new;
    $aio_load_f->retain;
    aio_load(
        $file,
        sub {
            my ($content) = @_;
            $aio_load_f->done($content);
        }
    );

    my $fetch_file_ft = Future->new;
    $aio_load_f->on_done(
        sub {
            my ($content) = @_;
            unless ( defined($content) ) {
                $fetch_file_ft->fail(
                    'failed to load content of file: ' . $file );
                return;
            }
            $fetch_file_ft->done($content);
        }
    );

    return $fetch_file_ft;
}

__PACKAGE__->meta->make_immutable;

1;

__END__

=head1 NAME

Async::MicroserviceReq - async microservice request class

=head1 SYNOPSIS

    my $this_req  = Async::MicroserviceReq->new(
        method     => $plack_req->method,
        headers    => $plack_req->headers,
        content    => $plack_req->content,
        path       => $plack_req->path_info,
        params     => $plack_req->parameters,
        static_dir => $self->static_dir,
    );

    ...

    my $plack_handler_sub = sub {
        my ($plack_respond) = @_;
        $this_req->plack_respond($plack_respond);
    ...



( run in 0.782 second using v1.01-cache-2.11-cpan-39bf76dae61 )